Skip to content

Fix conflict markers glued to hunks lacking a trailing newline#119

Open
jochenhz wants to merge 1 commit into
EpicGames:mainfrom
Anchorpoint-Software:fix/diffy-conflict-marker-newlines
Open

Fix conflict markers glued to hunks lacking a trailing newline#119
jochenhz wants to merge 1 commit into
EpicGames:mainfrom
Anchorpoint-Software:fix/diffy-conflict-marker-newlines

Conversation

@jochenhz

Copy link
Copy Markdown

When both sides of a conflict end the file without a trailing newline, the merge glues
the conflict markers onto the content lines and the file becomes unparseable — markers
are only recognizable at the start of a line:

<<<<<<< ours
This is line 2 changed.||||||| original
This is line 2.=======
This is line 2 also changed.>>>>>>> theirs

git merge-file --diff3 puts every marker on its own line for the same inputs.

Repro is easy: commit a file written with no trailing newline on two branches
from a common base, then branch merge start. With trailing newlines the markers come
out fine.

The bug is actually in the diffy crate (add_conflict_marker / add_conflict_marker_bytes
don't check whether the output ends in a newline). I've created PR to fix it upstream:
bmwill/diffy#85

Until that's released, this vendors diffy 0.4.2 with the two-line guard in both marker
builders, wired via [patch.crates-io] like the existing vendor/quinn-proto. There's also a regression test in
lore-revision/tests/merge.rs for the no-trailing-newline case.


Disclosure: I used Claude (Fable) to investigate the root cause of this bug and to
implement the fix. I reviewed and tested the changes myself.

Vendor diffy 0.4.2 with a newline guard in both conflict-marker
builders until a release contains the upstream fix
(bmwill/diffy#85).

Signed-off-by: Jochen Hunz <j.hunz@anchorpoint.app>
@jochenhz
jochenhz force-pushed the fix/diffy-conflict-marker-newlines branch from caaa1b4 to f80f8de Compare July 18, 2026 13:24
@mjansson

Copy link
Copy Markdown
Collaborator

Moving the markers to a new line is objectively wrong though, as that introduces a newline character in the content that is not actually there. If you then select mine or theirs hunk, you get a modification to the original mine or theirs file - an extra newline.

@bmwill

bmwill commented Jul 20, 2026

Copy link
Copy Markdown

I did accept the fix the @jochenhz submitted to diffy because he is correct in that the old behavior did not match the behavior of git merge-file --diff3. What i failed to check before accepting the fix is that the old behavior did correctly match the output of GNU diff3. So in this case it comes down to the fact that these two tools opted for different solutions, git likely optimizing for readability of the conflict.

Happy to take suggestions on how you'd like this addressed in diffy itself, it probably makes the most sense to provide a config toggle to select which behavior the user would like the output to match.

@jochenhz

Copy link
Copy Markdown
Author

I see the point that it creates a newline character that wasn't there before the merge. But Git is doing it like that and tools such as VSCode and Diffs (Conductor) cannot parse the diff created by Lore.
So at least a config value would be appreciated to match Git output.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants