Skip to content

fix: --topo-order and merge commit fallback in push_signed_commits.cjs#26306

Merged
pelikhan merged 5 commits intomainfrom
copilot/fix-push-signed-commits-ordering
Apr 14, 2026
Merged

fix: --topo-order and merge commit fallback in push_signed_commits.cjs#26306
pelikhan merged 5 commits intomainfrom
copilot/fix-push-signed-commits-ordering

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

push_signed_commits.cjs could replay commits in the wrong order when timestamps diverge (e.g. after rebase --committer-date-is-author-date), and would silently produce incorrect results when a merge commit was included in the series.

Changes

  • git rev-list: Switched to git rev-list --parents --topo-order --reverse to guarantee graph-topology ordering regardless of commit timestamps, and to obtain parent information for all commits in a single subprocess call.

  • Merge commit pre-flight check: Parses the --parents output from the rev-list call already made. Each output line is <sha> <parent1> [<parent2> ...]; if any line has 3+ space-separated fields, the commit has ≥2 parents (merge commit) and the entire series falls back to git push with a warning — since createCommitOnBranch does not support multiple parents. This approach is both efficient (no extra subprocess per SHA) and robust (immune to "parent " text appearing in a commit message body).

for (const line of revListLines) {
  const fields = line.split(" ");
  if (fields.length > 2) {
    const sha = fields[0];
    core.warning(`pushSignedCommits: merge commit ${sha} detected, falling back to git push`);
    throw new Error("merge commit detected");
  }
}

Non-merge commit series continue through the existing GraphQL signed-commit path unchanged.

Tests

New integration tests added in push_signed_commits.test.cjs:

  • Topological ordering: creates two commits with swapped author/committer dates and asserts GraphQL replays them in correct DAG order.
  • Merge commit fallback: creates a --no-ff merge commit and asserts GraphQL is not called and git push is used instead.
  • Regression: a commit whose message body starts with "parent " is not misidentified as a merge commit.


✨ PR Review Safe Output Test - Run 24426417551

💥 [THE END] — Illustrated by Smoke Claude · ● 177.2K ·


Changeset

  • Type: patch
  • Description: Fixes push_signed_commits.cjs commit replay ordering with --topo-order and adds merge-commit fallback to git push when multi-parent commits are detected.

Warning

⚠️ Firewall blocked 3 domains

The following domains were blocked by the firewall during workflow execution:

  • ab.chatgpt.com
  • chatgpt.com
  • invalid.example.invalid

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"
    - "chatgpt.com"
    - "invalid.example.invalid"

See Network Configuration for more information.

Generated by Changeset Generator for issue #26306 ·

…h_signed_commits.cjs

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/5c32795c-82f0-4b61-83c4-2a57c3a67eb7

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix commit ordering and add merge commit handling in push_signed_commits.cjs fix: --topo-order and merge commit fallback in push_signed_commits.cjs Apr 14, 2026
Copilot AI requested a review from pelikhan April 14, 2026 22:02
@pelikhan pelikhan marked this pull request as ready for review April 14, 2026 22:22
Copilot AI review requested due to automatic review settings April 14, 2026 22:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes incorrect signed-commit replay behavior when commit timestamps don’t reflect the DAG order, and prevents silently incorrect results when merge commits are present by falling back to a normal git push.

Changes:

  • Add --topo-order to git rev-list --reverse to ensure DAG-topological ordering (oldest-first) independent of timestamps.
  • Add a pre-flight merge-commit detector (multi-parent commits) and fall back to git push for the full series when detected.
Show a summary per file
File Description
actions/setup/js/push_signed_commits.cjs Enforces topological commit ordering and adds merge-commit detection to trigger a safe git push fallback.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 1/1 changed files
  • Comments generated: 3

Comment on lines 112 to +135
@@ -121,6 +122,18 @@ async function pushSignedCommits({ githubClient, owner, repo, branch, baseRef, c
core.info(`pushSignedCommits: replaying ${shas.length} commit(s) via GraphQL createCommitOnBranch (branch: ${branch}, repo: ${owner}/${repo})`);

try {
// Pre-flight check: detect merge commits (more than one parent). The GraphQL
// createCommitOnBranch mutation does not support multiple parents, so fall back
// to git push for the entire series if any merge commit is found.
for (const sha of shas) {
const { stdout: catFileOut } = await exec.getExecOutput("git", ["cat-file", "-p", sha], { cwd });
const parentCount = (catFileOut.match(/^parent /gm) || []).length;
if (parentCount > 1) {
core.warning(`pushSignedCommits: merge commit ${sha} detected, falling back to git push`);
throw new Error("merge commit detected");
}
}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior is introduced here (topo-order rev-list sequencing and merge-commit fallback to git push), but actions/setup/js/push_signed_commits.test.cjs currently has no coverage for either scenario. Please add tests that (1) create out-of-sync commit dates and assert the replay order is still correct, and (2) create a merge commit in the range and assert GraphQL is skipped and git push is used.

Copilot uses AI. Check for mistakes.
Comment on lines +129 to +134
const { stdout: catFileOut } = await exec.getExecOutput("git", ["cat-file", "-p", sha], { cwd });
const parentCount = (catFileOut.match(/^parent /gm) || []).length;
if (parentCount > 1) {
core.warning(`pushSignedCommits: merge commit ${sha} detected, falling back to git push`);
throw new Error("merge commit detected");
}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The merge-commit detection counts ^parent occurrences in the full git cat-file -p output, which includes the commit message after a blank line. A commit message line starting with parent would be miscounted as an extra parent and incorrectly trigger the fallback. Consider using a git format that outputs only parents (e.g., git show -s --format=%P <sha> or git rev-list --parents -n 1 <sha>), or restrict parsing to the header section before the first blank line.

Copilot uses AI. Check for mistakes.
Comment on lines +128 to +135
for (const sha of shas) {
const { stdout: catFileOut } = await exec.getExecOutput("git", ["cat-file", "-p", sha], { cwd });
const parentCount = (catFileOut.match(/^parent /gm) || []).length;
if (parentCount > 1) {
core.warning(`pushSignedCommits: merge commit ${sha} detected, falling back to git push`);
throw new Error("merge commit detected");
}
}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pre-flight check runs git cat-file -p in a separate subprocess for every commit SHA, which can be noticeably slow for larger series. You can detect merge commits in a single git invocation (e.g., git rev-list --parents --reverse --topo-order ${baseRef}..HEAD and treat any line with more than 2 fields as a merge) to reduce process spawn overhead.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new --parents approach in this PR directly addresses this concern — merge detection is now done inline from the same rev-list output without any extra subprocess per commit. And the commit message regression test confirms no false positives. 🎯

📰 BREAKING: Report filed by Smoke Copilot · ● 644.7K

@github-actions github-actions bot mentioned this pull request Apr 14, 2026
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review all comments

Copilot AI and others added 2 commits April 14, 2026 22:34
…o-order and merge fallback

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/9c5e299c-424a-49f8-bf1e-720f35988603

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 14, 2026

@copilot review all comments

All three reviewer comments have been addressed in commit 3178de1 (with a follow-up cleanup in 64dbf2b):

  1. Merge detection robustness & performance — Replaced the per-SHA git cat-file -p loop with a single git rev-list --parents --topo-order --reverse call. Each output line is <sha> <parent1> [<parent2> ...]; if any line has 3+ space-separated fields, it's a merge commit. This is immune to "parent " appearing in a commit message body and eliminates N subprocess calls.

  2. Missing tests — Added three new test cases in push_signed_commits.test.cjs:

    • Topological ordering: creates two commits with swapped author/committer dates and asserts GraphQL replays them in correct DAG order
    • Merge commit fallback: creates a --no-ff merge commit and asserts GraphQL is not called and git push is used instead
    • Regression test: a commit whose message body starts with "parent " is not misidentified as a merge commit (validates the fix above)
  3. SHA regex: tightened to [0-9a-f]{7,40} and the multi-line commit message uses git commit -F with a file.

@pelikhan pelikhan added the smoke label Apr 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

⚠️ Smoke Gemini failed. Gemini encountered unexpected challenges...

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions github-actions bot removed the smoke label Apr 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready.

@github-actions
Copy link
Copy Markdown
Contributor

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.53.0
jq 1.7
yq 4.52.5
curl 8.5.0
gh 2.89.0
node 20.20.2
python3 3.12.3
go 1.24.13
java 10.0.201
dotnet 10.0.201

Result: 12/12 tools available ✅

Overall Status: PASS

🔧 Tool validation by Agent Container Smoke Test · ● 157K ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke test summary (run 24426417596)
Merged PRs: #26313 fix(USE-003): emit staged mode preview summary in upload_artifact handler; #26305 Split frontmatter_types.go into types, parsing, and serialization files
GitHub MCP: ✅
Serena MCP: ❌
Playwright: ✅
Web Fetch MCP: ❌
File write/read + Bash cat: ✅
Build: ✅
Overall: FAIL

Warning

⚠️ Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • ab.chatgpt.com
  • chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"
    - "chatgpt.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results for this PR — run §24426417572

Test
GitHub MCP
MCP Scripts GH CLI
Playwright
Web Fetch
File Writing + Bash
Discussion Interaction
Build gh-aw
Upload artifact
Discussion Creation
Workflow Dispatch
PR Review

Overall: PASS ✅

PR Author: @Copilot | Assignees: @pelikhan, @Copilot

📰 BREAKING: Report filed by Smoke Copilot · ● 644.7K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR cleanly addresses the topo-order and merge-commit fallback by reusing the single --parents rev-list output. Both new scenarios are covered by integration tests including a regression test for commit messages that start with "parent ". Looks good overall!

📰 BREAKING: Report filed by Smoke Copilot · ● 644.7K

expect(mockCore.warning).not.toHaveBeenCalledWith(expect.stringContaining("merge commit"));
});
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice regression test for the "parent " commit message body false-positive — this directly validates that the --parents output approach (parsing only the rev-list line format) doesn't get confused by commit message content. 👍

core.warning(`pushSignedCommits: merge commit ${sha} detected, falling back to git push`);
throw new Error("merge commit detected");
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The merge commit pre-flight detection using --parents output is a clean single-subprocess approach. One minor note: the comment says "3+ space-separated fields" but fields.length > 2 accurately captures this (sha + parent1 + parent2 = 3 fields). ✅

@github-actions
Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results — Run §24426417551✅ PASS

Core Tests (#1–12): ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅

PR Review Tests (#13–19):

Overall: PARTIAL (all non-skipped tests passed)

💥 [THE END] — Illustrated by Smoke Claude · ● 177.2K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💥 Automated smoke test review - all systems nominal! Run 24426417551

💥 [THE END] — Illustrated by Smoke Claude · ● 177.2K

core.warning(`pushSignedCommits: merge commit ${sha} detected, falling back to git push`);
throw new Error("merge commit detected");
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Smoke test review comment #1 — The --parents --topo-order approach correctly combines merge-commit detection with topological ordering in a single git rev-list call. Efficient and correct. Run 24426417551.

@@ -883,4 +883,152 @@ describe("push_signed_commits integration tests", () => {
expect(Buffer.from(callArg.fileChanges.additions[0].contents, "base64").toString()).toBe("copy source\n");
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Smoke test review comment #2 — Good coverage of the topological ordering edge case using swapped commit dates. The test clearly validates the fix. Run 24426417551.

@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 9c927f3

Generated by Changeset Generator

@pelikhan pelikhan merged commit c25673e into main Apr 14, 2026
@pelikhan pelikhan deleted the copilot/fix-push-signed-commits-ordering branch April 14, 2026 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[plan] Fix commit ordering (--topo-order) and add merge commit handling in push_signed_commits.cjs

3 participants