From 911db644ed0c01bbeb598a7c4cf5d6e5117a1f25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 13:49:35 +0000 Subject: [PATCH 1/4] Initial plan From 2eac0dde663e83357666b1837da16f4b8089178b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 14:12:09 +0000 Subject: [PATCH 2/4] fix: bundle ref not found when agent commits to HEAD instead of named branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In generate_git_bundle.cjs Strategy 2, when the agent-specified branch doesn't exist locally, create a local branch pointing to HEAD before bundling so the bundle contains refs/heads/ — which create_pull_request.cjs needs. Also add a defensive fallback in create_pull_request.cjs that uses git bundle list-heads to find available refs when the expected ref is missing. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/dc510197-23d5-4865-87e8-b6726dc060ea Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/create_pull_request.cjs | 39 +++++++++++++++++++++--- actions/setup/js/generate_git_bundle.cjs | 17 ++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/actions/setup/js/create_pull_request.cjs b/actions/setup/js/create_pull_request.cjs index e606522c3d7..c0d3cb9c424 100644 --- a/actions/setup/js/create_pull_request.cjs +++ b/actions/setup/js/create_pull_request.cjs @@ -701,16 +701,47 @@ async function main(config = {}) { // unlike git format-patch which flattens history and drops merge resolution content. core.info(`Applying changes from bundle: ${bundleFilePath}`); const bundleBranchRef = originalAgentBranch || branchName; + let bundleApplied = false; try { // Fetch from bundle: creates a local branch pointing to the bundle's tip commit. // The bundle contains refs/heads/ which was the agent's working branch. await exec.exec("git", ["fetch", bundleFilePath, `refs/heads/${bundleBranchRef}:refs/heads/${branchName}`]); core.info(`Created local branch ${branchName} from bundle`); - await exec.exec("git", ["checkout", branchName]); - core.info(`Checked out branch ${branchName} from bundle`); + bundleApplied = true; } catch (bundleError) { - core.error(`Failed to apply bundle: ${bundleError instanceof Error ? bundleError.message : String(bundleError)}`); - return { success: false, error: "Failed to apply bundle" }; + // The bundle may not contain refs/heads/ (e.g. when the bundle was + // created from HEAD instead of a named branch). Fall back to listing available refs. + core.warning(`Branch ref 'refs/heads/${bundleBranchRef}' not found in bundle, trying fallback refs`); + core.debug(`Primary fetch failed: ${bundleError instanceof Error ? bundleError.message : String(bundleError)}`); + try { + const { stdout: headsOutput } = await exec.getExecOutput("git", ["bundle", "list-heads", bundleFilePath]); + const fallbackRef = headsOutput + .trim() + .split("\n") + .map(line => line.trim().split(" ")) + .filter(parts => parts.length >= 2) + .map(parts => parts[1]) + .find(ref => ref && ref.startsWith("refs/heads/")); + if (!fallbackRef) { + throw new Error(`No refs/heads/* found in bundle (output: ${headsOutput})`); + } + core.info(`Falling back to bundle ref '${fallbackRef}'`); + await exec.exec("git", ["fetch", bundleFilePath, `${fallbackRef}:refs/heads/${branchName}`]); + core.info(`Created local branch ${branchName} from bundle using fallback ref ${fallbackRef}`); + bundleApplied = true; + } catch (fallbackError) { + core.error(`Failed to apply bundle: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`); + return { success: false, error: "Failed to apply bundle" }; + } + } + if (bundleApplied) { + try { + await exec.exec("git", ["checkout", branchName]); + core.info(`Checked out branch ${branchName} from bundle`); + } catch (checkoutError) { + core.error(`Failed to checkout branch from bundle: ${checkoutError instanceof Error ? checkoutError.message : String(checkoutError)}`); + return { success: false, error: "Failed to apply bundle" }; + } } // Push the commits from the bundle to the remote branch diff --git a/actions/setup/js/generate_git_bundle.cjs b/actions/setup/js/generate_git_bundle.cjs index 5c3a7f0536d..2df5f783539 100644 --- a/actions/setup/js/generate_git_bundle.cjs +++ b/actions/setup/js/generate_git_bundle.cjs @@ -283,7 +283,22 @@ async function generateGitBundle(branchName, baseBranch, options = {}) { debugLog(`Strategy 2: Found ${commitCount} commits between GITHUB_SHA and HEAD`); if (commitCount > 0) { - execGitSync(["bundle", "create", bundlePath, `${githubSha}..HEAD`], { cwd }); + // If branchName is provided and doesn't exist locally (Strategy 1 already failed), + // create a local branch pointing to HEAD so the bundle contains + // refs/heads/ — required by create_pull_request.cjs when applying the bundle. + let rangeEnd = "HEAD"; + if (branchName) { + try { + // Use -f (force) to overwrite any stale local branch from previous runs, + // since Strategy 1 verified the named branch does not exist as a proper local ref. + execGitSync(["branch", "-f", branchName, "HEAD"], { cwd }); + rangeEnd = branchName; + debugLog(`Strategy 2: Created local branch '${branchName}' pointing to HEAD for bundle ref`); + } catch (branchErr) { + debugLog(`Strategy 2: Could not create branch '${branchName}': ${getErrorMessage(branchErr)}, using HEAD`); + } + } + execGitSync(["bundle", "create", bundlePath, `${githubSha}..${rangeEnd}`], { cwd }); if (fs.existsSync(bundlePath)) { const stat = fs.statSync(bundlePath); From c6ba266e262d1085ddbd915ad48765a99d8d0edc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 14:29:58 +0000 Subject: [PATCH 3/4] fix: remove fallback bundle ref lookup from create_pull_request.cjs Agent-Logs-Url: https://github.com/github/gh-aw/sessions/5d02e19c-08a5-4f7a-99bc-137d1df78d4e Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/create_pull_request.cjs | 39 +++--------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/actions/setup/js/create_pull_request.cjs b/actions/setup/js/create_pull_request.cjs index c0d3cb9c424..e606522c3d7 100644 --- a/actions/setup/js/create_pull_request.cjs +++ b/actions/setup/js/create_pull_request.cjs @@ -701,47 +701,16 @@ async function main(config = {}) { // unlike git format-patch which flattens history and drops merge resolution content. core.info(`Applying changes from bundle: ${bundleFilePath}`); const bundleBranchRef = originalAgentBranch || branchName; - let bundleApplied = false; try { // Fetch from bundle: creates a local branch pointing to the bundle's tip commit. // The bundle contains refs/heads/ which was the agent's working branch. await exec.exec("git", ["fetch", bundleFilePath, `refs/heads/${bundleBranchRef}:refs/heads/${branchName}`]); core.info(`Created local branch ${branchName} from bundle`); - bundleApplied = true; + await exec.exec("git", ["checkout", branchName]); + core.info(`Checked out branch ${branchName} from bundle`); } catch (bundleError) { - // The bundle may not contain refs/heads/ (e.g. when the bundle was - // created from HEAD instead of a named branch). Fall back to listing available refs. - core.warning(`Branch ref 'refs/heads/${bundleBranchRef}' not found in bundle, trying fallback refs`); - core.debug(`Primary fetch failed: ${bundleError instanceof Error ? bundleError.message : String(bundleError)}`); - try { - const { stdout: headsOutput } = await exec.getExecOutput("git", ["bundle", "list-heads", bundleFilePath]); - const fallbackRef = headsOutput - .trim() - .split("\n") - .map(line => line.trim().split(" ")) - .filter(parts => parts.length >= 2) - .map(parts => parts[1]) - .find(ref => ref && ref.startsWith("refs/heads/")); - if (!fallbackRef) { - throw new Error(`No refs/heads/* found in bundle (output: ${headsOutput})`); - } - core.info(`Falling back to bundle ref '${fallbackRef}'`); - await exec.exec("git", ["fetch", bundleFilePath, `${fallbackRef}:refs/heads/${branchName}`]); - core.info(`Created local branch ${branchName} from bundle using fallback ref ${fallbackRef}`); - bundleApplied = true; - } catch (fallbackError) { - core.error(`Failed to apply bundle: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`); - return { success: false, error: "Failed to apply bundle" }; - } - } - if (bundleApplied) { - try { - await exec.exec("git", ["checkout", branchName]); - core.info(`Checked out branch ${branchName} from bundle`); - } catch (checkoutError) { - core.error(`Failed to checkout branch from bundle: ${checkoutError instanceof Error ? checkoutError.message : String(checkoutError)}`); - return { success: false, error: "Failed to apply bundle" }; - } + core.error(`Failed to apply bundle: ${bundleError instanceof Error ? bundleError.message : String(bundleError)}`); + return { success: false, error: "Failed to apply bundle" }; } // Push the commits from the bundle to the remote branch From 5cf8908646a7d8998f6de8b673ab4c7fa2f7ed61 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Apr 2026 14:53:52 +0000 Subject: [PATCH 4/4] fix: add -- before branchName in git branch -f to guard against leading dash Agent-Logs-Url: https://github.com/github/gh-aw/sessions/a02ead34-16bc-4fb7-8018-0e89a4453e2c Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/generate_git_bundle.cjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/generate_git_bundle.cjs b/actions/setup/js/generate_git_bundle.cjs index 2df5f783539..7ede91e1555 100644 --- a/actions/setup/js/generate_git_bundle.cjs +++ b/actions/setup/js/generate_git_bundle.cjs @@ -291,7 +291,8 @@ async function generateGitBundle(branchName, baseBranch, options = {}) { try { // Use -f (force) to overwrite any stale local branch from previous runs, // since Strategy 1 verified the named branch does not exist as a proper local ref. - execGitSync(["branch", "-f", branchName, "HEAD"], { cwd }); + // Use -- so a branch name beginning with "-" is not parsed as another option. + execGitSync(["branch", "-f", "--", branchName, "HEAD"], { cwd }); rangeEnd = branchName; debugLog(`Strategy 2: Created local branch '${branchName}' pointing to HEAD for bundle ref`); } catch (branchErr) {