Post a plain two-merge conflict resolution instead of a git-merge-onto re-parent#61
Closed
Phlogistique wants to merge 2 commits into
Closed
Conversation
The conflict comment asked the user to run a single `uvx 'git-merge-onto>=0.2' --absorbed origin/<trunk> origin/<merged>`. --absorbed is an obscure assertion flag; a plain two-step recipe reads better. The recipe is now `git merge origin/<merged>` (catch up to the moved base), then `uvx git-merge-onto origin/<trunk> origin/<merged>` (re-home onto the trunk). The first step is what --absorbed was for: it lands the merged branch's tip in the resolved head's ancestry, and the re-home keeps it as a parent, so the pushed head still descends from its base and GitHub fires the resume event. Splitting also gives the user a base-vs-parent conflict and a base-vs-trunk conflict separately instead of one merge that conflates both. No rebase detection comes back with it: the recipe never references SQUASH_COMMIT~ (the reference that broke on rebase merges, dropped in #60), only branch tips, which carry the same content under squash and rebase. The action's own clean re-parent keeps --absorbed; it is internal and unchanged. Only the user-facing recipe drops it, so the posted command runs on the published git-merge-onto 0.1.0 and no longer waits for 0.2.0 on PyPI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SKuDUgzS8rSA4mvJ1r7Djd
The second step re-parented with `uvx git-merge-onto origin/<trunk> origin/<merged>`. Replace it with a plain `git merge origin/<trunk>`: the trunk already carries the merged branch's content, so once the head contains the trunk the retargeted diff shows only the child's own changes -- dropping the base explicitly is unnecessary. The recipe is now entirely plain git. Still rebase-safe and still needs no rebase detection: both merges name branch tips, never SQUASH_COMMIT or its parent. Tradeoff: git-merge-onto forced the merge base to the parent's tip, which kept the trunk step clean when the child had edited its parent's lines. A plain `git merge origin/<trunk>` uses the true merge base, so in that case the child re-resolves the same region against the trunk. The unit test now covers this (both merges conflict on the same line). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SKuDUgzS8rSA4mvJ1r7Djd
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.
Stacked on #60.
The conflict comment asked the user to run a single
uvx 'git-merge-onto>=0.2' --absorbed origin/<trunk> origin/<merged>.--absorbedis an obscure flag andgit-merge-ontois an extra tool to reach for; the resolution is now two plain merges:Why this works without a re-parent:
synchronizeevent, and GitHub creates no runs for a PR that conflicts with its base (the merged branch, kept until the resume retargets it). The first merge lands the merged branch's tip in the head's ancestry, so the pushed head descends from its base and the event fires. This is the role--absorbedplayed.No rebase detection comes back with it: both merges name branch tips, never
SQUASH_COMMITor its parent (theSQUASH_COMMIT~reference that broke on rebase merges, dropped in #60), so a squash and a rebase merge resolve identically.Tradeoff:
git-merge-ontoforced the merge base to the parent's tip, which kept the trunk step clean when the child had edited its parent's own lines. A plaingit merge origin/<trunk>uses the true merge base, so in that case the child re-resolves the same region against the trunk. In the common case (the child's changes are elsewhere) the base merge is a no-op or a clean fast-forward and only the trunk merge conflicts.The action's own automated re-parent still uses
git-merge-onto --absorbedinternally on the clean path; only the user-facing recipe changed. Since the posted command drops--absorbed, it no longer waits for git-merge-onto 0.2.0 on PyPI.test_conflict_absorbed_resolution.sh(which replayed the incident that motivated--absorbed) becomestest_conflict_two_step_resolution.shand asserts the same descent guarantee, now provided by the first merge. The e2e's conflict-comment assertion and resume checks follow the plain recipe.🤖 Generated with Claude Code
https://claude.ai/code/session_01SKuDUgzS8rSA4mvJ1r7Djd