t / annotate-tests.shon commit Merge branch 'nd/corrupt-worktrees' into maint (933f294)
   1# This file isn't used as a test script directly, instead it is
   2# sourced from t8001-annotate.sh and t8002-blame.sh.
   3
   4if test_have_prereq MINGW
   5then
   6  sanitize_L () {
   7        echo "$1" | sed 'sX\(^-L\|,\)\^\?/X&\\;*Xg'
   8  }
   9else
  10  sanitize_L () {
  11        echo "$1"
  12  }
  13fi
  14
  15check_count () {
  16        head= &&
  17        file='file' &&
  18        options= &&
  19        while :
  20        do
  21                case "$1" in
  22                -h) head="$2"; shift; shift ;;
  23                -f) file="$2"; shift; shift ;;
  24                -L*) options="$options $(sanitize_L "$1")"; shift ;;
  25                -*) options="$options $1"; shift ;;
  26                *) break ;;
  27                esac
  28        done &&
  29        echo "$PROG $options $file $head" >&4 &&
  30        $PROG $options $file $head >actual &&
  31        perl -e '
  32                my %expect = (@ARGV);
  33                my %count = map { $_ => 0 } keys %expect;
  34                while (<STDIN>) {
  35                        if (/^[0-9a-f]+\t\(([^\t]+)\t/) {
  36                                my $author = $1;
  37                                for ($author) { s/^\s*//; s/\s*$//; }
  38                                $count{$author}++;
  39                        }
  40                }
  41                my $bad = 0;
  42                while (my ($author, $count) = each %count) {
  43                        my $ok;
  44                        my $value = 0;
  45                        $value = $expect{$author} if defined $expect{$author};
  46                        if ($value != $count) {
  47                                $bad = 1;
  48                                $ok = "bad";
  49                        }
  50                        else {
  51                                $ok = "good";
  52                        }
  53                        print STDERR "Author $author (expected $value, attributed $count) $ok\n";
  54                }
  55                exit($bad);
  56        ' "$@" <actual
  57}
  58
  59test_expect_success 'setup A lines' '
  60        echo "1A quick brown fox jumps over the" >file &&
  61        echo "lazy dog" >>file &&
  62        git add file &&
  63        GIT_AUTHOR_NAME="A" GIT_AUTHOR_EMAIL="A@test.git" \
  64        git commit -a -m "Initial."
  65'
  66
  67test_expect_success 'blame 1 author' '
  68        check_count A 2
  69'
  70
  71test_expect_success 'blame in a bare repo without starting commit' '
  72        git clone --bare . bare.git &&
  73        (
  74                cd bare.git &&
  75                check_count A 2
  76        )
  77'
  78
  79test_expect_success 'blame by tag objects' '
  80        git tag -m "test tag" testTag &&
  81        git tag -m "test tag #2" testTag2 testTag &&
  82        check_count -h testTag A 2 &&
  83        check_count -h testTag2 A 2
  84'
  85
  86test_expect_success 'setup B lines' '
  87        echo "2A quick brown fox jumps over the" >>file &&
  88        echo "lazy dog" >>file &&
  89        GIT_AUTHOR_NAME="B" GIT_AUTHOR_EMAIL="B@test.git" \
  90        git commit -a -m "Second."
  91'
  92
  93test_expect_success 'blame 2 authors' '
  94        check_count A 2 B 2
  95'
  96
  97test_expect_success 'setup B1 lines (branch1)' '
  98        git checkout -b branch1 master &&
  99        echo "3A slow green fox jumps into the" >>file &&
 100        echo "well." >>file &&
 101        GIT_AUTHOR_NAME="B1" GIT_AUTHOR_EMAIL="B1@test.git" \
 102        git commit -a -m "Branch1-1"
 103'
 104
 105test_expect_success 'blame 2 authors + 1 branch1 author' '
 106        check_count A 2 B 2 B1 2
 107'
 108
 109test_expect_success 'setup B2 lines (branch2)' '
 110        git checkout -b branch2 master &&
 111        sed -e "s/2A quick brown/4A quick brown lazy dog/" <file >file.new &&
 112        mv file.new file &&
 113        GIT_AUTHOR_NAME="B2" GIT_AUTHOR_EMAIL="B2@test.git" \
 114        git commit -a -m "Branch2-1"
 115'
 116
 117test_expect_success 'blame 2 authors + 1 branch2 author' '
 118        check_count A 2 B 1 B2 1
 119'
 120
 121test_expect_success 'merge branch1 & branch2' '
 122        git merge branch1
 123'
 124
 125test_expect_success 'blame 2 authors + 2 merged-in authors' '
 126        check_count A 2 B 1 B1 2 B2 1
 127'
 128
 129test_expect_success 'blame --first-parent blames merge for branch1' '
 130        check_count --first-parent A 2 B 1 "A U Thor" 2 B2 1
 131'
 132
 133test_expect_success 'blame ancestor' '
 134        check_count -h master A 2 B 2
 135'
 136
 137test_expect_success 'blame great-ancestor' '
 138        check_count -h master^ A 2
 139'
 140
 141test_expect_success 'setup evil merge' '
 142        echo "evil merge." >>file &&
 143        git commit -a --amend
 144'
 145
 146test_expect_success 'blame evil merge' '
 147        check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1
 148'
 149
 150test_expect_success 'blame huge graft' '
 151        test_when_finished "git checkout branch2" &&
 152        test_when_finished "rm -f .git/info/grafts" &&
 153        graft= &&
 154        for i in 0 1 2
 155        do
 156                for j in 0 1 2 3 4 5 6 7 8 9
 157                do
 158                        git checkout --orphan "$i$j" &&
 159                        printf "%s\n" "$i" "$j" >file &&
 160                        test_tick &&
 161                        GIT_AUTHOR_NAME=$i$j GIT_AUTHOR_EMAIL=$i$j@test.git \
 162                        git commit -a -m "$i$j" &&
 163                        commit=$(git rev-parse --verify HEAD) &&
 164                        graft="$graft$commit "
 165                done
 166        done &&
 167        printf "%s " $graft >.git/info/grafts &&
 168        check_count -h 00 01 1 10 1
 169'
 170
 171test_expect_success 'setup incomplete line' '
 172        echo "incomplete" | tr -d "\\012" >>file &&
 173        GIT_AUTHOR_NAME="C" GIT_AUTHOR_EMAIL="C@test.git" \
 174        git commit -a -m "Incomplete"
 175'
 176
 177test_expect_success 'blame incomplete line' '
 178        check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1 C 1
 179'
 180
 181test_expect_success 'setup edits' '
 182        mv file file.orig &&
 183        {
 184                cat file.orig &&
 185                echo
 186        } | sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" >file &&
 187        echo "incomplete" | tr -d "\\012" >>file &&
 188        GIT_AUTHOR_NAME="D" GIT_AUTHOR_EMAIL="D@test.git" \
 189        git commit -a -m "edit"
 190'
 191
 192test_expect_success 'blame edits' '
 193        check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1
 194'
 195
 196test_expect_success 'setup obfuscated email' '
 197        echo "No robots allowed" >file.new &&
 198        cat file >>file.new &&
 199        mv file.new file &&
 200        GIT_AUTHOR_NAME="E" GIT_AUTHOR_EMAIL="E at test dot git" \
 201        git commit -a -m "norobots"
 202'
 203
 204test_expect_success 'blame obfuscated email' '
 205        check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
 206'
 207
 208test_expect_success 'blame -L 1 (all)' '
 209        check_count -L1 A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
 210'
 211
 212test_expect_success 'blame -L , (all)' '
 213        check_count -L, A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
 214'
 215
 216test_expect_success 'blame -L X (X to end)' '
 217        check_count -L5 B1 1 C 1 D 1 "A U Thor" 1
 218'
 219
 220test_expect_success 'blame -L X, (X to end)' '
 221        check_count -L5, B1 1 C 1 D 1 "A U Thor" 1
 222'
 223
 224test_expect_success 'blame -L ,Y (up to Y)' '
 225        check_count -L,3 A 1 B2 1 E 1
 226'
 227
 228test_expect_success 'blame -L X,X' '
 229        check_count -L3,3 B2 1
 230'
 231
 232test_expect_success 'blame -L X,Y' '
 233        check_count -L3,6 B 1 B1 1 B2 1 D 1
 234'
 235
 236test_expect_success 'blame -L Y,X (undocumented)' '
 237        check_count -L6,3 B 1 B1 1 B2 1 D 1
 238'
 239
 240test_expect_success 'blame -L -X' '
 241        test_must_fail $PROG -L-1 file
 242'
 243
 244test_expect_success 'blame -L 0' '
 245        test_must_fail $PROG -L0 file
 246'
 247
 248test_expect_success 'blame -L ,0' '
 249        test_must_fail $PROG -L,0 file
 250'
 251
 252test_expect_success 'blame -L ,+0' '
 253        test_must_fail $PROG -L,+0 file
 254'
 255
 256test_expect_success 'blame -L X,+0' '
 257        test_must_fail $PROG -L1,+0 file
 258'
 259
 260test_expect_success 'blame -L X,+1' '
 261        check_count -L3,+1 B2 1
 262'
 263
 264test_expect_success 'blame -L X,+N' '
 265        check_count -L3,+4 B 1 B1 1 B2 1 D 1
 266'
 267
 268test_expect_success 'blame -L ,-0' '
 269        test_must_fail $PROG -L,-0 file
 270'
 271
 272test_expect_success 'blame -L X,-0' '
 273        test_must_fail $PROG -L1,-0 file
 274'
 275
 276test_expect_success 'blame -L X,-1' '
 277        check_count -L3,-1 B2 1
 278'
 279
 280test_expect_success 'blame -L X,-N' '
 281        check_count -L6,-4 B 1 B1 1 B2 1 D 1
 282'
 283
 284test_expect_success 'blame -L /RE/ (RE to end)' '
 285        check_count -L/evil/ C 1 "A U Thor" 1
 286'
 287
 288test_expect_success 'blame -L /RE/,/RE2/' '
 289        check_count -L/robot/,/green/ A 1 B 1 B2 1 D 1 E 1
 290'
 291
 292test_expect_success 'blame -L X,/RE/' '
 293        check_count -L5,/evil/ B1 1 D 1 "A U Thor" 1
 294'
 295
 296test_expect_success 'blame -L /RE/,Y' '
 297        check_count -L/99/,7 B1 1 D 1 "A U Thor" 1
 298'
 299
 300test_expect_success 'blame -L /RE/,+N' '
 301        check_count -L/99/,+3 B1 1 D 1 "A U Thor" 1
 302'
 303
 304test_expect_success 'blame -L /RE/,-N' '
 305        check_count -L/99/,-3 B 1 B2 1 D 1
 306'
 307
 308# 'file' ends with an incomplete line, so 'wc' reports one fewer lines than
 309# git-blame sees, hence the last line is actually $(wc...)+1.
 310test_expect_success 'blame -L X (X == nlines)' '
 311        n=$(expr $(wc -l <file) + 1) &&
 312        check_count -L$n C 1
 313'
 314
 315test_expect_success 'blame -L X (X == nlines + 1)' '
 316        n=$(expr $(wc -l <file) + 2) &&
 317        test_must_fail $PROG -L$n file
 318'
 319
 320test_expect_success 'blame -L X (X > nlines)' '
 321        test_must_fail $PROG -L12345 file
 322'
 323
 324test_expect_success 'blame -L ,Y (Y == nlines)' '
 325        n=$(expr $(wc -l <file) + 1) &&
 326        check_count -L,$n A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
 327'
 328
 329test_expect_success 'blame -L ,Y (Y == nlines + 1)' '
 330        n=$(expr $(wc -l <file) + 2) &&
 331        check_count -L,$n A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
 332'
 333
 334test_expect_success 'blame -L ,Y (Y > nlines)' '
 335        check_count -L,12345 A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1
 336'
 337
 338test_expect_success 'blame -L multiple (disjoint)' '
 339        check_count -L2,3 -L6,7 A 1 B1 1 B2 1 "A U Thor" 1
 340'
 341
 342test_expect_success 'blame -L multiple (disjoint: unordered)' '
 343        check_count -L6,7 -L2,3 A 1 B1 1 B2 1 "A U Thor" 1
 344'
 345
 346test_expect_success 'blame -L multiple (adjacent)' '
 347        check_count -L2,3 -L4,5 A 1 B 1 B2 1 D 1
 348'
 349
 350test_expect_success 'blame -L multiple (adjacent: unordered)' '
 351        check_count -L4,5 -L2,3 A 1 B 1 B2 1 D 1
 352'
 353
 354test_expect_success 'blame -L multiple (overlapping)' '
 355        check_count -L2,4 -L3,5 A 1 B 1 B2 1 D 1
 356'
 357
 358test_expect_success 'blame -L multiple (overlapping: unordered)' '
 359        check_count -L3,5 -L2,4 A 1 B 1 B2 1 D 1
 360'
 361
 362test_expect_success 'blame -L multiple (superset/subset)' '
 363        check_count -L2,8 -L3,5 A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
 364'
 365
 366test_expect_success 'blame -L multiple (superset/subset: unordered)' '
 367        check_count -L3,5 -L2,8 A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
 368'
 369
 370test_expect_success 'blame -L /RE/ (relative)' '
 371        check_count -L3,3 -L/fox/ B1 1 B2 1 C 1 D 1 "A U Thor" 1
 372'
 373
 374test_expect_success 'blame -L /RE/ (relative: no preceding range)' '
 375        check_count -L/dog/ A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1
 376'
 377
 378test_expect_success 'blame -L /RE/ (relative: adjacent)' '
 379        check_count -L1,1 -L/dog/,+1 A 1 E 1
 380'
 381
 382test_expect_success 'blame -L /RE/ (relative: not found)' '
 383        test_must_fail $PROG -L4,4 -L/dog/ file
 384'
 385
 386test_expect_success 'blame -L /RE/ (relative: end-of-file)' '
 387        test_must_fail $PROG -L, -L/$/ file
 388'
 389
 390test_expect_success 'blame -L ^/RE/ (absolute)' '
 391        check_count -L3,3 -L^/dog/,+2 A 1 B2 1
 392'
 393
 394test_expect_success 'blame -L ^/RE/ (absolute: no preceding range)' '
 395        check_count -L^/dog/,+2 A 1 B2 1
 396'
 397
 398test_expect_success 'blame -L ^/RE/ (absolute: not found)' '
 399        test_must_fail $PROG -L4,4 -L^/tambourine/ file
 400'
 401
 402test_expect_success 'blame -L ^/RE/ (absolute: end-of-file)' '
 403        n=$(expr $(wc -l <file) + 1) &&
 404        check_count -L$n -L^/$/,+2 A 1 C 1 E 1
 405'
 406
 407test_expect_success 'setup -L :regex' '
 408        tr Q "\\t" >hello.c <<-\EOF &&
 409        int main(int argc, const char *argv[])
 410        {
 411        Qputs("hello");
 412        }
 413        EOF
 414        git add hello.c &&
 415        GIT_AUTHOR_NAME="F" GIT_AUTHOR_EMAIL="F@test.git" \
 416        git commit -m "hello" &&
 417
 418        mv hello.c hello.orig &&
 419        sed -e "/}/ {x; s/$/Qputs(\"goodbye\");/; G;}" <hello.orig |
 420        tr Q "\\t" >hello.c &&
 421        GIT_AUTHOR_NAME="G" GIT_AUTHOR_EMAIL="G@test.git" \
 422        git commit -a -m "goodbye" &&
 423
 424        mv hello.c hello.orig &&
 425        echo "#include <stdio.h>" >hello.c &&
 426        cat hello.orig >>hello.c &&
 427        tr Q "\\t" >>hello.c <<-\EOF &&
 428        void mail()
 429        {
 430        Qputs("mail");
 431        }
 432        EOF
 433        GIT_AUTHOR_NAME="H" GIT_AUTHOR_EMAIL="H@test.git" \
 434        git commit -a -m "mail"
 435'
 436
 437test_expect_success 'blame -L :literal' '
 438        check_count -f hello.c -L:main F 4 G 1
 439'
 440
 441test_expect_success 'blame -L :regex' '
 442        check_count -f hello.c "-L:m[a-z][a-z]l" H 4
 443'
 444
 445test_expect_success 'blame -L :nomatch' '
 446        test_must_fail $PROG -L:nomatch hello.c
 447'
 448
 449test_expect_success 'blame -L :RE (relative)' '
 450        check_count -f hello.c -L3,3 -L:ma.. F 1 H 4
 451'
 452
 453test_expect_success 'blame -L :RE (relative: no preceding range)' '
 454        check_count -f hello.c -L:ma.. F 4 G 1
 455'
 456
 457test_expect_success 'blame -L :RE (relative: not found)' '
 458        test_must_fail $PROG -L3,3 -L:tambourine hello.c
 459'
 460
 461test_expect_success 'blame -L :RE (relative: end-of-file)' '
 462        test_must_fail $PROG -L, -L:main hello.c
 463'
 464
 465test_expect_success 'blame -L ^:RE (absolute)' '
 466        check_count -f hello.c -L3,3 -L^:ma.. F 4 G 1
 467'
 468
 469test_expect_success 'blame -L ^:RE (absolute: no preceding range)' '
 470        check_count -f hello.c -L^:ma.. F 4 G 1
 471'
 472
 473test_expect_success 'blame -L ^:RE (absolute: not found)' '
 474        test_must_fail $PROG -L4,4 -L^:tambourine hello.c
 475'
 476
 477test_expect_success 'blame -L ^:RE (absolute: end-of-file)' '
 478        n=$(printf "%d" $(wc -l <hello.c)) &&
 479        check_count -f hello.c -L$n -L^:ma.. F 4 G 1 H 1
 480'
 481
 482test_expect_success 'setup incremental' '
 483        (
 484        GIT_AUTHOR_NAME=I &&
 485        export GIT_AUTHOR_NAME &&
 486        GIT_AUTHOR_EMAIL=I@test.git &&
 487        export GIT_AUTHOR_EMAIL &&
 488        >incremental &&
 489        git add incremental &&
 490        git commit -m "step 0" &&
 491        printf "partial" >>incremental &&
 492        git commit -a -m "step 0.5" &&
 493        echo >>incremental &&
 494        git commit -a -m "step 1"
 495        )
 496'
 497
 498test_expect_success 'blame empty' '
 499        check_count -h HEAD^^ -f incremental
 500'
 501
 502test_expect_success 'blame -L 0 empty' '
 503        test_must_fail $PROG -L0 incremental HEAD^^
 504'
 505
 506test_expect_success 'blame -L 1 empty' '
 507        test_must_fail $PROG -L1 incremental HEAD^^
 508'
 509
 510test_expect_success 'blame -L 2 empty' '
 511        test_must_fail $PROG -L2 incremental HEAD^^
 512'
 513
 514test_expect_success 'blame half' '
 515        check_count -h HEAD^ -f incremental I 1
 516'
 517
 518test_expect_success 'blame -L 0 half' '
 519        test_must_fail $PROG -L0 incremental HEAD^
 520'
 521
 522test_expect_success 'blame -L 1 half' '
 523        check_count -h HEAD^ -f incremental -L1 I 1
 524'
 525
 526test_expect_success 'blame -L 2 half' '
 527        test_must_fail $PROG -L2 incremental HEAD^
 528'
 529
 530test_expect_success 'blame -L 3 half' '
 531        test_must_fail $PROG -L3 incremental HEAD^
 532'
 533
 534test_expect_success 'blame full' '
 535        check_count -f incremental I 1
 536'
 537
 538test_expect_success 'blame -L 0 full' '
 539        test_must_fail $PROG -L0 incremental
 540'
 541
 542test_expect_success 'blame -L 1 full' '
 543        check_count -f incremental -L1 I 1
 544'
 545
 546test_expect_success 'blame -L 2 full' '
 547        test_must_fail $PROG -L2 incremental
 548'
 549
 550test_expect_success 'blame -L 3 full' '
 551        test_must_fail $PROG -L3 incremental
 552'
 553
 554test_expect_success 'blame -L' '
 555        test_must_fail $PROG -L file
 556'
 557
 558test_expect_success 'blame -L X,+' '
 559        test_must_fail $PROG -L1,+ file
 560'
 561
 562test_expect_success 'blame -L X,-' '
 563        test_must_fail $PROG -L1,- file
 564'
 565
 566test_expect_success 'blame -L X (non-numeric X)' '
 567        test_must_fail $PROG -LX file
 568'
 569
 570test_expect_success 'blame -L X,Y (non-numeric Y)' '
 571        test_must_fail $PROG -L1,Y file
 572'
 573
 574test_expect_success 'blame -L X,+N (non-numeric N)' '
 575        test_must_fail $PROG -L1,+N file
 576'
 577
 578test_expect_success 'blame -L X,-N (non-numeric N)' '
 579        test_must_fail $PROG -L1,-N file
 580'
 581
 582test_expect_success 'blame -L ,^/RE/' '
 583        test_must_fail $PROG -L1,^/99/ file
 584'