Skip to content

Show unchanged lines that fall inside an inline hunk#980

Open
ChrisJr404 wants to merge 1 commit into
Wilfred:masterfrom
ChrisJr404:fix-git-config-quoted-section-headers
Open

Show unchanged lines that fall inside an inline hunk#980
ChrisJr404 wants to merge 1 commit into
Wilfred:masterfrom
ChrisJr404:fix-git-config-quoted-section-headers

Conversation

@ChrisJr404
Copy link
Copy Markdown

Closes #978.

Bug

When two novel lines in a hunk are close enough that the merge step in display::hunks::merge_adjacent combines them into one hunk, the unchanged lines between them are silently dropped from inline (--display=inline) output. Side-by-side and JSON output don't have this problem because both use matched_lines_indexes_for_hunk to walk the full hunk range, so they already include the in-between unchanged lines. Inline was iterating hunk.lines directly, and that field only contains positions with novel content.

In the report this surfaces as a missing section heading on a .gitconfig:

$ difft before.gitconfig after.gitconfig --display=inline

The line [url "ssh://git@github.com"] between two changed pushInsteadOf = lines does not appear.

Repro

before.gitconfig:

[uploadpack]
    allowFilter = true

[url "ssh://aur@aur.archlinux.org"]
    pushInsteadOf = "https://aur.archlinux.org"

[url "ssh://git@github.com"]
    pushInsteadOf = "https://github.com"

[versionsort]
    # prereleaseSuffix is deprecated in favour of suffix

after.gitconfig (same, but both pushInsteadOf lines are commented out):

[uploadpack]
    allowFilter = true

[url "ssh://aur@aur.archlinux.org"]
    ; pushInsteadOf = "https://aur.archlinux.org"

[url "ssh://git@github.com"]
    ; pushInsteadOf = "https://github.com"

[versionsort]
    # prereleaseSuffix is deprecated in favour of suffix

Before this PR

/tmp/after3.gitconfig --- Text
1    [uploadpack]
2        allowFilter = true
3    
4    [url "ssh://aur@aur.archlinux.org"]
5        pushInsteadOf = "https://aur.archlinux.org"
8        pushInsteadOf = "https://github.com"
   5     ; pushInsteadOf = "https://aur.archlinux.org"
   8     ; pushInsteadOf = "https://github.com"
   9 
   10 [versionsort]
   11     # prereleaseSuffix is deprecated in favour of suffix

Lines 6 (blank) and 7 ([url "ssh://git@github.com"]) are missing on both sides.

After this PR

/tmp/after3.gitconfig --- Text
1    [uploadpack]
2        allowFilter = true
3    
4    [url "ssh://aur@aur.archlinux.org"]
5        pushInsteadOf = "https://aur.archlinux.org"
6    
7    [url "ssh://git@github.com"]
8        pushInsteadOf = "https://github.com"
   5     ; pushInsteadOf = "https://aur.archlinux.org"
   6 
   7 [url "ssh://git@github.com"]
   8     ; pushInsteadOf = "https://github.com"
   9 
   10 [versionsort]
   11     # prereleaseSuffix is deprecated in favour of suffix

Fix

Add a small fill_in_hunk_gaps helper in src/display/inline.rs that walks hunk.lines and emits the intervening line numbers for each side, then update the LHS and RHS print loops to consult hunk.novel_lhs / hunk.novel_rhs so the new gap entries render with dimmed (context) line numbers instead of bold red / green ones.

I considered switching inline to use all_matched_lines_filled + matched_lines_indexes_for_hunk the same way side-by-side does, but that would also require restructuring how the before / after context loops are integrated. This narrower change keeps the existing structure and only fixes the dropped-context-inside-hunk case.

Testing

  • Added four unit tests for fill_in_hunk_gaps covering the empty input, no-gap, LHS-only-changes-with-an-unchanged-tail, and unequal-side-gaps shapes.
  • cargo test --release (148 tests) passes.
  • Manually verified against the .gitconfig repro above and against syntactic (Rust) inputs to confirm the multi-hunk path still splits correctly when changes are far apart.

When two novel lines in a hunk are close enough to merge into a single
hunk, the unchanged lines between them were dropped from inline display
output. Side-by-side rendering uses matched_lines_indexes_for_hunk to
walk the full hunk range, so it already includes these lines. Inline
was iterating hunk.lines directly, which only contains positions with
novel content.

This is most visible on .gitconfig files where a section heading like
[url "ssh://git@github.com"] sits between two pushInsteadOf edits and
silently disappears from the diff (issue Wilfred#978).

Add a fill_in_hunk_gaps helper that walks hunk.lines and emits the
intervening line numbers for each side, then update the LHS and RHS
print loops to use the hunk's novel_lhs / novel_rhs sets so that gap
lines render as context rather than as added or removed.

Signed-off-by: Chris <chris@hacknow.com>
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.

Incorrect diff with git config

1 participant