From 0db3d1d6d5f55e3d74ad27897ab0010a1f93e79b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 17:44:04 +0000 Subject: [PATCH 1/3] Initial plan From e01af392d90ff4a2166b44c70ef1058198c376f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 17:49:53 +0000 Subject: [PATCH 2/3] fix: use git add --sparse to handle sparse-checkout on orphan branch creation Agent-Logs-Url: https://github.com/github/gh-aw/sessions/409fef1d-ed92-46a5-9d2d-83ae9657714a Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/push_repo_memory.cjs | 6 +++++- actions/setup/js/push_repo_memory.test.cjs | 23 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/push_repo_memory.cjs b/actions/setup/js/push_repo_memory.cjs index 4e005e15974..364551b7ec2 100644 --- a/actions/setup/js/push_repo_memory.cjs +++ b/actions/setup/js/push_repo_memory.cjs @@ -369,8 +369,12 @@ async function main() { core.info("Changes detected, committing and pushing..."); // Stage all changes + // Use --sparse to allow staging files that fall outside an active + // sparse-checkout definition. This can happen on the first run when an + // orphan branch is created: "git checkout --orphan" can re-activate + // sparse-checkout behaviour, which would cause a plain "git add ." to fail. try { - execGitSync(["add", "."], { stdio: "inherit" }); + execGitSync(["add", "--sparse", "."], { stdio: "inherit" }); } catch (error) { core.setFailed(`Failed to stage changes: ${getErrorMessage(error)}`); return; diff --git a/actions/setup/js/push_repo_memory.test.cjs b/actions/setup/js/push_repo_memory.test.cjs index cea1629085c..6bdd63fd16d 100644 --- a/actions/setup/js/push_repo_memory.test.cjs +++ b/actions/setup/js/push_repo_memory.test.cjs @@ -1057,6 +1057,29 @@ describe("push_repo_memory.cjs - shell injection security tests", () => { expect(scriptContent).toContain("fs.rmSync("); }); + it("should use git add --sparse to handle sparse-checkout on orphan branch creation", () => { + // Regression test for: push_repo_memory fails with sparse-checkout error on first run. + // + // Root cause: "git checkout --orphan" can re-activate sparse-checkout behaviour. + // A plain "git add ." then fails because the files fall outside the sparse-checkout + // definition. + // + // Fix: use "git add --sparse ." so files are staged regardless of whether + // sparse-checkout is active. + + const fs = require("fs"); + const path = require("path"); + + const scriptPath = path.join(import.meta.dirname, "push_repo_memory.cjs"); + const scriptContent = fs.readFileSync(scriptPath, "utf8"); + + // Must use "git add --sparse ." to stage files regardless of sparse-checkout state. + expect(scriptContent).toContain('"add", "--sparse", "."'); + + // Must NOT use plain "git add ." which breaks under sparse-checkout. + expect(scriptContent).not.toContain('"add", "."'); + }); + it("should safely handle malicious branch names", () => { // Test that malicious branch names would be rejected by git, not executed as shell commands const maliciousBranchNames = [ From eb3b05d29417596ad9a766802dc62a3208c797d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 18:11:35 +0000 Subject: [PATCH 3/3] fix: update git add --sparse comment to quote official git-add(1) documentation Agent-Logs-Url: https://github.com/github/gh-aw/sessions/7b5cf987-0bae-497f-a5b8-e69a09bf3ed8 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/push_repo_memory.cjs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/actions/setup/js/push_repo_memory.cjs b/actions/setup/js/push_repo_memory.cjs index 364551b7ec2..6dc404a14d4 100644 --- a/actions/setup/js/push_repo_memory.cjs +++ b/actions/setup/js/push_repo_memory.cjs @@ -368,11 +368,14 @@ async function main() { core.info("Changes detected, committing and pushing..."); - // Stage all changes - // Use --sparse to allow staging files that fall outside an active - // sparse-checkout definition. This can happen on the first run when an - // orphan branch is created: "git checkout --orphan" can re-activate - // sparse-checkout behaviour, which would cause a plain "git add ." to fail. + // Stage all changes. + // --sparse: "Allow updating index entries outside of the sparse-checkout cone. + // Normally, git add refuses to update index entries whose paths do not fit + // within the sparse-checkout cone, since those files might be removed from the + // working tree without warning." (git-add(1)) + // This is required because "git checkout --orphan" can re-activate + // sparse-checkout, causing a plain "git add ." to silently skip or reject + // files on the first run for a new memory branch. try { execGitSync(["add", "--sparse", "."], { stdio: "inherit" }); } catch (error) {