Skip to content

Fix workspace merge failure when stacks have adjacent edits#13155

Merged
krlvi merged 1 commit intomasterfrom
refactor-git2-to-gix
Apr 2, 2026
Merged

Fix workspace merge failure when stacks have adjacent edits#13155
krlvi merged 1 commit intomasterfrom
refactor-git2-to-gix

Conversation

@mtsgrd
Copy link
Copy Markdown
Contributor

@mtsgrd mtsgrd commented Apr 2, 2026

When two stacks each modify adjacent but non-overlapping lines in the
same file, git2 treats the adjacent hunks as conflicting. This caused
update_uncommitted_changes to fail with MergeConflict (-24) on any
mutation that recomputed the workspace tree (squash, reorder, etc.)
— even though the stacks don't actually conflict.

The workspace commit was already built using gix
(remerged_workspace_tree_v2), which resolves adjacent hunks cleanly,
so it was possible to reach a valid workspace state that then broke on
every subsequent operation.

Fix

Replace the git2 octopus merge in merge_workspace with the same
gix-based approach used for workspace commit creation:
merge_options_fail_fast + has_unresolved_conflicts. The function
now returns gix::ObjectId; callers in integrate.rs that pass the
result into git2 APIs convert with .to_git2().

Test

Add a regression test that calls merge_workspace directly with two
stacks whose edits are adjacent from both sides (Stack A owns lines 1–5
and 11–15, Stack B owns lines 6–10). Verified the test fails with
MergeConflict (-24) under git2 and passes under gix.

Copilot AI review requested due to automatic review settings April 2, 2026 09:45
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gitbutler-web Ignored Ignored Preview Apr 2, 2026 11:36am

Request Review

@github-actions github-actions Bot added the rust Pull requests that update Rust code label Apr 2, 2026
@mtsgrd mtsgrd requested a review from Byron April 2, 2026 09:45
@mtsgrd mtsgrd changed the title Fix squash failure caused by git2/gix merge algorithm divergence Fix workspace error caused by git2/gix merge algorithm divergence Apr 2, 2026
@mtsgrd mtsgrd changed the title Fix workspace error caused by git2/gix merge algorithm divergence Fix workspace errors caused by git2/gix merge algorithm divergence Apr 2, 2026
@mtsgrd mtsgrd force-pushed the refactor-git2-to-gix branch from c59241f to b9401de Compare April 2, 2026 09:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes false-positive merge conflicts during workspace mutations (e.g., squash/reorder) caused by a divergence between git2’s Myers diff merge behavior and gix’s merge behavior when stacks modify adjacent but non-overlapping hunks. It aligns workspace tree computation with the already-used gix merge approach so valid workspace states don’t later fail during recomputation.

Changes:

  • Replaced the git2-based octopus merge in merge_workspace with a gix-based merge using merge_options_fail_fast + has_unresolved_conflicts.
  • Updated workspace tree recomputation paths to use a merge-optimized gix::Repository, converting results to git2 OIDs only at git2 API boundaries.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
crates/gitbutler-workspace/src/branch_trees.rs Switches workspace tree octopus merge from git2 to gix and threads a merge-optimized gix repo through uncommitted-change update flows.
crates/but-worktrees/src/integrate.rs Updates integration conflict checks to compute workspace trees via gix and convert to git2 only when calling move_tree.

@mtsgrd
Copy link
Copy Markdown
Contributor Author

mtsgrd commented Apr 2, 2026

@Byron this is different from the others but it has a similar consequence. In this screenshot there are two commits that touch Segment.svelte, they do not overlap, but have adjacent edits on lines 24:25.

As a result, any operation that recomputes the workspace commit failed, and knowing why takes knowledge of this bug. It took me a few minutes to find the culprit, even though I knew what to look for.

image
command: squash_commits
params: {"projectId":"L1VzZXJzL21hdHRpYXMvYy9naXRidXRsZXIvLmdpdA","stackId":"5323a6a0-fbcf-41ad-987e-9344d96a9a99","sourceCommitIds":["b8460f75257ee8dc5e5b9cf54caccf409892bc75"],"targetCommitId":"1ffae114a3d46b6e547c62b92a2e527a18829819"})

merge conflicts exist; class=Merge (22); code=MergeConflict (-24)

@mtsgrd mtsgrd force-pushed the refactor-git2-to-gix branch from b9401de to c149222 Compare April 2, 2026 11:34
When two stacks each modify adjacent but non-overlapping lines in the
same file, git2 treats the adjacent hunks as conflicting. This caused
`update_uncommitted_changes` to fail with `MergeConflict (-24)` on any
mutation that recomputed the workspace tree (squash, reorder, etc.)
— even though the stacks don't actually conflict.

The workspace commit was already built using gix
(`remerged_workspace_tree_v2`), which resolves adjacent hunks cleanly,
so it was possible to reach a valid workspace state that then broke on
every subsequent operation.

Fix by replacing the git2 octopus merge in `merge_workspace` with the
same gix-based approach used for workspace commit creation:
`merge_options_fail_fast` + `has_unresolved_conflicts`. The function
now returns `gix::ObjectId`; callers in `integrate.rs` that pass the
result into git2 APIs convert with `.to_git2()`.

Add a regression test that calls `merge_workspace` directly with two
stacks whose edits are adjacent from both sides (Stack A owns lines 1–5
and 11–15, Stack B owns lines 6–10). The test confirms the fix by
failing with `MergeConflict (-24)` under git2 and passing under gix.
@mtsgrd mtsgrd force-pushed the refactor-git2-to-gix branch from c149222 to d954a50 Compare April 2, 2026 11:36
@mtsgrd mtsgrd changed the title Fix workspace errors caused by git2/gix merge algorithm divergence Fix workspace merge failure when stacks have adjacent edits Apr 2, 2026
@krlvi krlvi merged commit dc0c262 into master Apr 2, 2026
37 checks passed
@krlvi krlvi deleted the refactor-git2-to-gix branch April 2, 2026 16:34
@Byron
Copy link
Copy Markdown
Collaborator

Byron commented Apr 5, 2026

It's good to see that gix is actually fixing something merge-related this time 😅.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants