1#!/bin/sh 2# 3# Copyright (c) 2006 Junio C Hamano 4# 5 6test_description='Various diff formatting options' 7 8GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master 9export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 10 11. ./test-lib.sh 12. "$TEST_DIRECTORY"/lib-diff.sh 13 14test_expect_success setup ' 15 16 GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" && 17 GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" && 18 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 19 20 mkdir dir && 21 mkdir dir2 && 22 for i in 1 2 3; do echo $i; done >file0 && 23 for i in A B; do echo $i; done >dir/sub && 24 cat file0 >file2 && 25 git add file0 file2 dir/sub && 26 git commit -m Initial && 27 28 git branch initial && 29 git branch side && 30 31 GIT_AUTHOR_DATE="2006-06-26 00:01:00 +0000" && 32 GIT_COMMITTER_DATE="2006-06-26 00:01:00 +0000" && 33 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 34 35 for i in 4 5 6; do echo $i; done >>file0 && 36 for i in C D; do echo $i; done >>dir/sub && 37 rm -f file2 && 38 git update-index --remove file0 file2 dir/sub && 39 git commit -m "Second${LF}${LF}This is the second commit." && 40 41 GIT_AUTHOR_DATE="2006-06-26 00:02:00 +0000" && 42 GIT_COMMITTER_DATE="2006-06-26 00:02:00 +0000" && 43 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 44 45 for i in A B C; do echo $i; done >file1 && 46 git add file1 && 47 for i in E F; do echo $i; done >>dir/sub && 48 git update-index dir/sub && 49 git commit -m Third && 50 51 GIT_AUTHOR_DATE="2006-06-26 00:03:00 +0000" && 52 GIT_COMMITTER_DATE="2006-06-26 00:03:00 +0000" && 53 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 54 55 git checkout side && 56 for i in A B C; do echo $i; done >>file0 && 57 for i in 1 2; do echo $i; done >>dir/sub && 58 cat dir/sub >file3 && 59 git add file3 && 60 git update-index file0 dir/sub && 61 git commit -m Side && 62 63 GIT_AUTHOR_DATE="2006-06-26 00:04:00 +0000" && 64 GIT_COMMITTER_DATE="2006-06-26 00:04:00 +0000" && 65 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 66 67 git checkout master && 68 git pull -s ours --no-rebase . side && 69 70 GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" && 71 GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" && 72 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 73 74 for i in A B C; do echo $i; done >>file0 && 75 for i in 1 2; do echo $i; done >>dir/sub && 76 git update-index file0 dir/sub && 77 78 mkdir dir3 && 79 cp dir/sub dir3/sub && 80 test-tool chmtime +1 dir3/sub && 81 82 git config log.showroot false && 83 git commit --amend && 84 85 GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" && 86 GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" && 87 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 88 git checkout -b rearrange initial && 89 for i in B A; do echo $i; done >dir/sub && 90 git add dir/sub && 91 git commit -m "Rearranged lines in dir/sub" && 92 git checkout master && 93 94 GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" && 95 GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" && 96 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 97 git checkout -b mode initial && 98 git update-index --chmod=+x file0 && 99 git commit -m "update mode" && 100 git checkout -f master && 101 102 GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" && 103 GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" && 104 export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && 105 git checkout -b note initial && 106 git update-index --chmod=+x file2 && 107 git commit -m "update mode (file2)" && 108 git notes add -m "note" && 109 git checkout -f master && 110 111 # Same merge as master, but with parents reversed. Hide it in a 112 # pseudo-ref to avoid impacting tests with --all. 113 commit=$(echo reverse | 114 git commit-tree -p master^2 -p master^1 master^{tree}) && 115 git update-ref REVERSE $commit && 116 117 git config diff.renames false && 118 119 git show-branch 120' 121 122: <<\EOF 123! [initial] Initial 124 * [master] Merge branch 'side' 125 ! [rearrange] Rearranged lines in dir/sub 126 ! [side] Side 127---- 128 + [rearrange] Rearranged lines in dir/sub 129 - [master] Merge branch 'side' 130 * + [side] Side 131 * [master^] Third 132 * [master~2] Second 133+*++ [initial] Initial 134EOF 135 136process_diffs () { 137 perl -e ' 138 my $oid_length = length($ARGV[0]); 139 my $x40 = "[0-9a-f]{40}"; 140 my $xab = "[0-9a-f]{4,16}"; 141 my $orx = "[0-9a-f]" x $oid_length; 142 143 sub munge_oid { 144 my ($oid) = @_; 145 my $x; 146 147 return "" unless length $oid; 148 149 if ($oid =~ /^(100644|100755|120000)$/) { 150 return $oid; 151 } 152 153 if ($oid =~ /^0*$/) { 154 $x = "0"; 155 } else { 156 $x = "f"; 157 } 158 159 if (length($oid) == 40) { 160 return $x x $oid_length; 161 } else { 162 return $x x length($oid); 163 } 164 } 165 166 while (<STDIN>) { 167 s/($orx)/munge_oid($1)/ge; 168 s/From ($x40)( |\))/"From " . munge_oid($1) . $2/ge; 169 s/commit ($x40)($| \(from )($x40?)/"commit " . munge_oid($1) . $2 . munge_oid($3)/ge; 170 s/\b($x40)( |\.\.|$)/munge_oid($1) . $2/ge; 171 s/^($x40)($| )/munge_oid($1) . $2/e; 172 s/($xab)(\.\.|,| |\.\.\.|$)/munge_oid($1) . $2/ge; 173 print; 174 } 175 ' "$ZERO_OID" <"$1" 176} 177 178V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g') 179while read magic cmd 180do 181 status=success 182 case "$magic" in 183 '' | '#'*) 184 continue ;; 185 :*) 186 magic=${magic#:} 187 label="$magic-$cmd" 188 case "$magic" in 189 noellipses) ;; 190 failure) 191 status=failure 192 magic= 193 label="$cmd" ;; 194 *) 195 BUG "unknown magic $magic" ;; 196 esac ;; 197 *) 198 cmd="$magic $cmd" magic= 199 label="$cmd" ;; 200 esac 201 test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g') 202 pfx=$(printf "%04d" $test_count) 203 expect="$TEST_DIRECTORY/t4013/diff.$test" 204 actual="$pfx-diff.$test" 205 206 test_expect_$status "git $cmd # magic is ${magic:-(not used)}" ' 207 { 208 echo "$ git $cmd" 209 case "$magic" in 210 "") 211 GIT_PRINT_SHA1_ELLIPSIS=yes git $cmd ;; 212 noellipses) 213 git $cmd ;; 214 esac | 215 sed -e "s/^\\(-*\\)$V\\(-*\\)\$/\\1g-i-t--v-e-r-s-i-o-n\2/" \ 216 -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/" 217 echo "\$" 218 } >"$actual" && 219 if test -f "$expect" 220 then 221 process_diffs "$actual" >actual && 222 process_diffs "$expect" >expect && 223 case $cmd in 224 *format-patch* | *-stat*) 225 test_cmp expect actual;; 226 *) 227 test_cmp expect actual;; 228 esac && 229 rm -f "$actual" actual expect 230 else 231 # this is to help developing new tests. 232 cp "$actual" "$expect" 233 false 234 fi 235 ' 236done <<\EOF 237diff-tree initial 238diff-tree -r initial 239diff-tree -r --abbrev initial 240diff-tree -r --abbrev=4 initial 241diff-tree --root initial 242diff-tree --root --abbrev initial 243:noellipses diff-tree --root --abbrev initial 244diff-tree --root -r initial 245diff-tree --root -r --abbrev initial 246:noellipses diff-tree --root -r --abbrev initial 247diff-tree --root -r --abbrev=4 initial 248:noellipses diff-tree --root -r --abbrev=4 initial 249diff-tree -p initial 250diff-tree --root -p initial 251diff-tree --root -p --abbrev=10 initial 252diff-tree --root -p --full-index initial 253diff-tree --root -p --full-index --abbrev=10 initial 254diff-tree --patch-with-stat initial 255diff-tree --root --patch-with-stat initial 256diff-tree --patch-with-raw initial 257diff-tree --root --patch-with-raw initial 258 259diff-tree --pretty initial 260diff-tree --pretty --root initial 261diff-tree --pretty -p initial 262diff-tree --pretty --stat initial 263diff-tree --pretty --summary initial 264diff-tree --pretty --stat --summary initial 265diff-tree --pretty --root -p initial 266diff-tree --pretty --root --stat initial 267# improved by Timo's patch 268diff-tree --pretty --root --summary initial 269# improved by Timo's patch 270diff-tree --pretty --root --summary -r initial 271diff-tree --pretty --root --stat --summary initial 272diff-tree --pretty --patch-with-stat initial 273diff-tree --pretty --root --patch-with-stat initial 274diff-tree --pretty --patch-with-raw initial 275diff-tree --pretty --root --patch-with-raw initial 276 277diff-tree --pretty=oneline initial 278diff-tree --pretty=oneline --root initial 279diff-tree --pretty=oneline -p initial 280diff-tree --pretty=oneline --root -p initial 281diff-tree --pretty=oneline --patch-with-stat initial 282# improved by Timo's patch 283diff-tree --pretty=oneline --root --patch-with-stat initial 284diff-tree --pretty=oneline --patch-with-raw initial 285diff-tree --pretty=oneline --root --patch-with-raw initial 286 287diff-tree --pretty side 288diff-tree --pretty -p side 289diff-tree --pretty --patch-with-stat side 290 291diff-tree initial mode 292diff-tree --stat initial mode 293diff-tree --summary initial mode 294 295diff-tree master 296diff-tree -m master 297diff-tree -p master 298diff-tree -p -m master 299diff-tree -c master 300diff-tree -c --abbrev master 301:noellipses diff-tree -c --abbrev master 302diff-tree --cc master 303# stat only should show the diffstat with the first parent 304diff-tree -c --stat master 305diff-tree --cc --stat master 306diff-tree -c --stat --summary master 307diff-tree --cc --stat --summary master 308# stat summary should show the diffstat and summary with the first parent 309diff-tree -c --stat --summary side 310diff-tree --cc --stat --summary side 311diff-tree --cc --shortstat master 312diff-tree --cc --summary REVERSE 313# improved by Timo's patch 314diff-tree --cc --patch-with-stat master 315# improved by Timo's patch 316diff-tree --cc --patch-with-stat --summary master 317# this is correct 318diff-tree --cc --patch-with-stat --summary side 319 320log master 321log -p master 322log --root master 323log --root -p master 324log --patch-with-stat master 325log --root --patch-with-stat master 326log --root --patch-with-stat --summary master 327# improved by Timo's patch 328log --root -c --patch-with-stat --summary master 329# improved by Timo's patch 330log --root --cc --patch-with-stat --summary master 331log --no-diff-merges -p --first-parent master 332log --diff-merges=off -p --first-parent master 333log --first-parent --diff-merges=off -p master 334log -p --first-parent master 335log -p --diff-merges=first-parent master 336log --diff-merges=first-parent master 337log -m -p --first-parent master 338log -m -p master 339log --cc -m -p master 340log -c -m -p master 341log -m --raw master 342log -m --stat master 343log -SF master 344log -S F master 345log -SF -p master 346log -SF master --max-count=0 347log -SF master --max-count=1 348log -SF master --max-count=2 349log -GF master 350log -GF -p master 351log -GF -p --pickaxe-all master 352log -IA -IB -I1 -I2 -p master 353log --decorate --all 354log --decorate=full --all 355 356rev-list --parents HEAD 357rev-list --children HEAD 358 359whatchanged master 360:noellipses whatchanged master 361whatchanged -p master 362whatchanged --root master 363:noellipses whatchanged --root master 364whatchanged --root -p master 365whatchanged --patch-with-stat master 366whatchanged --root --patch-with-stat master 367whatchanged --root --patch-with-stat --summary master 368# improved by Timo's patch 369whatchanged --root -c --patch-with-stat --summary master 370# improved by Timo's patch 371whatchanged --root --cc --patch-with-stat --summary master 372whatchanged -SF master 373:noellipses whatchanged -SF master 374whatchanged -SF -p master 375 376log --patch-with-stat master -- dir/ 377whatchanged --patch-with-stat master -- dir/ 378log --patch-with-stat --summary master -- dir/ 379whatchanged --patch-with-stat --summary master -- dir/ 380 381show initial 382show --root initial 383show side 384show master 385show -c master 386show -m master 387show --first-parent master 388show --stat side 389show --stat --summary side 390show --patch-with-stat side 391show --patch-with-raw side 392:noellipses show --patch-with-raw side 393show --patch-with-stat --summary side 394 395format-patch --stdout initial..side 396format-patch --stdout initial..master^ 397format-patch --stdout initial..master 398format-patch --stdout --no-numbered initial..master 399format-patch --stdout --numbered initial..master 400format-patch --attach --stdout initial..side 401format-patch --attach --stdout --suffix=.diff initial..side 402format-patch --attach --stdout initial..master^ 403format-patch --attach --stdout initial..master 404format-patch --inline --stdout initial..side 405format-patch --inline --stdout initial..master^ 406format-patch --inline --stdout --numbered-files initial..master 407format-patch --inline --stdout initial..master 408format-patch --inline --stdout --subject-prefix=TESTCASE initial..master 409config format.subjectprefix DIFFERENT_PREFIX 410format-patch --inline --stdout initial..master^^ 411format-patch --stdout --cover-letter -n initial..master^ 412 413diff --abbrev initial..side 414diff -U initial..side 415diff -U1 initial..side 416diff -r initial..side 417diff --stat initial..side 418diff -r --stat initial..side 419diff initial..side 420diff --patch-with-stat initial..side 421diff --patch-with-raw initial..side 422:noellipses diff --patch-with-raw initial..side 423diff --patch-with-stat -r initial..side 424diff --patch-with-raw -r initial..side 425:noellipses diff --patch-with-raw -r initial..side 426diff --name-status dir2 dir 427diff --no-index --name-status dir2 dir 428diff --no-index --name-status -- dir2 dir 429diff --no-index dir dir3 430diff master master^ side 431# Can't use spaces... 432diff --line-prefix=abc master master^ side 433diff --dirstat master~1 master~2 434diff --dirstat initial rearrange 435diff --dirstat-by-file initial rearrange 436diff --dirstat --cc master~1 master 437# No-index --abbrev and --no-abbrev 438diff --raw initial 439:noellipses diff --raw initial 440diff --raw --abbrev=4 initial 441:noellipses diff --raw --abbrev=4 initial 442diff --raw --no-abbrev initial 443diff --no-index --raw dir2 dir 444:noellipses diff --no-index --raw dir2 dir 445diff --no-index --raw --abbrev=4 dir2 dir 446:noellipses diff --no-index --raw --abbrev=4 dir2 dir 447diff --no-index --raw --no-abbrev dir2 dir 448 449diff-tree --pretty --root --stat --compact-summary initial 450diff-tree --pretty -R --root --stat --compact-summary initial 451diff-tree --pretty note 452diff-tree --pretty --notes note 453diff-tree --format=%N note 454diff-tree --stat --compact-summary initial mode 455diff-tree -R --stat --compact-summary initial mode 456EOF 457 458test_expect_success 'log -m matches pure log' ' 459 git log master >result && 460 process_diffs result >expected && 461 git log -m >result && 462 process_diffs result >actual && 463 test_cmp expected actual 464' 465 466test_expect_success 'log --diff-merges=on matches --diff-merges=separate' ' 467 git log -p --diff-merges=separate master >result && 468 process_diffs result >expected && 469 git log -p --diff-merges=on master >result && 470 process_diffs result >actual && 471 test_cmp expected actual 472' 473 474test_expect_success 'deny wrong log.diffMerges config' ' 475 test_config log.diffMerges wrong-value && 476 test_expect_code 128 git log 477' 478 479test_expect_success 'git config log.diffMerges first-parent' ' 480 git log -p --diff-merges=first-parent master >result && 481 process_diffs result >expected && 482 test_config log.diffMerges first-parent && 483 git log -p --diff-merges=on master >result && 484 process_diffs result >actual && 485 test_cmp expected actual 486' 487 488test_expect_success 'git config log.diffMerges first-parent vs -m' ' 489 git log -p --diff-merges=first-parent master >result && 490 process_diffs result >expected && 491 test_config log.diffMerges first-parent && 492 git log -p -m master >result && 493 process_diffs result >actual && 494 test_cmp expected actual 495' 496 497# -m in "git diff-index" means "match missing", that differs 498# from its meaning in "git diff". Let's check it in diff-index. 499# The line in the output for removed file should disappear when 500# we provide -m in diff-index. 501test_expect_success 'git diff-index -m' ' 502 rm -f file1 && 503 git diff-index HEAD >without-m && 504 lines_count=$(wc -l <without-m) && 505 git diff-index -m HEAD >with-m && 506 git restore file1 && 507 test_line_count = $((lines_count - 1)) with-m 508' 509 510test_expect_success 'log -S requires an argument' ' 511 test_must_fail git log -S 512' 513 514test_expect_success 'diff --cached on unborn branch' ' 515 echo ref: refs/heads/unborn >.git/HEAD && 516 git diff --cached >result && 517 process_diffs result >actual && 518 process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached" >expected && 519 test_cmp expected actual 520' 521 522test_expect_success 'diff --cached -- file on unborn branch' ' 523 git diff --cached -- file0 >result && 524 process_diffs result >actual && 525 process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" >expected && 526 test_cmp expected actual 527' 528test_expect_success 'diff --line-prefix with spaces' ' 529 git diff --line-prefix="| | | " --cached -- file0 >result && 530 process_diffs result >actual && 531 process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--line-prefix_--cached_--_file0" >expected && 532 test_cmp expected actual 533' 534 535test_expect_success 'diff-tree --stdin with log formatting' ' 536 cat >expect <<-\EOF && 537 Side 538 Third 539 Second 540 EOF 541 git rev-list master | git diff-tree --stdin --format=%s -s >actual && 542 test_cmp expect actual 543' 544 545test_expect_success 'diff -I<regex>: setup' ' 546 git checkout master && 547 test_seq 50 >file0 && 548 git commit -m "Set up -I<regex> test file" file0 && 549 test_seq 50 | sed -e "s/13/ten and three/" -e "/7\$/d" >file0 && 550 echo >>file0 551' 552test_expect_success 'diff -I<regex>' ' 553 git diff --ignore-blank-lines -I"ten.*e" -I"^[124-9]" >actual && 554 cat >expect <<-\EOF && 555 diff --git a/file0 b/file0 556 --- a/file0 557 +++ b/file0 558 @@ -34,7 +31,6 @@ 559 34 560 35 561 36 562 -37 563 38 564 39 565 40 566 EOF 567 compare_diff_patch expect actual 568' 569 570test_expect_success 'diff -I<regex> --stat' ' 571 git diff --stat --ignore-blank-lines -I"ten.*e" -I"^[124-9]" >actual && 572 cat >expect <<-\EOF && 573 file0 | 1 - 574 1 file changed, 1 deletion(-) 575 EOF 576 test_cmp expect actual 577' 578 579test_expect_success 'diff -I<regex>: detect malformed regex' ' 580 test_expect_code 129 git diff --ignore-matching-lines="^[124-9" 2>error && 581 test_i18ngrep "invalid regex given to -I: " error 582' 583 584test_done 585