jesseduffield.lazygit/pkg/commands
Stefan Haller cf8e5fd27e Recover diff-line identity by parsing the buffer, behind a swappable seam
The focused main view's click/enter/e/G handlers all need the same thing: given
a rendered diff row, the patch-space line it corresponds to. Until now that came
solely from delta's lazygit-edit:// hyperlinks, which only carry a path and a
single line number — no side. That's lossy: for a deletion the number is the old
line, but the consumers fed it into new-file lookups, and two consecutive
deletions (which share a new-file line number) couldn't be told apart at all.

Replace GetFileAndLineForClickedDiffLine with GetDiffLineInfo, returning the
fuller (file, type, new-line, old-line) record from diff-line-metadata-notes.md.
This is mechanism #1: parse the decolorized view buffer — walk up to the file's
"diff --git" section, reuse patch.Parse on it (splitting multi-file commit diffs
on the "diff --git" boundaries), and read the type and line numbers off the patch
arithmetic. It serves the structure-preserving renderings — no pager, git diff
--color, and delta --color-only without line numbers — with no external
dependency.

To avoid trusting a mis-parse, the parser bails when a hunk's body no longer
matches its header (Patch.IsWellFormed). That's what happens when a pager keeps
the diff/hunk headers but restructures the body: delta's line-number gutters push
the +/- marker off the start of each line, so every body line reads as context.
Such renderings fall through to the next backend rather than yielding a confident
wrong answer. (diff-so-fancy goes further and rewrites the headers too, so it
fails even earlier, on the missing "diff --git".)

GetDiffLineInfo is a seam with swappable backends: the buffer parser first, then
the old hyperlink reader as a fallback for renderings the parser can't handle
(delta's default mode, or delta with line-number gutters). The future #2 OSC
per-cell metadata reader plugs in ahead of both, behind the same record shape.

Wire the consumers to the record per that doc's field mapping:
- dive into staging/patch building lands on the exact patch line, looking a
  deletion up by its old-file line number (PatchLineForOldLineNumber) so the
  two-deletions case resolves correctly;
- `e` edits at the new-file line;
- `G` anchors the PR link on the left (old) side for a deletion, the right (new)
  side otherwise.

The hyperlink fallback can't convey the side, so it reports DiffLineOther, which
the consumers treat as a non-deletion — i.e. exactly today's behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-08 12:58:59 +02:00
..
direnv Offer direnv .envrc approval from inside lazygit 2026-06-04 09:05:01 +02:00
git_commands Honor the conflict-marker-size gitattribute 2026-08-08 12:43:42 +02:00
git_config Pin the cached git config's commands to the repo directory 2026-07-20 17:07:39 +02:00
hosting_service Optimize regex compilations 2026-05-10 15:28:14 +02:00
models Make the conflict marker size a parameter of our marker matching 2026-08-08 12:43:42 +02:00
oscommands Start all commands of a pipeline before waiting for any of them 2026-08-06 14:34:47 +02:00
patch Recover diff-line identity by parsing the buffer, behind a swappable seam 2026-08-08 12:58:59 +02:00
testdata Support opening lazygit in a submodule 2019-05-12 17:59:49 +10:00
git.go Tell git where the repo is when it can't find it itself 2026-08-08 11:15:01 +02:00
git_cmd_obj_builder.go Tell git where the repo is when it can't find it itself 2026-08-08 11:15:01 +02:00
git_cmd_obj_builder_test.go Tell git where the repo is when it can't find it itself 2026-08-08 11:15:01 +02:00
git_cmd_obj_runner.go Back off exponentially between lock-error retries 2026-07-15 10:08:44 +02:00
git_cmd_obj_runner_test.go Back off exponentially between lock-error retries 2026-07-15 10:08:44 +02:00