Skip to content

diff: merge hunks separated by up to twice the context size - #306

Merged
sylvestre merged 1 commit into
uutils:mainfrom
emirmrkaljevic:fix-hunk-merging
Oct 18, 2026
Merged

sylvestre merged 1 commit into
uutils:mainfrom
emirmrkaljevic:fix-hunk-merging

Conversation

@emirmrkaljevic

Copy link
Copy Markdown
Contributor

Fixes #268.

GNU diff keeps two changes in one hunk as long as at most 2*N unchanged lines separate them (N = context size). We were splitting earlier: after N lines in unified mode and N+1 in context mode. With -U1 on the shopping files from the issue, that gave two hunks, the second one without its leading context line.

Both make_diff functions now start a new hunk only when the gap is larger than 2*N. Context lines in between already go through context_queue, so they now get added to the current hunk.

Added test_hunk_merging to unified_diff.rs and context_diff.rs (gap of 2*N merges, 2*N+1 splits; the expected output comes from GNU diff 3.10). I also ran a few thousand random small file pairs with -U0..4 and -C0..4. The output still applies with patch, and no two hunks touch or overlap anymore. Before this change, about 840 of 3000 runs had adjacent hunks. cargo test, cargo clippy -- -D warnings and cargo fmt --check pass.

GNU diff keeps two changes in the same unified or context hunk when at
most 2*N unchanged lines separate them. We split them earlier (after N
lines for -u, N+1 for -c), so we printed separate hunks where GNU
prints one, and -u could start a hunk with no leading context.

Fixes uutils#268
Comment thread src/unified_diff.rs
let from = ["a", "b", "c", "d", "e", "f", "g", ""].join("\n");
let to = ["a", "B", "c", "d", "e", "F", "g", ""].join("\n");
let expected = [
"--- foo\tTIMESTAMP",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please also add the case from the issue (an insertion, so different line counts on both sides)?
in a different PR

@sylvestre
sylvestre merged commit 141e2d6 into uutils:main Oct 18, 2026
31 checks passed
@sylvestre

Copy link
Copy Markdown
Collaborator

Thanks for your PR

@emirmrkaljevic

Copy link
Copy Markdown
Contributor Author

Hey, of course. Here it is: #307

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.

context hunk merging in diff

2 participants