Skip to content

feat: add --absorbed to record the old parent as merged#3

Merged
Phlogistique merged 1 commit into
mainfrom
claude/absorbed-flag
Jul 5, 2026
Merged

feat: add --absorbed to record the old parent as merged#3
Phlogistique merged 1 commit into
mainfrom
claude/absorbed-flag

Conversation

@Phlogistique

@Phlogistique Phlogistique commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

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. --absorbed asserts 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 in MERGE_HEAD, so the resolver's plain git commit records it without knowing about the flag. A redundant extra parent (tip already an ancestor) is dropped by git commit itself.

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_request workflow 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 --absorbed in scortexio/autorestack-action#59, which must wait for this to be released.

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
Phlogistique marked this pull request as ready for review July 5, 2026 20:40
@Phlogistique
Phlogistique merged commit 1c71a35 into main Jul 5, 2026
2 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 5, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants