cli.sgit.ai / Builds / sgit-ai 0.26.5: line-level merge, opt-in

sgit-ai 0.26.5

┌─ sgit-ai 0.26.5 ── dev build ── 28 Oct 2026, 11:25 UTC ─────────────────────────
│ tag v0.26.5 = 43e1889c (dev) · PyPI package == tag
│ new     pull --merge lines · branch merge --merge lines · --conflict diff3
│ tests   5,030 unit+security ✓ · X1–X4 ✓ · 18,000 merges vs git merge-file
│ open    BR-2 (medium, opt-in) · BR-3 (low) · BR-1 (all builds) · R3-1
│ maturity  #######---  good for an opt-in: read line-merged files before a push
└──────────────────────────────────────────────────────────────────────────────────

What is new

Git-parity item 2.1, from design 01.

$ sgit pull --merge lines                         # line by line, for files both sides changed
$ sgit pull --merge lines --conflict diff3        # markers carry the base version too
$ sgit branch merge feature --merge lines
$ export SGIT_MERGE_STYLE=lines                   # per session; or merge_style in .sg_vault/local/config.json

Compatibility

No format change and no gate. A line-merged result is an ordinary commit, which every client reads.

Review by cli.build

Verdict: good for an opt-in feature.

┌─ line merge vs git merge-file · 18,000 random three-way merges, 4 seeds ─────────────
│ verdict                          unique     code-like   3-letter alphabet
│ byte-identical                    8,925        4,501         4,209
│ both conflict, blocks differ          0           41           258    ── BR-3
│ sgit conflict, git clean              0            0            36
│ sgit clean, git conflict              0            2            23    ── BR-2
│ both clean, bytes differ              0            0             5
├──────────────────────────────────────────────────────────────────────────────────────
│ ✓ X1 different lines merge   ✓ X2 markers; commit refuses   ✓ X3 default unchanged
│ ✓ X4 an edit that would get markers refuses the pull, edit kept
└──────────────────────────────────────────────────────────────────────────────────────
  code-like: 60% of lines from {"}", "", "{", "    return x;", "    i++;", "else", …}
  3-letter: every line is a, b or c, the worst case for any line differ

BR-2 (medium, opt-in): a clean merge where Git reports a conflict, when lines repeat

Why it happens:

One of the two code-like cases, seed 4, diff3:

base                ours                       theirs
line 34408          line 34413                 line 34408
{                   line 34412                 {
end                 {                          end
if (a) {            if (a) {                   if (a) {
line 34409          line 34408
                    {
                    end
                    line 34409
                    line 34414
                    if (a) {

git merge-file: a conflict around "line 34409"; theirs deleted it, ours moved "if (a) {" past it
sgit:           clean, = ours, so "line 34409", which theirs deleted, is still there

Either reading is a valid alignment. Git's is the one users expect.

For the CLI team's agent, in order of cost:

  1. Conservative rule. Treat two one-sided changes as touching when the base lines between them, or within one line of them, are not unique in the base. A clean result then needs unambiguous context. It costs a few more conflicts and no silent merges. Re-run fuzz_line_merge.py: the target is 0 in the "sgit clean, git conflict" row.
  2. Exact placement. Port the rest of xdiff's diff (xdl_recs_cmp with its split heuristics and XDF_NEED_MINIMAL off), so that hunks land where Git puts them on repeated lines too. More work, and it also closes BR-3.
  3. Add the repeated-line generators (the "code" and "tiny" kinds in the fuzzer) to the CLI's own tests against git merge-file.

BR-3 (low): conflict blocks drawn differently from Git's

Where both report a conflict, the blocks differ in 41 of 4,544 code-like merges (0.9%): where a block starts and ends, or how many blocks there are. The content is not lost either way. Exact placement (BR-2, option 2) fixes this too.

Scripts: fuzz_line_merge.py <seed> <cases> [merge|diff3], check_build.py. Results: results/lm_*.json with up to three samples per verdict, and results/check_0.26.5.json. All builds: the builds page.

This page as markdown · its source, admin/content/builds/0-26-5.md