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