3 test_description
='range-diff tests'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 # Note that because of the range-diff's heuristics, test_commit does more
11 # harm than good. We need some real history.
13 test_expect_success
'setup' '
14 git fast-import <"$TEST_DIRECTORY"/t3206/history.export &&
15 test_oid_cache <<-\EOF
126 # Empty delimiter (included so lines match neatly)
132 test_expect_success
'simple A..B A..C (unmodified)' '
133 git range-diff --no-color main..topic main..unmodified \
135 cat >expect <<-EOF &&
136 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
137 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
138 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
139 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/
141 test_cmp expect actual
144 test_expect_success
'simple B...C (unmodified)' '
145 git range-diff --no-color topic...unmodified >actual &&
146 # same "expect" as above
147 test_cmp expect actual
150 test_expect_success
'simple A B C (unmodified)' '
151 git range-diff --no-color main topic unmodified >actual &&
152 # same "expect" as above
153 test_cmp expect actual
156 test_expect_success
'A^! and A^-<n> (unmodified)' '
157 git range-diff --no-color topic^! unmodified^-1 >actual &&
158 cat >expect <<-EOF &&
159 1: $(test_oid t4) = 1: $(test_oid u4) s/12/B/
161 test_cmp expect actual
164 test_expect_success
'A^{/..} is not mistaken for a range' '
165 test_must_fail git range-diff topic^.. topic^{/..} 2>error &&
166 test_i18ngrep "not a commit range" error
169 test_expect_success
'trivial reordering' '
170 git range-diff --no-color main topic reordered >actual &&
171 cat >expect <<-EOF &&
172 1: $(test_oid t1) = 1: $(test_oid r1) s/5/A/
173 3: $(test_oid t3) = 2: $(test_oid r2) s/11/B/
174 4: $(test_oid t4) = 3: $(test_oid r3) s/12/B/
175 2: $(test_oid t2) = 4: $(test_oid r4) s/4/A/
177 test_cmp expect actual
180 test_expect_success
'removed a commit' '
181 git range-diff --no-color main topic removed >actual &&
182 cat >expect <<-EOF &&
183 1: $(test_oid t1) = 1: $(test_oid d1) s/5/A/
184 2: $(test_oid t2) < -: $(test_oid __) s/4/A/
185 3: $(test_oid t3) = 2: $(test_oid d2) s/11/B/
186 4: $(test_oid t4) = 3: $(test_oid d3) s/12/B/
188 test_cmp expect actual
191 test_expect_success
'added a commit' '
192 git range-diff --no-color main topic added >actual &&
193 cat >expect <<-EOF &&
194 1: $(test_oid t1) = 1: $(test_oid a1) s/5/A/
195 2: $(test_oid t2) = 2: $(test_oid a2) s/4/A/
196 -: $(test_oid __) > 3: $(test_oid a3) s/6/A/
197 3: $(test_oid t3) = 4: $(test_oid a4) s/11/B/
198 4: $(test_oid t4) = 5: $(test_oid a5) s/12/B/
200 test_cmp expect actual
203 test_expect_success
'new base, A B C' '
204 git range-diff --no-color main topic rebased >actual &&
205 cat >expect <<-EOF &&
206 1: $(test_oid t1) = 1: $(test_oid b1) s/5/A/
207 2: $(test_oid t2) = 2: $(test_oid b2) s/4/A/
208 3: $(test_oid t3) = 3: $(test_oid b3) s/11/B/
209 4: $(test_oid t4) = 4: $(test_oid b4) s/12/B/
211 test_cmp expect actual
214 test_expect_success
'new base, B...C' '
215 # this syntax includes the commits from main!
216 git range-diff --no-color topic...rebased >actual &&
217 cat >expect <<-EOF &&
218 -: $(test_oid __) > 1: $(test_oid b5) unrelated
219 1: $(test_oid t1) = 2: $(test_oid b1) s/5/A/
220 2: $(test_oid t2) = 3: $(test_oid b2) s/4/A/
221 3: $(test_oid t3) = 4: $(test_oid b3) s/11/B/
222 4: $(test_oid t4) = 5: $(test_oid b4) s/12/B/
224 test_cmp expect actual
227 test_expect_success
'changed commit' '
228 git range-diff --no-color topic...changed >actual &&
229 cat >expect <<-EOF &&
230 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
231 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
232 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
242 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
253 test_cmp expect actual
256 test_expect_success
'changed commit with --no-patch diff option' '
257 git range-diff --no-color --no-patch topic...changed >actual &&
258 cat >expect <<-EOF &&
259 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
260 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
261 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
262 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
264 test_cmp expect actual
267 test_expect_success
'changed commit with --stat diff option' '
268 git range-diff --no-color --stat topic...changed >actual &&
269 cat >expect <<-EOF &&
270 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
271 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
272 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
274 1 file changed, 1 insertion(+), 1 deletion(-)
275 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
277 1 file changed, 1 insertion(+), 1 deletion(-)
279 test_cmp expect actual
282 test_expect_success
'changed commit with sm config' '
283 git range-diff --no-color --submodule=log topic...changed >actual &&
284 cat >expect <<-EOF &&
285 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/
286 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/
287 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/
297 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/
308 test_cmp expect actual
311 test_expect_success
'renamed file' '
312 git range-diff --no-color --submodule=log topic...renamed-file >actual &&
313 sed s/Z/\ /g >expect <<-EOF &&
314 1: $(test_oid t1) = 1: $(test_oid n1) s/5/A/
315 2: $(test_oid t2) ! 2: $(test_oid n2) s/4/A/
317 ZAuthor: Thomas Rast <trast@inf.ethz.ch>
319 Z ## Commit message ##
321 + s/4/A/ + rename file
324 + ## file => renamed-file ##
328 3: $(test_oid t3) ! 3: $(test_oid n3) s/11/B/
330 Z ## Commit message ##
340 4: $(test_oid t4) ! 4: $(test_oid n4) s/12/B/
342 Z ## Commit message ##
353 test_cmp expect actual
356 test_expect_success
'file with mode only change' '
357 git range-diff --no-color --submodule=log topic...mode-only-change >actual &&
358 sed s/Z/\ /g >expect <<-EOF &&
359 1: $(test_oid t2) ! 1: $(test_oid o1) s/4/A/
361 ZAuthor: Thomas Rast <trast@inf.ethz.ch>
363 Z ## Commit message ##
365 + s/4/A/ + add other-file
374 + ## other-file (new) ##
375 2: $(test_oid t3) ! 2: $(test_oid o2) s/11/B/
377 ZAuthor: Thomas Rast <trast@inf.ethz.ch>
379 Z ## Commit message ##
381 + s/11/B/ + mode change other-file
390 + ## other-file (mode change 100644 => 100755) ##
391 3: $(test_oid t4) = 3: $(test_oid o3) s/12/B/
393 test_cmp expect actual
396 test_expect_success
'file added and later removed' '
397 git range-diff --no-color --submodule=log topic...added-removed >actual &&
398 sed s/Z/\ /g >expect <<-EOF &&
399 1: $(test_oid t1) = 1: $(test_oid s1) s/5/A/
400 2: $(test_oid t2) ! 2: $(test_oid s2) s/4/A/
402 ZAuthor: Thomas Rast <trast@inf.ethz.ch>
404 Z ## Commit message ##
415 + ## new-file (new) ##
416 3: $(test_oid t3) ! 3: $(test_oid s3) s/11/B/
418 ZAuthor: Thomas Rast <trast@inf.ethz.ch>
420 Z ## Commit message ##
422 + s/11/B/ + remove file
431 + ## new-file (deleted) ##
432 4: $(test_oid t4) = 4: $(test_oid s4) s/12/B/
434 test_cmp expect actual
437 test_expect_success
'no commits on one side' '
438 git commit --amend -m "new message" &&
439 git range-diff main HEAD@{1} HEAD
442 test_expect_success
'changed message' '
443 git range-diff --no-color topic...changed-message >actual &&
444 sed s/Z/\ /g >expect <<-EOF &&
445 1: $(test_oid t1) = 1: $(test_oid m1) s/5/A/
446 2: $(test_oid t2) ! 2: $(test_oid m2) s/4/A/
448 Z ## Commit message ##
451 + Also a silly comment here!
456 3: $(test_oid t3) = 3: $(test_oid m3) s/11/B/
457 4: $(test_oid t4) = 4: $(test_oid m4) s/12/B/
459 test_cmp expect actual
462 test_expect_success
'dual-coloring' '
463 sed -e "s|^:||" >expect <<-EOF &&
464 :<YELLOW>1: $(test_oid c1) = 1: $(test_oid m1) s/5/A/<RESET>
465 :<RED>2: $(test_oid c2) <RESET><YELLOW>!<RESET><GREEN> 2: $(test_oid m2)<RESET><YELLOW> s/4/A/<RESET>
466 : <REVERSE><CYAN>@@<RESET> <RESET>Metadata<RESET>
467 : ## Commit message ##<RESET>
470 : <REVERSE><GREEN>+<RESET><BOLD> Also a silly comment here!<RESET>
471 : <REVERSE><GREEN>+<RESET>
475 :<RED>3: $(test_oid c3) <RESET><YELLOW>!<RESET><GREEN> 3: $(test_oid m3)<RESET><YELLOW> s/11/B/<RESET>
476 : <REVERSE><CYAN>@@<RESET> <RESET>file: A<RESET>
480 : <REVERSE><RED>-<RESET><FAINT;GREEN>+BB<RESET>
481 : <REVERSE><GREEN>+<RESET><BOLD;GREEN>+B<RESET>
485 :<RED>4: $(test_oid c4) <RESET><YELLOW>!<RESET><GREEN> 4: $(test_oid m4)<RESET><YELLOW> s/12/B/<RESET>
486 : <REVERSE><CYAN>@@<RESET> <RESET>file<RESET>
487 : <CYAN> @@ file: A<RESET>
490 : <REVERSE><RED>-<RESET><FAINT> BB<RESET>
491 : <REVERSE><GREEN>+<RESET><BOLD> B<RESET>
496 git range-diff changed...changed-message --color --dual-color >actual.raw &&
497 test_decode_color >actual <actual.raw &&
498 test_cmp expect actual
501 for prev
in topic main..topic
503 test_expect_success
"format-patch --range-diff=$prev" '
504 git format-patch --cover-letter --range-diff=$prev \
505 main..unmodified >actual &&
506 test_when_finished "rm 000?-*" &&
507 test_line_count = 5 actual &&
508 test_i18ngrep "^Range-diff:$" 0000-* &&
509 grep "= 1: .* s/5/A" 0000-* &&
510 grep "= 2: .* s/4/A" 0000-* &&
511 grep "= 3: .* s/11/B" 0000-* &&
512 grep "= 4: .* s/12/B" 0000-*
516 test_expect_success
'format-patch --range-diff as commentary' '
517 git format-patch --range-diff=HEAD~1 HEAD~1 >actual &&
518 test_when_finished "rm 0001-*" &&
519 test_line_count = 1 actual &&
520 test_i18ngrep "^Range-diff:$" 0001-* &&
521 grep "> 1: .* new message" 0001-*
524 test_expect_success
'format-patch --range-diff reroll-count with a non-integer' '
525 git format-patch --range-diff=HEAD~1 -v2.9 HEAD~1 >actual &&
526 test_when_finished "rm v2.9-0001-*" &&
527 test_line_count = 1 actual &&
528 test_i18ngrep "^Range-diff:$" v2.9-0001-* &&
529 grep "> 1: .* new message" v2.9-0001-*
532 test_expect_success
'format-patch --range-diff reroll-count with a integer' '
533 git format-patch --range-diff=HEAD~1 -v2 HEAD~1 >actual &&
534 test_when_finished "rm v2-0001-*" &&
535 test_line_count = 1 actual &&
536 test_i18ngrep "^Range-diff ..* v1:$" v2-0001-* &&
537 grep "> 1: .* new message" v2-0001-*
540 test_expect_success
'format-patch --range-diff with v0' '
541 git format-patch --range-diff=HEAD~1 -v0 HEAD~1 >actual &&
542 test_when_finished "rm v0-0001-*" &&
543 test_line_count = 1 actual &&
544 test_i18ngrep "^Range-diff:$" v0-0001-* &&
545 grep "> 1: .* new message" v0-0001-*
548 test_expect_success
'range-diff overrides diff.noprefix internally' '
549 git -c diff.noprefix=true range-diff HEAD^...
552 test_expect_success
'basic with modified format.pretty with suffix' '
553 git -c format.pretty="format:commit %H%d%n" range-diff \
554 main..topic main..unmodified
557 test_expect_success
'basic with modified format.pretty without "commit "' '
558 git -c format.pretty="format:%H%n" range-diff \
559 main..topic main..unmodified
562 test_expect_success
'range-diff compares notes by default' '
563 git notes add -m "topic note" topic &&
564 git notes add -m "unmodified note" unmodified &&
565 test_when_finished git notes remove topic unmodified &&
566 git range-diff --no-color main..topic main..unmodified \
568 sed s/Z/\ /g >expect <<-EOF &&
569 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
570 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
571 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
572 4: $(test_oid t4) ! 4: $(test_oid u4) s/12/B/
583 test_cmp expect actual
586 test_expect_success
'range-diff with --no-notes' '
587 git notes add -m "topic note" topic &&
588 git notes add -m "unmodified note" unmodified &&
589 test_when_finished git notes remove topic unmodified &&
590 git range-diff --no-color --no-notes main..topic main..unmodified \
592 cat >expect <<-EOF &&
593 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
594 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
595 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
596 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/
598 test_cmp expect actual
601 test_expect_success
'range-diff with multiple --notes' '
602 git notes --ref=note1 add -m "topic note1" topic &&
603 git notes --ref=note1 add -m "unmodified note1" unmodified &&
604 test_when_finished git notes --ref=note1 remove topic unmodified &&
605 git notes --ref=note2 add -m "topic note2" topic &&
606 git notes --ref=note2 add -m "unmodified note2" unmodified &&
607 test_when_finished git notes --ref=note2 remove topic unmodified &&
608 git range-diff --no-color --notes=note1 --notes=note2 main..topic main..unmodified \
610 sed s/Z/\ /g >expect <<-EOF &&
611 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/
612 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/
613 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/
614 4: $(test_oid t4) ! 4: $(test_oid u4) s/12/B/
618 Z ## Notes (note1) ##
623 Z ## Notes (note2) ##
630 test_cmp expect actual
633 test_expect_success
'format-patch --range-diff does not compare notes by default' '
634 git notes add -m "topic note" topic &&
635 git notes add -m "unmodified note" unmodified &&
636 test_when_finished git notes remove topic unmodified &&
637 git format-patch --cover-letter --range-diff=$prev \
638 main..unmodified >actual &&
639 test_when_finished "rm 000?-*" &&
640 test_line_count = 5 actual &&
641 test_i18ngrep "^Range-diff:$" 0000-* &&
642 grep "= 1: .* s/5/A" 0000-* &&
643 grep "= 2: .* s/4/A" 0000-* &&
644 grep "= 3: .* s/11/B" 0000-* &&
645 grep "= 4: .* s/12/B" 0000-* &&
646 ! grep "Notes" 0000-* &&
650 test_expect_success
'format-patch --range-diff with --no-notes' '
651 git notes add -m "topic note" topic &&
652 git notes add -m "unmodified note" unmodified &&
653 test_when_finished git notes remove topic unmodified &&
654 git format-patch --no-notes --cover-letter --range-diff=$prev \
655 main..unmodified >actual &&
656 test_when_finished "rm 000?-*" &&
657 test_line_count = 5 actual &&
658 test_i18ngrep "^Range-diff:$" 0000-* &&
659 grep "= 1: .* s/5/A" 0000-* &&
660 grep "= 2: .* s/4/A" 0000-* &&
661 grep "= 3: .* s/11/B" 0000-* &&
662 grep "= 4: .* s/12/B" 0000-* &&
663 ! grep "Notes" 0000-* &&
667 test_expect_success
'format-patch --range-diff with --notes' '
668 git notes add -m "topic note" topic &&
669 git notes add -m "unmodified note" unmodified &&
670 test_when_finished git notes remove topic unmodified &&
671 git format-patch --notes --cover-letter --range-diff=$prev \
672 main..unmodified >actual &&
673 test_when_finished "rm 000?-*" &&
674 test_line_count = 5 actual &&
675 test_i18ngrep "^Range-diff:$" 0000-* &&
676 grep "= 1: .* s/5/A" 0000-* &&
677 grep "= 2: .* s/4/A" 0000-* &&
678 grep "= 3: .* s/11/B" 0000-* &&
679 grep "! 4: .* s/12/B" 0000-* &&
680 sed s/Z/\ /g >expect <<-EOF &&
691 sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual &&
692 test_cmp expect actual
695 test_expect_success
'format-patch --range-diff with format.notes config' '
696 git notes add -m "topic note" topic &&
697 git notes add -m "unmodified note" unmodified &&
698 test_when_finished git notes remove topic unmodified &&
699 test_config format.notes true &&
700 git format-patch --cover-letter --range-diff=$prev \
701 main..unmodified >actual &&
702 test_when_finished "rm 000?-*" &&
703 test_line_count = 5 actual &&
704 test_i18ngrep "^Range-diff:$" 0000-* &&
705 grep "= 1: .* s/5/A" 0000-* &&
706 grep "= 2: .* s/4/A" 0000-* &&
707 grep "= 3: .* s/11/B" 0000-* &&
708 grep "! 4: .* s/12/B" 0000-* &&
709 sed s/Z/\ /g >expect <<-EOF &&
720 sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual &&
721 test_cmp expect actual
724 test_expect_success
'format-patch --range-diff with multiple notes' '
725 git notes --ref=note1 add -m "topic note1" topic &&
726 git notes --ref=note1 add -m "unmodified note1" unmodified &&
727 test_when_finished git notes --ref=note1 remove topic unmodified &&
728 git notes --ref=note2 add -m "topic note2" topic &&
729 git notes --ref=note2 add -m "unmodified note2" unmodified &&
730 test_when_finished git notes --ref=note2 remove topic unmodified &&
731 git format-patch --notes=note1 --notes=note2 --cover-letter --range-diff=$prev \
732 main..unmodified >actual &&
733 test_when_finished "rm 000?-*" &&
734 test_line_count = 5 actual &&
735 test_i18ngrep "^Range-diff:$" 0000-* &&
736 grep "= 1: .* s/5/A" 0000-* &&
737 grep "= 2: .* s/4/A" 0000-* &&
738 grep "= 3: .* s/11/B" 0000-* &&
739 grep "! 4: .* s/12/B" 0000-* &&
740 sed s/Z/\ /g >expect <<-EOF &&
744 Z ## Notes (note1) ##
749 Z ## Notes (note2) ##
756 sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual &&
757 test_cmp expect actual
760 test_expect_success
'--left-only/--right-only' '
761 git switch --orphan left-right &&
763 test_commit unmatched &&
764 test_commit common &&
765 git switch -C left-right first &&
766 git cherry-pick common &&
768 git range-diff -s --left-only ...common >actual &&
769 head_oid=$(git rev-parse --short HEAD) &&
770 common_oid=$(git rev-parse --short common) &&
771 echo "1: $head_oid = 2: $common_oid common" >expect &&
772 test_cmp expect actual