The index decides which marker blocks git actually wrote - #54
Merged
Conversation
A document ABOUT merge conflicts carries marker-shaped lines of its own. The parser could not tell them from git's, so the view offered the documented example as a decision — and answering it dropped one side of it. Silently: the result pane shows no markers, so there was nothing on screen to notice by. It also claimed two conflicts where git had made one. This is the reference tools' whole reason for not reading $MERGED: JetBrains resolves from the three VCS revisions, so marker-shaped prose is just text on every side. The same source of truth settles it here without replacing git's merge — git never writes markers into the index, so a block that appears verbatim in a pristine side was already in the file, and is put back as stable text. With no index there is nothing to check against and nothing is demoted: guessing there would drop a real conflict. Deliberately NOT recomputing the regions from the three stages, which is what JetBrains does literally. That would replace git's own auto-merge with another algorithm's on the one file this app overwrites, and buys nothing here — git has already decided where the conflicts are, and this only stops us inventing extra ones. The panes now take their seed ranges from the store rather than re-parsing `rawContent`, which is what kept the corrected regions and the seeded decorations from disagreeing — and drops a second parse of the file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
The finding left open at the end of the v0.4.30 audit, now closed.
The bug
A document about merge conflicts carries marker-shaped lines of its own:
Change
settingon both branches and git conflicts that line only. But the parser reads$MERGEDand finds two marker blocks, so the view offered the document's own example as a decision — and answering it dropped one of its two sides. Silently: the result pane deliberately shows no markers, so there was nothing on screen to notice by. It also said "2 conflicts left" where git had made one.Why the reference tools don't have it
JetBrains' resolve-conflicts dialog never reads
$MERGED. It loads the three revisions from the VCS and works from those, so marker-shaped prose is just text — identical on both sides, hence not a conflict.We already read the same three stages. Look at what git puts in the index for the file above:
The example is ordinary text there. git never writes markers into the index — that is the whole test, and it is exact rather than heuristic: a block appearing verbatim in a pristine side was already in the file, so it goes back as stable text.
What I did not do, and why
JetBrains literally recomputes the conflict regions from the three revisions. I deliberately did not.
Doing so replaces git's own auto-merge with another algorithm's output on the one file this app overwrites — every stable line between conflicts would become ours rather than git's, with different answers on whitespace, renames and the rest. It also buys nothing for this bug: git has already decided where the conflicts are, and the only defect was that we invented extra ones. Using the index to validate keeps git's result byte-for-byte and fixes exactly what was broken.
Worth having on record if the full three-way model is ever wanted for its own sake — it would additionally handle a
$MERGEDsomeone had hand-edited.Guarded
2 conflicts left; with it, one decision and the document lands on disk byte-identical, markers and both sides intact.rawContent. That is what kept the corrected regions and the seeded decorations from disagreeing, and it drops a second parse of the file.npm run checkexit 0. 20/20 merge e2e green.🤖 Generated with Claude Code