feat: add --absorbed to record the old parent as merged#3
Merged
Conversation
Asserts that <new> already carries <old>'s changes (squash merge, rebase merge, cherry-picks): <old>'s tip is recorded as an extra parent of the merge, so the result descends from it and git and GitHub treat <old> as merged instead of dropped. On a conflict the extra parent rides along in MERGE_HEAD, so the resolver's plain git commit records it too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PHUVU3Ek3U9j3LrdjPnyAy
Phlogistique
marked this pull request as ready for review
July 5, 2026 20:40
Phlogistique
added a commit
to scortexio/autorestack-action
that referenced
this pull request
Jul 6, 2026
…59) In scortexio/gh-stack-mv#36 a conflict resolution followed the posted instructions but the action never resumed and the conflict label stayed stuck. The resume rides on a `synchronize` event, and GitHub creates no `pull_request` runs for a PR that conflicts with its base. The PR did conflict with its base (the merged branch, kept until the resume retargets it): autorestack itself had advanced that branch when a grandparent PR merged, so the head no longer descended from its tip, and the resolution rewrote the same lines the squash reshaped, so GitHub's textual mergeability check failed too. The old merge dance guaranteed the descent structurally; the switch to git-merge-onto (#56) dropped that guarantee. This re-vendors git-merge-onto 0.2.0 with its new `--absorbed` flag (scortexio/git-merge-onto#3) and passes it both in the action's own re-parent and in the posted resolution command. The merged branch's tip is recorded as an extra parent of the merge (on a conflict it rides along in `MERGE_HEAD`, so the user's plain `git commit` records it), so the pushed resolution descends from its base again and the resume event is guaranteed to fire. New unit test replays the incident: parent advanced after the child forked, squash-merged, conflicting re-parent, resolution via the posted command; asserts the resolution descends from the old base's tip. The e2e gets the same assertion on its real conflict scenario. Do not merge before git-merge-onto 0.2.0 is on PyPI: the posted command, which the e2e replays verbatim, runs `uvx 'git-merge-onto>=0.2'`. --- _Generated by [Claude Code](https://claude.ai/code/session_01PHUVU3Ek3U9j3LrdjPnyAy)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
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.
By default a re-parent drops the old parent: the result does not descend from its tip, so git and GitHub keep treating it as unmerged.
--absorbedasserts that the new parent already carries the old one's changes without its commits (squash merge, rebase merge, cherry-picks) and records the old parent's tip as an extra parent of the merge, so git and GitHub treat it as merged. On a conflict the extra parent rides along inMERGE_HEAD, so the resolver's plaingit commitrecords it without knowing about the flag. A redundant extra parent (tip already an ancestor) is dropped bygit commititself.Opt-in because it asserts something git can't see: that the old parent's changes were already absorbed into the new parent (via squash merge, rebase merge, or cherry-picks) even though the commit graph shows no link between them. When you move a branch off a parent that is still live, recording it would falsely mark that parent as merged.
Motivation: in scortexio/gh-stack-mv#36, autorestack re-parented a child PR whose parent branch had moved after the fork point and was then squash-merged. The result did not descend from the base branch's tip, the PR read as conflicting, and GitHub creates no
pull_requestworkflow runs on a conflicting PR, so autorestack's resume-after-resolution mechanism could never fire. The old "merge dance" guaranteed that ancestry structurally; the switch to git-merge-onto (scortexio/autorestack-action#56) lost it. autorestack-action passes--absorbedin scortexio/autorestack-action#59, which must wait for this to be released.