Skip to content

Improve resolving non-textual and submodule merge conflicts#5735

Merged
stefanhaller merged 6 commits into
masterfrom
submodule-conflicts
Jun 28, 2026
Merged

Improve resolving non-textual and submodule merge conflicts#5735
stefanhaller merged 6 commits into
masterfrom
submodule-conflicts

Conversation

@stefanhaller

Copy link
Copy Markdown
Collaborator

For a submodule conflict (where the two branches point the submodule at different commits, resulting in a UU status), pressing space would show a confusing "Nothing to stage…" error, and enter just stepped into the submodule; neither is helpful for resolving the conflict. Now both space and enter open a dialog where you can pick the current commit or the incoming commit, each shown with its head commit subject so you know what you're choosing. And the main panel explains the conflict and lists the commits each side added, so you can see how they diverged before deciding.

This now behaves very similarly to the way you resolve non-textual conflicts for text files (e.g. AU or UD). Speaking of which: for these it was still possible to press space to stage them, which simply ran git add, whose behavior in this case is to keep the file. This is neither obvious nor symmetric, so we change this to route space to the conflict picker too, like enter.

stefanhaller and others added 6 commits June 28, 2026 15:47
Some merge conflicts can't be resolved by editing markers in the merge view;
they require a dialog that picks one side (the "non-textual" conflicts like
DD/AU/UA/UD/DU). Both `enter` and, soon, `space` need to recognize these, so
pull the test into a shared predicate and rename handleNonInlineConflict to
openConflictResolutionMenu to match.

Restructure EnterFile so the predicate is checked first, ahead of the submodule
and inline-conflict branches. This is its final shape: upcoming commits only add
the submodule case to the predicate, with no further reordering. Behavior is
unchanged here, since the predicate is currently false for submodules.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
For a non-textual conflict (e.g. DD/AU/UA/UD/DU), pressing space used to run the
normal stage path, which did something unclear: `git add` happens to resolve the
conflict by keeping the file, but that's neither obvious nor symmetric. Route a
single such file to the same Keep/Delete picker that enter opens, so space and
enter agree.

For a range selection that includes one of these conflicts, staging makes no
sense, so disable it with a toast that points the user at resolving them one at
a time. (Entering a range was already disabled with the standard toast.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When both sides of a merge moved a submodule's gitlink, git reports it as "UU".
Pressing space used to fall into the submodule no-op guard and pop the confusing
"Nothing to stage..." error, and enter just entered the submodule, which does
nothing to resolve the superproject conflict.

Treat a conflicted submodule like the other non-textual conflicts: both space
and enter now open a picker offering the two candidate commits, "current" and
"incoming", each labelled with its summary. `git checkout --ours/--theirs` is a
no-op on gitlinks, so we resolve by checking the submodule out at the chosen
commit and staging it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a conflicted submodule is selected, the main view shows the commits
each side added relative to their common ancestor as two indented logs,
labelled current and incoming, so it's clear which commit each side would
resolve to.

The logs aren't truncated (the view scrolls). If a side added no commits
of its own (e.g. it was rewound to an ancestor of the other), its head
commit is shown instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GetOnRenderToMain had grown to handle five distinct rendering cases inline (no
selection, submodule conflict, inline text conflict, non-textual text conflict,
and the normal working-tree diff), which made it hard to follow. Split each case
into its own method so the function reads as a short dispatcher, and pull the
repeated main-view boilerplate into renderToMainWithTask. Pure refactor; no
behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stefanhaller stefanhaller added the enhancement New feature or request label Jun 28, 2026
@stefanhaller stefanhaller enabled auto-merge June 28, 2026 14:44
@stefanhaller stefanhaller merged commit b31e572 into master Jun 28, 2026
14 checks passed
@stefanhaller stefanhaller deleted the submodule-conflicts branch June 28, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant