Skip to content

update: each changed file lives on one shared row, and stage hunks the index holds part of - #61

Merged
undont merged 93 commits into
mainfrom
feat/mm-unified-diff
Oct 9, 2026
Merged

undont merged 93 commits into
mainfrom
feat/mm-unified-diff

Conversation

@undont

@undont undont commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • a file changed in both the index and the worktree lists once, under a new Partial section, instead of once per side. every row diffs HEAD to the worktree with the lines the index already holds shaded; sections come from git's status letters: Conflicts, Staged, Partial, Unstaged, Untracked
  • staged state is tracked per line, so s and u act on a hunk the index holds only part of, and the winbar tallies staged and partial hunks
  • staging no longer patches the index: each op works out the content the index should hold and writes it whole, so a hunk can't land on the wrong side of a context line
  • staged content the diff can't draw (staged then put back, staged then edited again, a staged mode change undone on disk) gets a ! in the gutter and a winbar note. dw opens what changed since staging, where it shows as hunks of its own and s / u / X work on it, including a mode change, a binary file and a staged add whose file was deleted
  • u on a ! hunk takes back only the lines it rewrote, and names the whole staged block when it can't
  • ds previews the commit: the panel lists only the staged files, each diffed HEAD to the index, and u takes changes back out. X there refuses rather than discard unstaged work the preview doesn't show
  • X on a hunk discards it from the index and the file together, rather than asking you to unstage it first
  • X reverts a mode change or a binary file from the diff, and brings a staged edit whose file was deleted back as staged, in the diff and the panel alike
  • u and U ask before dropping staged content that neither HEAD nor the file holds, in the diff and the panel alike
  • S / U take the whole file to the worktree's or HEAD's side, mode included; a rename's move stays with the panel row
  • the s / u walk goes down the list once and ends by saying what is left. s stops on a file whose remaining change only dw shows, until dw finishes it or ]f leaves it
  • editing from a staged diff no longer unstages the whole file first
  • a change to a file's final newline is a hunk on the last line, with a ¬ in the gutter on whichever side ends without one
  • some other small fixes: paths with glob characters or a leading 1: no longer stage the wrong content, symlinks diffing as their target, discarding a staged rename or add whose file was deleted, "stage failed" on a staged rename or deletion from the panel, a file swapped for a symlink refusing every staging key, and panel X silently doing nothing on a submodule

Test plan

  • make check clean
  • driven headless against a scratch repo covering MM, RM, RD, AD, MD, kept deletions, symlinks, glob and colon paths, a merge conflict and all four final-newline cases, with both review walks run end to end
  • s / S / u / U / X walked headless across the whole diff, whole-file rows, the local view, the INDEX view and the commit preview; each finding fixed with a spec
  • ~20,000 fuzzed ops (s / S / u / U / X, dw and ds) across 8 seeds: no lua errors, no write to the wrong path or the worktree, no index line from outside HEAD, the index, the worktree or the open view's snapshot

@undont
undont marked this pull request as draft September 25, 2026 18:01
@undont undont changed the title feat: each changed file lives on one shared row, and stage hunks the index holds part of update: each changed file lives on one shared row, and stage hunks the index holds part of Oct 4, 2026
@undont
undont marked this pull request as ready for review October 8, 2026 12:02
@undont
undont merged commit 1feecdd into main Oct 9, 2026
11 checks passed
@undont
undont deleted the feat/mm-unified-diff branch October 9, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant