fix(but-graph): don't pin an orphaned target commit after a history rewrite#14556
Open
ameyypawar wants to merge 1 commit into
Open
fix(but-graph): don't pin an orphaned target commit after a history rewrite#14556ameyypawar wants to merge 1 commit into
ameyypawar wants to merge 1 commit into
Conversation
When a target branch's history is rewritten upstream (e.g. `git filter-repo` or `git filter-branch` followed by a force-push), the stored target commit (`gitbutler.project.targetCommitId`) points at a commit that still exists as an object but shares no history with the rewritten target ref. Workspace graph init pinned it as an integrated tip after only checking that the object existed, so the workspace ended up with no merge-base against its target -- the perpetual "No merge-base found" / "Target branch divergence" state described in the issue. Before pinning a stored target commit, drop it when, on a full clone, it shares no merge-base with the live target-ref tip (a genuine rewrite); the workspace then falls back to the live target tip. On a shallow clone the commit is kept, because gix's merge-base cannot distinguish a below-graft merge-base from a real rewrite, so keeping it is the conservative choice. Adds a regression test for the full-clone orphaned-target case. Fixes gitbutlerapp#14415
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.
Fixes #14415.
Bug
After an upstream history rewrite (
git filter-repo/git filter-branch+ force-push), GitButler gets stuck in a perpetual "No merge-base found" / "Target branch divergence" state and keeps recreatinggitbutler/workspacefrom the pre-rewrite commit.Cause
The stored target commit (
gitbutler.project.targetCommitId) still exists as an object but is disjoint from the rewritten target ref. Inbut-graph'sinitial_tips_from_workspace_metadata, a storedtarget_commit_idwas pinned as an integrated tip after only checking that the object existed (repo.find_commit) — never that it was still reachable from the target. The orphaned commit got pinned, leaving the workspace with no merge-base against its target. (This matches @shanoor's root-cause analysis in the issue.)Fix
Before pinning a stored target commit, drop it when — on a full clone — it shares no merge-base with the live target-ref tip (a genuine rewrite). The workspace then falls back to the live target tip and the merge-base is restored.
On a shallow clone the commit is kept: gix's merge-base silently treats a below-graft parent as a root, so a below-graft merge-base is indistinguishable from a real rewrite — keeping the stored commit is the conservative choice and matches prior behavior (never dropping a still-reachable target).
Test
Adds
ignores_orphaned_target_commit_unreachable_from_target_ref, which pins a disjoint commit as the target and asserts the workspace resolves to the live target tip instead. Fails onmaster, passes here; the fullbut-graphsuite stays green.