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