ref:main

feat: line-level (diff3) blob merge — stop false-conflicting non-overlapping edits to the same file #62

closed Opened by cole.christensen@gmail.com

Links

No links yet.

Problem

ExGitObjectstore.Merge does a tree-level three-way merge only: when a file’s blob differs on both sides relative to the merge base (and the blobs aren’t byte-identical), resolve_divergent/6 declares a conflict with no attempt at a line-level merge.

This false-conflicts any merge where the same file is touched on both sides — extremely common once main advances onto a file a PR also edited. It surfaced as Anvil PR #159 showing mergeable: conflict while git merge-file merges all four shared files cleanly. Because merge_commits backs merge_branches/squash_merge and Anvil’s compute_mergeable_status, this affects both the mergeability badge and the actual merge.

Fix

Add a proper diff3 line-level merge (ExGitObjectstore.Merge.Diff3) built on the existing Diff.Myers edit script, wired into resolve_divergent for regular files (with exec-bit/mode reconciliation; symlinks, gitlinks, deletions, and binaries fall through to conflict).

Acceptance criteria

  • Non-overlapping edits to the same file merge cleanly; overlapping edits still conflict.
  • Byte-for-byte parity with git merge-file on realistic (distinct-line) inputs, verified by a differential fuzz test.
  • No false auto-merges (never merge cleanly where git conflicts), verified by an adversarial repeated-line fuzz; pathological repeated-line inputs may conservatively over-conflict (safe direction only).
  • Exec-bit mode reconciliation; symlink/gitlink/binary → conflict.
  • All existing merge tests still pass.

Out of scope (follow-ups)

  • Full xdl_merge parity on pathological repeated-run inputs (relates to #55 patience/histogram diff).
  • Recursive/ort multi-base strategies (#56).