Re-parent with the vendored git-merge-onto instead of the merge dance#56
Merged
Conversation
update_direct_target re-homed each child with five git commands (merge the merged branch, merge the pre-squash target, merge -s ours the squash, commit-tree a three-parent commit, reset). That is one re-parent: a merge of the squash commit with the base forced to merge-base(HEAD, merged branch). Replace it with a single git-merge-onto call, vendored as a zero-dependency file run with python3 so the action needs no download. The two-merge conflict path collapses: on a conflict the action now commits and pushes nothing (the pre-push of the clean half is gone), and the comment asks for one `uvx git-merge-onto`. Drops the conflict-matrix e2e scenario, whose base-vs-trunk distinctions and follow-up-trunk-conflict case only existed because there were two merges. git-merge-onto: https://github.com/scortexio/git-merge-onto Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRBBuBCbXvdmtRQiSMixVL
astral-sh/setup-uv publishes no moving `v8` major tag, so `@v8` fails to resolve. Pin the exact v8.2.0 commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRBBuBCbXvdmtRQiSMixVL
"Merge updates from <target> and squash commit" was vague; the squash commit lives on the target, and the branch this commit exists because of is the merged one. Say "<target> and <merged branch>". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRBBuBCbXvdmtRQiSMixVL
The human-facing conflict comment now says `uvx git-merge-onto origin/<trunk> origin/<merged>` instead of pinning the squash SHA. If trunk advanced since the parent landed, the user resolves those conflicts now (they would have to before merging anyway) and gets readable branch names. The action's own call keeps SQUASH_COMMIT, the stable pin that keeps the resume a no-op. Also fix the e2e's get_conflict_comment: it still grepped the old plural "merge conflicts" heading after the single-merge rewrite made it "a merge conflict", so it found the (correctly posted) comment as 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRBBuBCbXvdmtRQiSMixVL
continue_after_resolution re-ran the re-parent through update_direct_target to "confirm" it. But git-merge-onto's forced base is the old parent, where the lines the user just resolved still differ from the trunk, so the re-merge re-raised the very conflict they had fixed; the no-op skip never fired because the conflict (rc=1) precedes it. (Not a merge-onto bug: "theirs is an ancestor" cannot mean "no-op", or a down-move that must drop the old parent's content would wrongly skip.) The resume only needs to confirm the user's pushed head contains the squash, then retarget and drop the label. Replace the re-merge with that ancestry check. update_direct_target is now used only by the squash-merge path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRBBuBCbXvdmtRQiSMixVL
If the user pushes without finishing the re-parent, the head lacks the squash; make the run fail with an actionable message instead of retrying silently, so they notice and look again. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SRBBuBCbXvdmtRQiSMixVL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-parents each child PR with a single git-merge-onto call (the merge equivalent of
git rebase --onto) instead of the five-command danceupdate_direct_targetused: merge the merged branch, merge the pre-squash target, merge-s oursthe squash,commit-treea three-parent commit, reset. That sequence only ever reconstructed one operation: a merge of the squash commit with the base forced tomerge-base(HEAD, merged branch). git-merge-onto is vendored as a zero-dependency file run withpython3, so the action needs no network download.Conflict: the action commits and pushes nothing on a conflict, leaving the head at its pre-conflict commit (still mergeable, so the resuming
synchronizeevent still fires). The pre-push of the clean half is gone, and the comment asks for a singleuvx git-merge-onto origin/<trunk> origin/<merged>(re-home onto the live trunk, since any newer-trunk conflicts must be resolved before the PR can merge anyway).Resume: the continuation no longer re-runs the merge. Re-parenting an already-resolved head against the old-parent base would re-open the hunk the user just fixed, because that forced base predates their resolution. It now checks the pushed head contains the squash, then retargets and drops the label; if it does not, the run fails so the user sees they need to look again.
update_direct_targetis used only by the squash-merge path now.Removes the conflict-matrix e2e scenario: with one merge there is no base-vs-trunk distinction, and the "follow-up trunk conflict on continuation" case it covered cannot happen, since the single merge brings the trunk content in the first pass.