Skip to content

Stop corrupting PRs whose base changed during conflict resolution#39

Merged
Phlogistique merged 7 commits into
mainfrom
fix-conflict-resume-detect-manual-retarget
Jun 2, 2026
Merged

Stop corrupting PRs whose base changed during conflict resolution#39
Phlogistique merged 7 commits into
mainfrom
fix-conflict-resume-detect-manual-retarget

Conversation

@Phlogistique
Copy link
Copy Markdown
Collaborator

@Phlogistique Phlogistique commented Jun 1, 2026

When a PR sat in autorestack-needs-conflict-resolution and a human changed its base instead of resolving the conflict, the resume run rebuilt its state with gh pr list --head <base> | .[0]. On a long-lived base like spark that returns an unrelated ancient merge: in run 26764629741 it picked a 2022 release merge into the deleted branch spark-v1.13.0-rc-dev, pushed a merge commit built against it onto the PR, removed the conflict label, then crashed setting the base to the missing branch.

The resume now recovers base/target/squash from a marker the squash-merge run embeds in the conflict comment, and bails before any mutation when the marker is missing or the PR's current base no longer matches the one we left it on (the manual-retarget case). Target existence is checked as a backstop, and the base retarget runs before the label is dropped so a failure leaves the PR resumable.

New unit test tests/test_conflict_resolution_resume.sh covers the three dead-end paths (missing marker, manual retarget, missing target) and the happy-path ordering: push the cleaned-up head, retarget the base, then remove the label.

Phlogistique and others added 7 commits June 1, 2026 18:02
When a PR sat in autorestack-needs-conflict-resolution and a human changed
its base instead of resolving the conflict, the resume run rebuilt its state
with `gh pr list --head <base> | .[0]`. On a long-lived base like `spark`
that returns an unrelated ancient merge: in run 26764629741 it picked a 2022
release merge into the deleted branch `spark-v1.13.0-rc-dev`, pushed a merge
commit built against it onto the PR, removed the conflict label, then crashed
setting the base to the missing branch.

The resume now recovers base/target/squash from a marker the squash-merge run
embeds in the conflict comment, and bails before any mutation when the marker
is missing or the PR's current base no longer matches the one we left it on
(the manual-retarget case). Target existence is checked as a backstop, and the
base retarget runs before the label is dropped so a failure leaves the PR
resumable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The missing-target backstop returned silently, leaving the PR labeled with
no explanation and no path to ever resume. It now posts a comment and drops
the label like the other two dead-end cases, routed through a shared
abandon_resume helper.
Both ordering comments narrated the bug being prevented ("the step that
previously failed", "the failure mode where we pushed a merge against a bogus
target and crashed"). Restate them as the rules a fresh reader needs: the base
check runs before any mutation because a diverged base makes the recorded
target stale, and the label drops last so any earlier failure stays resumable.
The marker is a new source for the base the PR is moving off of, not a new
concept, so renaming OLD_BASE to RECORDED_BASE was only diff churn. It reads
fine next to CURRENT_BASE.
The conflict-resolved path relies on pushing the cleaned-up head before retargeting the base, and retargeting before dropping the retry label. The focused resume test now records git commands as well as gh calls so that ordering is enforced, and the README happy path matches the same sequence.
@Phlogistique Phlogistique marked this pull request as ready for review June 2, 2026 07:42
@Phlogistique Phlogistique merged commit e80c278 into main Jun 2, 2026
3 checks passed
@github-actions github-actions Bot deleted the fix-conflict-resume-detect-manual-retarget branch June 2, 2026 07:43
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.

1 participant