]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'mm/line-log-limited-ops' into mm/diff-process-hunks
authorJunio C Hamano <gitster@pobox.com>
Sun, 26 Jul 2026 21:03:04 +0000 (14:03 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 26 Jul 2026 21:03:04 +0000 (14:03 -0700)
* mm/line-log-limited-ops:
  diffcore-pickaxe: scope -G to the -L tracked range
  diff: support --check with -L line ranges
  line-log: support diff stat formats with -L
  diff: extract a line-range diff helper for reuse
  diff: emit -L hunk headers via xdiff's formatter
  diff: simplify the line-range filter by classifying removals immediately
  diff: rename and group the line-range filter for clarity

1  2 
diff.c
diffcore-pickaxe.c
revision.c
t/t4211-line-log.sh
xdiff-interface.c

diff --cc diff.c
Simple merge
Simple merge
diff --cc revision.c
Simple merge
index e61ef9b21104b2c461672743cde92c962d1c3831,bac74d44794778e1d31fb904f8027ae7fe722921..ba3ea94c856d468e8e3a8c59ced2fa1535b19938
@@@ -731,13 -722,138 +722,138 @@@ test_expect_success '-L with -S filter
  test_expect_success '-L with -G filters to diff-text matches' '
        git checkout parent-oids &&
        git log -L:func2:file.c -G "F2 [+] 2" --format= >actual &&
-       # -G greps the whole-file diff text, not just the tracked range;
-       # combined with -L, this selects commits that both touch func2
-       # and have "F2 + 2" in their diff.
+       # -G greps the diff text, and under -L only the lines in the
+       # tracked range (unlike -S above, which searches the whole file);
+       # this selects commits whose change to func2 contains "F2 + 2".
        test $(grep -c "^diff --git" actual) = 1 &&
 -      grep "F2 + 2" actual
 +      test_grep "F2 + 2" actual
  '
  
+ test_expect_success 'setup for trailing deletion test' '
+       git checkout --orphan trailing-del &&
+       git reset --hard &&
+       cat >file.c <<-\EOF &&
+       void tracked()
+       {
+           return 1;
+       }
+       // trailing comment
+       EOF
+       git add file.c &&
+       test_tick &&
+       git commit -m "add file with trailing comment" &&
+       # Modify tracked() AND delete the trailing comment in
+       # one commit, so the commit touches the tracked range
+       # and is not filtered out by the revision walker.
+       cat >file.c <<-\EOF &&
+       void tracked()
+       {
+           return 2;
+       }
+       EOF
+       git commit -a -m "modify tracked and delete trailing comment"
+ '
+ test_expect_success '-L does not include deletions past end of tracked range' '
+       git log -L:tracked:file.c --format= -1 -p >actual &&
+       # The trailing comment deletion is outside the tracked
+       # range and should not appear in the patch output.
+       test_grep "return 2" actual &&
+       test_grep ! "trailing comment" actual
+ '
+ test_expect_success '-L includes leading deletions resolved by in-range line' '
+       git checkout --orphan leading-del &&
+       git reset --hard &&
+       cat >file.c <<-\EOF &&
+       // leading comment
+       void tracked()
+       {
+           return 1;
+       }
+       EOF
+       git add file.c &&
+       test_tick &&
+       git commit -m "add file with leading comment" &&
+       cat >file.c <<-\EOF &&
+       void tracked()
+       {
+           return 2;
+       }
+       EOF
+       git commit -a -m "modify tracked and delete leading comment" &&
+       git log -L:tracked:file.c --format= -1 -p >actual &&
+       # The leading comment deletion is resolved by the next
+       # non-removal line (void tracked), which is in range: a
+       # removal is classified by the position of the following
+       # line, so it joins the range that line falls in.
+       test_grep "return 2" actual &&
+       test_grep "leading comment" actual
+ '
+ test_expect_success 'setup for line-range filter edge cases' '
+       git checkout --orphan filter-edge &&
+       git reset --hard &&
+       cat >file.c <<-\EOF &&
+       void before()
+       {
+           return 0;
+       }
+       void tracked()
+       {
+           int a = 1;
+           int b = 2;
+           int c = 3;
+           return a + b + c;
+       }
+       void after()
+       {
+           return 9;
+       }
+       EOF
+       git add file.c &&
+       test_tick &&
+       git commit -m "initial"
+ '
+ test_expect_success '-L change at exact first line of range' '
+       git checkout filter-edge &&
+       # Change the function signature (first line of range)
+       sed "s/void tracked/int tracked/" file.c >tmp &&
+       mv tmp file.c &&
+       git commit -a -m "change first line" &&
+       git log -L:tracked:file.c -p --format=%s -1 >actual &&
+       test_grep "change first line" actual &&
+       test_grep "+int tracked" actual &&
+       test_grep "\\-void tracked" actual
+ '
+ test_expect_success '-L change at exact last line of range' '
+       git checkout filter-edge &&
+       git reset --hard HEAD~1 &&
+       # Change the closing brace line (last line of range)
+       sed "s/^}$/} \/\/ end tracked/" file.c >tmp &&
+       mv tmp file.c &&
+       git commit -a -m "change last line" &&
+       git log -L:tracked:file.c -p --format=%s -1 >actual &&
+       test_grep "change last line" actual &&
+       test_grep "end tracked" actual
+ '
+ test_expect_success '-L pure deletion in range (no additions)' '
+       git checkout filter-edge &&
+       git reset --hard HEAD~1 &&
+       # Delete a line inside tracked() without adding anything
+       sed "/int c/d" file.c >tmp &&
+       mv tmp file.c &&
+       git commit -a -m "pure deletion" &&
+       git log -L:tracked:file.c -p --format=%s -1 >actual &&
+       test_grep "pure deletion" actual &&
+       test_grep "\\-.*int c" actual
+ '
  test_expect_success '-L with --diff-filter=M excludes root commit' '
        git checkout parent-oids &&
        git log -L:func2:file.c --diff-filter=M --format=%s --no-patch >actual &&
Simple merge