Skip to content

Commit 9650e54

Browse files
committed
t4211: add tests for -L with standard diff options
Now that -L output flows through the standard diff pipeline, verify that previously-ignored diff options work: formatting (--word-diff, --word-diff-regex, --no-prefix, --src/dst-prefix, --full-index, --abbrev), whitespace handling (-w, -b), output indicators (--output-indicator-new/old/context), direction reversal (-R), --color-moved, and pickaxe options (-S, -G). Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
1 parent cf6df2b commit 9650e54

File tree

1 file changed

+281
-0
lines changed

1 file changed

+281
-0
lines changed

t/t4211-line-log.sh

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,92 @@ test_expect_success 'zero-width regex .* matches any function name' '
339339
test_cmp expect actual
340340
'
341341

342+
test_expect_success 'setup for diff pipeline tests' '
343+
git checkout parent-oids &&
344+
345+
head_blob_old=$(git rev-parse --short HEAD^:file.c) &&
346+
head_blob_new=$(git rev-parse --short HEAD:file.c) &&
347+
root_blob=$(git rev-parse --short HEAD~4:file.c) &&
348+
null_blob=$(test_oid zero | cut -c1-7) &&
349+
head_blob_old_full=$(git rev-parse HEAD^:file.c) &&
350+
head_blob_new_full=$(git rev-parse HEAD:file.c) &&
351+
root_blob_full=$(git rev-parse HEAD~4:file.c) &&
352+
null_blob_full=$(test_oid zero)
353+
'
354+
355+
test_expect_success '-L diff output includes index and new file mode' '
356+
git log -L:func2:file.c --format= >actual &&
357+
358+
# Output should contain index headers (not present in old code path)
359+
grep "^index $head_blob_old\.\.$head_blob_new 100644" actual &&
360+
361+
# Root commit should show new file mode and null index
362+
grep "^new file mode 100644" actual &&
363+
grep "^index $null_blob\.\.$root_blob$" actual &&
364+
365+
# Hunk headers should include funcname context
366+
grep "^@@ .* @@ int func1()" actual
367+
'
368+
369+
test_expect_success '-L with --word-diff' '
370+
cat >expect <<-\EOF &&
371+
372+
diff --git a/file.c b/file.c
373+
--- a/file.c
374+
+++ b/file.c
375+
@@ -6,4 +6,4 @@ int func1()
376+
int func2()
377+
{
378+
return [-F2;-]{+F2 + 2;+}
379+
}
380+
381+
diff --git a/file.c b/file.c
382+
new file mode 100644
383+
--- /dev/null
384+
+++ b/file.c
385+
@@ -0,0 +6,4 @@
386+
{+int func2()+}
387+
{+{+}
388+
{+ return F2;+}
389+
{+}+}
390+
EOF
391+
git log -L:func2:file.c --word-diff --format= >actual &&
392+
grep -v "^index " actual >actual.filtered &&
393+
grep -v "^index " expect >expect.filtered &&
394+
test_cmp expect.filtered actual.filtered
395+
'
396+
397+
test_expect_success '-L with --no-prefix' '
398+
git log -L:func2:file.c --no-prefix --format= >actual &&
399+
grep "^diff --git file.c file.c" actual &&
400+
grep "^--- file.c" actual &&
401+
! grep "^--- a/" actual
402+
'
403+
404+
test_expect_success '-L with --full-index' '
405+
git log -L:func2:file.c --full-index --format= >actual &&
406+
grep "^index $head_blob_old_full\.\.$head_blob_new_full 100644" actual &&
407+
grep "^index $null_blob_full\.\.$root_blob_full$" actual
408+
'
409+
410+
test_expect_success 'setup -L with whitespace change' '
411+
git checkout -b ws-change parent-oids &&
412+
sed "s/ return F2 + 2;/ return F2 + 2;/" file.c >tmp &&
413+
mv tmp file.c &&
414+
git commit -a -m "Whitespace change in func2()"
415+
'
416+
417+
test_expect_success '-L with --ignore-all-space suppresses whitespace-only diff' '
418+
git log -L:func2:file.c --format= >without_w &&
419+
git log -L:func2:file.c --format= -w >with_w &&
420+
421+
# Without -w: three commits produce diffs (whitespace, modify, root)
422+
test $(grep -c "^diff --git" without_w) = 3 &&
423+
424+
# With -w: whitespace-only commit produces no hunk, so only two diffs
425+
test $(grep -c "^diff --git" with_w) = 2
426+
'
427+
342428
test_expect_success 'show line-log with graph' '
343429
git checkout parent-oids &&
344430
head_blob_old=$(git rev-parse --short HEAD^:file.c) &&
@@ -375,4 +461,199 @@ test_expect_success 'show line-log with graph' '
375461
test_cmp expect actual
376462
'
377463

464+
test_expect_success '-L with --word-diff-regex' '
465+
git checkout parent-oids &&
466+
git log -L:func2:file.c --word-diff \
467+
--word-diff-regex="[a-zA-Z0-9_]+" --format= >actual &&
468+
# Word-diff markers must be present
469+
grep "{+" actual &&
470+
grep "+}" actual &&
471+
# No line-level +/- markers (word-diff replaces them);
472+
# exclude --- header lines from the check
473+
! grep "^+[^+]" actual &&
474+
! grep "^-[^-]" actual
475+
'
476+
477+
test_expect_success '-L with --src-prefix and --dst-prefix' '
478+
git checkout parent-oids &&
479+
git log -L:func2:file.c --src-prefix=old/ --dst-prefix=new/ \
480+
--format= >actual &&
481+
grep "^diff --git old/file.c new/file.c" actual &&
482+
grep "^--- old/file.c" actual &&
483+
grep "^+++ new/file.c" actual &&
484+
! grep "^--- a/" actual
485+
'
486+
487+
test_expect_success '-L with --abbrev' '
488+
git checkout parent-oids &&
489+
git log -L:func2:file.c --abbrev=4 --format= -1 >actual &&
490+
# 4-char abbreviated hashes on index line
491+
grep "^index [0-9a-f]\{4\}\.\.[0-9a-f]\{4\}" actual
492+
'
493+
494+
test_expect_success '-L with -b suppresses whitespace-only diff' '
495+
git checkout ws-change &&
496+
git log -L:func2:file.c --format= >without_b &&
497+
git log -L:func2:file.c --format= -b >with_b &&
498+
test $(grep -c "^diff --git" without_b) = 3 &&
499+
test $(grep -c "^diff --git" with_b) = 2
500+
'
501+
502+
test_expect_success '-L with --output-indicator-*' '
503+
git checkout parent-oids &&
504+
git log -L:func2:file.c --output-indicator-new=">" \
505+
--output-indicator-old="<" --output-indicator-context="|" \
506+
--format= -1 >actual &&
507+
grep "^>" actual &&
508+
grep "^<" actual &&
509+
grep "^|" actual &&
510+
# No standard +/-/space content markers; exclude ---/+++ headers
511+
! grep "^+[^+]" actual &&
512+
! grep "^-[^-]" actual &&
513+
! grep "^ " actual
514+
'
515+
516+
test_expect_success '-L with -R reverses diff' '
517+
git checkout parent-oids &&
518+
git log -L:func2:file.c -R --format= -1 >actual &&
519+
grep "^diff --git b/file.c a/file.c" actual &&
520+
grep "^--- b/file.c" actual &&
521+
grep "^+++ a/file.c" actual &&
522+
# The modification added "F2 + 2", so reversed it is removed
523+
grep "^-.*F2 + 2" actual &&
524+
grep "^+.*return F2;" actual
525+
'
526+
527+
test_expect_success 'setup for color-moved test' '
528+
git checkout -b color-moved-test parent-oids &&
529+
cat >big.c <<-\EOF &&
530+
int bigfunc()
531+
{
532+
int a = 1;
533+
int b = 2;
534+
int c = 3;
535+
return a + b + c;
536+
}
537+
EOF
538+
git add big.c &&
539+
git commit -m "add bigfunc" &&
540+
sed "s/ / /" big.c >tmp && mv tmp big.c &&
541+
git commit -a -m "reindent bigfunc"
542+
'
543+
544+
test_expect_success '-L with --color-moved' '
545+
git log -L:bigfunc:big.c --color-moved=zebra \
546+
--color-moved-ws=ignore-all-space \
547+
--color=always --format= -1 >actual.raw &&
548+
test_decode_color <actual.raw >actual &&
549+
# Old moved lines: bold magenta; new moved lines: bold cyan
550+
grep "BOLD;MAGENTA" actual &&
551+
grep "BOLD;CYAN" actual
552+
'
553+
554+
test_expect_success 'setup for no-newline-at-eof tests' '
555+
git checkout --orphan no-newline &&
556+
git reset --hard &&
557+
printf "int top()\n{\n return 1;\n}\n\nint bot()\n{\n return 2;\n}" >noeol.c &&
558+
git add noeol.c &&
559+
test_tick &&
560+
git commit -m "add noeol.c (no trailing newline)" &&
561+
sed "s/return 2/return 22/" noeol.c >tmp && mv tmp noeol.c &&
562+
git commit -a -m "modify bot()" &&
563+
printf "int top()\n{\n return 1;\n}\n\nint bot()\n{\n return 33;\n}\n" >noeol.c &&
564+
git commit -a -m "modify bot() and add trailing newline"
565+
'
566+
567+
# When the tracked function is at the end of a file with no trailing
568+
# newline, the "\ No newline at end of file" marker should appear.
569+
test_expect_success '-L no-newline-at-eof appears in tracked range' '
570+
git log -L:bot:noeol.c --format= -1 HEAD~1 >actual &&
571+
grep "No newline at end of file" actual
572+
'
573+
574+
# When tracking a function that ends before the no-newline content,
575+
# the marker should not appear in the output.
576+
test_expect_success '-L no-newline-at-eof suppressed outside range' '
577+
git log -L:top:noeol.c --format= >actual &&
578+
! grep "No newline at end of file" actual
579+
'
580+
581+
# When a commit removes a no-newline last line and replaces it with
582+
# a newline-terminated line, the marker should still appear (on the
583+
# old side of the diff).
584+
test_expect_success '-L no-newline-at-eof marker with deleted line' '
585+
git log -L:bot:noeol.c --format= -1 >actual &&
586+
grep "No newline at end of file" actual
587+
'
588+
589+
test_expect_success 'setup for range boundary deletion test' '
590+
git checkout --orphan range-boundary &&
591+
git reset --hard &&
592+
cat >boundary.c <<-\EOF &&
593+
void above()
594+
{
595+
return;
596+
}
597+
598+
void tracked()
599+
{
600+
int x = 1;
601+
int y = 2;
602+
}
603+
604+
void below()
605+
{
606+
return;
607+
}
608+
EOF
609+
git add boundary.c &&
610+
test_tick &&
611+
git commit -m "add boundary.c" &&
612+
cat >boundary.c <<-\EOF &&
613+
void above()
614+
{
615+
return;
616+
}
617+
618+
void tracked()
619+
{
620+
int x = 1;
621+
int y = 2;
622+
}
623+
624+
void below_renamed()
625+
{
626+
return 0;
627+
}
628+
EOF
629+
git commit -a -m "modify below() only"
630+
'
631+
632+
# When only a function below the tracked range is modified, the
633+
# tracked function should not produce a diff.
634+
test_expect_success '-L suppresses deletions outside tracked range' '
635+
git log -L:tracked:boundary.c --format= >actual &&
636+
test $(grep -c "^diff --git" actual) = 1
637+
'
638+
639+
test_expect_success '-L with -S filters to string-count changes' '
640+
git checkout parent-oids &&
641+
git log -L:func2:file.c -S "F2 + 2" --format= >actual &&
642+
# -S searches the whole file, not just the tracked range;
643+
# combined with the -L range walk, this selects commits that
644+
# both touch func2 and change the count of "F2 + 2" in the file.
645+
test $(grep -c "^diff --git" actual) = 1 &&
646+
grep "F2 + 2" actual
647+
'
648+
649+
test_expect_success '-L with -G filters to diff-text matches' '
650+
git checkout parent-oids &&
651+
git log -L:func2:file.c -G "F2 [+] 2" --format= >actual &&
652+
# -G greps the whole-file diff text, not just the tracked range;
653+
# combined with -L, this selects commits that both touch func2
654+
# and have "F2 + 2" in their diff.
655+
test $(grep -c "^diff --git" actual) = 1 &&
656+
grep "F2 + 2" actual
657+
'
658+
378659
test_done

0 commit comments

Comments
 (0)