t / t7810-grep.shon commit vscode: wrap commit messages at column 72 by default (f2a3b68)
   1#!/bin/sh
   2#
   3# Copyright (c) 2006 Junio C Hamano
   4#
   5
   6test_description='git grep various.
   7'
   8
   9. ./test-lib.sh
  10
  11cat >hello.c <<EOF
  12#include <assert.h>
  13#include <stdio.h>
  14
  15int main(int argc, const char **argv)
  16{
  17        printf("Hello world.\n");
  18        return 0;
  19        /* char ?? */
  20}
  21EOF
  22
  23test_expect_success setup '
  24        {
  25                echo foo mmap bar
  26                echo foo_mmap bar
  27                echo foo_mmap bar mmap
  28                echo foo mmap bar_mmap
  29                echo foo_mmap bar mmap baz
  30        } >file &&
  31        {
  32                echo Hello world
  33                echo HeLLo world
  34                echo Hello_world
  35                echo HeLLo_world
  36        } >hello_world &&
  37        {
  38                echo "a+b*c"
  39                echo "a+bc"
  40                echo "abc"
  41        } >ab &&
  42        {
  43                echo d &&
  44                echo 0
  45        } >d0 &&
  46        echo vvv >v &&
  47        echo ww w >w &&
  48        echo x x xx x >x &&
  49        echo y yy >y &&
  50        echo zzz > z &&
  51        mkdir t &&
  52        echo test >t/t &&
  53        echo vvv >t/v &&
  54        mkdir t/a &&
  55        echo vvv >t/a/v &&
  56        {
  57                echo "line without leading space1"
  58                echo " line with leading space1"
  59                echo " line with leading space2"
  60                echo " line with leading space3"
  61                echo "line without leading space2"
  62        } >space &&
  63        cat >hello.ps1 <<-\EOF &&
  64        # No-op.
  65        function dummy() {}
  66
  67        # Say hello.
  68        function hello() {
  69          echo "Hello world."
  70        } # hello
  71
  72        # Still a no-op.
  73        function dummy() {}
  74        EOF
  75        git add . &&
  76        test_tick &&
  77        git commit -m initial
  78'
  79
  80test_expect_success 'grep should not segfault with a bad input' '
  81        test_must_fail git grep "("
  82'
  83
  84for H in HEAD ''
  85do
  86        case "$H" in
  87        HEAD)   HC='HEAD:' L='HEAD' ;;
  88        '')     HC= L='in working tree' ;;
  89        esac
  90
  91        test_expect_success "grep -w $L" '
  92                {
  93                        echo ${HC}file:1:foo mmap bar
  94                        echo ${HC}file:3:foo_mmap bar mmap
  95                        echo ${HC}file:4:foo mmap bar_mmap
  96                        echo ${HC}file:5:foo_mmap bar mmap baz
  97                } >expected &&
  98                git -c grep.linenumber=false grep -n -w -e mmap $H >actual &&
  99                test_cmp expected actual
 100        '
 101
 102        test_expect_success "grep -w $L (with --column)" '
 103                {
 104                        echo ${HC}file:5:foo mmap bar
 105                        echo ${HC}file:14:foo_mmap bar mmap
 106                        echo ${HC}file:5:foo mmap bar_mmap
 107                        echo ${HC}file:14:foo_mmap bar mmap baz
 108                } >expected &&
 109                git grep --column -w -e mmap $H >actual &&
 110                test_cmp expected actual
 111        '
 112
 113        test_expect_success "grep -w $L (with --column, extended OR)" '
 114                {
 115                        echo ${HC}file:14:foo_mmap bar mmap
 116                        echo ${HC}file:19:foo_mmap bar mmap baz
 117                } >expected &&
 118                git grep --column -w -e mmap$ --or -e baz $H >actual &&
 119                test_cmp expected actual
 120        '
 121
 122        test_expect_success "grep -w $L (with --column, --invert)" '
 123                {
 124                        echo ${HC}file:1:foo mmap bar
 125                        echo ${HC}file:1:foo_mmap bar
 126                        echo ${HC}file:1:foo_mmap bar mmap
 127                        echo ${HC}file:1:foo mmap bar_mmap
 128                } >expected &&
 129                git grep --column --invert -w -e baz $H -- file >actual &&
 130                test_cmp expected actual
 131        '
 132
 133        test_expect_success "grep $L (with --column, --invert, extended OR)" '
 134                {
 135                        echo ${HC}hello_world:6:HeLLo_world
 136                } >expected &&
 137                git grep --column --invert -e ll --or --not -e _ $H -- hello_world \
 138                        >actual &&
 139                test_cmp expected actual
 140        '
 141
 142        test_expect_success "grep $L (with --column, --invert, extended AND)" '
 143                {
 144                        echo ${HC}hello_world:3:Hello world
 145                        echo ${HC}hello_world:3:Hello_world
 146                        echo ${HC}hello_world:6:HeLLo_world
 147                } >expected &&
 148                git grep --column --invert --not -e _ --and --not -e ll $H -- hello_world \
 149                        >actual &&
 150                test_cmp expected actual
 151        '
 152
 153        test_expect_success "grep $L (with --column, double-negation)" '
 154                {
 155                        echo ${HC}file:1:foo_mmap bar mmap baz
 156                } >expected &&
 157                git grep --column --not \( --not -e foo --or --not -e baz \) $H -- file \
 158                        >actual &&
 159                test_cmp expected actual
 160        '
 161
 162        test_expect_success "grep -w $L (with --column, -C)" '
 163                {
 164                        echo ${HC}file:5:foo mmap bar
 165                        echo ${HC}file-foo_mmap bar
 166                        echo ${HC}file:14:foo_mmap bar mmap
 167                        echo ${HC}file:5:foo mmap bar_mmap
 168                        echo ${HC}file:14:foo_mmap bar mmap baz
 169                } >expected &&
 170                git grep --column -w -C1 -e mmap $H >actual &&
 171                test_cmp expected actual
 172        '
 173
 174        test_expect_success "grep -w $L (with --line-number, --column)" '
 175                {
 176                        echo ${HC}file:1:5:foo mmap bar
 177                        echo ${HC}file:3:14:foo_mmap bar mmap
 178                        echo ${HC}file:4:5:foo mmap bar_mmap
 179                        echo ${HC}file:5:14:foo_mmap bar mmap baz
 180                } >expected &&
 181                git grep -n --column -w -e mmap $H >actual &&
 182                test_cmp expected actual
 183        '
 184
 185        test_expect_success "grep -w $L (with non-extended patterns, --column)" '
 186                {
 187                        echo ${HC}file:5:foo mmap bar
 188                        echo ${HC}file:10:foo_mmap bar
 189                        echo ${HC}file:10:foo_mmap bar mmap
 190                        echo ${HC}file:5:foo mmap bar_mmap
 191                        echo ${HC}file:10:foo_mmap bar mmap baz
 192                } >expected &&
 193                git grep --column -w -e bar -e mmap $H >actual &&
 194                test_cmp expected actual
 195        '
 196
 197        test_expect_success "grep -w $L" '
 198                {
 199                        echo ${HC}file:1:foo mmap bar
 200                        echo ${HC}file:3:foo_mmap bar mmap
 201                        echo ${HC}file:4:foo mmap bar_mmap
 202                        echo ${HC}file:5:foo_mmap bar mmap baz
 203                } >expected &&
 204                git -c grep.linenumber=true grep -w -e mmap $H >actual &&
 205                test_cmp expected actual
 206        '
 207
 208        test_expect_success "grep -w $L" '
 209                {
 210                        echo ${HC}file:foo mmap bar
 211                        echo ${HC}file:foo_mmap bar mmap
 212                        echo ${HC}file:foo mmap bar_mmap
 213                        echo ${HC}file:foo_mmap bar mmap baz
 214                } >expected &&
 215                git -c grep.linenumber=true grep --no-line-number -w -e mmap $H >actual &&
 216                test_cmp expected actual
 217        '
 218
 219        test_expect_success "grep -w $L (w)" '
 220                : >expected &&
 221                test_must_fail git grep -n -w -e "^w" $H >actual &&
 222                test_cmp expected actual
 223        '
 224
 225        test_expect_success "grep -w $L (x)" '
 226                {
 227                        echo ${HC}x:1:x x xx x
 228                } >expected &&
 229                git grep -n -w -e "x xx* x" $H >actual &&
 230                test_cmp expected actual
 231        '
 232
 233        test_expect_success "grep -w $L (y-1)" '
 234                {
 235                        echo ${HC}y:1:y yy
 236                } >expected &&
 237                git grep -n -w -e "^y" $H >actual &&
 238                test_cmp expected actual
 239        '
 240
 241        test_expect_success "grep -w $L (y-2)" '
 242                : >expected &&
 243                if git grep -n -w -e "^y y" $H >actual
 244                then
 245                        echo should not have matched
 246                        cat actual
 247                        false
 248                else
 249                        test_cmp expected actual
 250                fi
 251        '
 252
 253        test_expect_success "grep -w $L (z)" '
 254                : >expected &&
 255                if git grep -n -w -e "^z" $H >actual
 256                then
 257                        echo should not have matched
 258                        cat actual
 259                        false
 260                else
 261                        test_cmp expected actual
 262                fi
 263        '
 264
 265        test_expect_success "grep $L (t-1)" '
 266                echo "${HC}t/t:1:test" >expected &&
 267                git grep -n -e test $H >actual &&
 268                test_cmp expected actual
 269        '
 270
 271        test_expect_success "grep $L (t-2)" '
 272                echo "${HC}t:1:test" >expected &&
 273                (
 274                        cd t &&
 275                        git grep -n -e test $H
 276                ) >actual &&
 277                test_cmp expected actual
 278        '
 279
 280        test_expect_success "grep $L (t-3)" '
 281                echo "${HC}t/t:1:test" >expected &&
 282                (
 283                        cd t &&
 284                        git grep --full-name -n -e test $H
 285                ) >actual &&
 286                test_cmp expected actual
 287        '
 288
 289        test_expect_success "grep -c $L (no /dev/null)" '
 290                ! git grep -c test $H | grep /dev/null
 291        '
 292
 293        test_expect_success "grep --max-depth -1 $L" '
 294                {
 295                        echo ${HC}t/a/v:1:vvv
 296                        echo ${HC}t/v:1:vvv
 297                        echo ${HC}v:1:vvv
 298                } >expected &&
 299                git grep --max-depth -1 -n -e vvv $H >actual &&
 300                test_cmp expected actual
 301        '
 302
 303        test_expect_success "grep --max-depth 0 $L" '
 304                {
 305                        echo ${HC}v:1:vvv
 306                } >expected &&
 307                git grep --max-depth 0 -n -e vvv $H >actual &&
 308                test_cmp expected actual
 309        '
 310
 311        test_expect_success "grep --max-depth 0 -- '*' $L" '
 312                {
 313                        echo ${HC}t/a/v:1:vvv
 314                        echo ${HC}t/v:1:vvv
 315                        echo ${HC}v:1:vvv
 316                } >expected &&
 317                git grep --max-depth 0 -n -e vvv $H -- "*" >actual &&
 318                test_cmp expected actual
 319        '
 320
 321        test_expect_success "grep --max-depth 1 $L" '
 322                {
 323                        echo ${HC}t/v:1:vvv
 324                        echo ${HC}v:1:vvv
 325                } >expected &&
 326                git grep --max-depth 1 -n -e vvv $H >actual &&
 327                test_cmp expected actual
 328        '
 329
 330        test_expect_success "grep --max-depth 0 -- t $L" '
 331                {
 332                        echo ${HC}t/v:1:vvv
 333                } >expected &&
 334                git grep --max-depth 0 -n -e vvv $H -- t >actual &&
 335                test_cmp expected actual
 336        '
 337
 338        test_expect_success "grep --max-depth 0 -- . t $L" '
 339                {
 340                        echo ${HC}t/v:1:vvv
 341                        echo ${HC}v:1:vvv
 342                } >expected &&
 343                git grep --max-depth 0 -n -e vvv $H -- . t >actual &&
 344                test_cmp expected actual
 345        '
 346
 347        test_expect_success "grep --max-depth 0 -- t . $L" '
 348                {
 349                        echo ${HC}t/v:1:vvv
 350                        echo ${HC}v:1:vvv
 351                } >expected &&
 352                git grep --max-depth 0 -n -e vvv $H -- t . >actual &&
 353                test_cmp expected actual
 354        '
 355        test_expect_success "grep $L with grep.extendedRegexp=false" '
 356                echo "${HC}ab:a+bc" >expected &&
 357                git -c grep.extendedRegexp=false grep "a+b*c" $H ab >actual &&
 358                test_cmp expected actual
 359        '
 360
 361        test_expect_success "grep $L with grep.extendedRegexp=true" '
 362                echo "${HC}ab:abc" >expected &&
 363                git -c grep.extendedRegexp=true grep "a+b*c" $H ab >actual &&
 364                test_cmp expected actual
 365        '
 366
 367        test_expect_success "grep $L with grep.patterntype=basic" '
 368                echo "${HC}ab:a+bc" >expected &&
 369                git -c grep.patterntype=basic grep "a+b*c" $H ab >actual &&
 370                test_cmp expected actual
 371        '
 372
 373        test_expect_success "grep $L with grep.patterntype=extended" '
 374                echo "${HC}ab:abc" >expected &&
 375                git -c grep.patterntype=extended grep "a+b*c" $H ab >actual &&
 376                test_cmp expected actual
 377        '
 378
 379        test_expect_success "grep $L with grep.patterntype=fixed" '
 380                echo "${HC}ab:a+b*c" >expected &&
 381                git -c grep.patterntype=fixed grep "a+b*c" $H ab >actual &&
 382                test_cmp expected actual
 383        '
 384
 385        test_expect_success PCRE "grep $L with grep.patterntype=perl" '
 386                echo "${HC}ab:a+b*c" >expected &&
 387                git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" $H ab >actual &&
 388                test_cmp expected actual
 389        '
 390
 391        test_expect_success !PCRE "grep $L with grep.patterntype=perl errors without PCRE" '
 392                test_must_fail git -c grep.patterntype=perl grep "foo.*bar"
 393        '
 394
 395        test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" '
 396                echo "${HC}ab:abc" >expected &&
 397                git \
 398                        -c grep.patternType=default \
 399                        -c grep.extendedRegexp=true \
 400                        grep "a+b*c" $H ab >actual &&
 401                test_cmp expected actual
 402        '
 403
 404        test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" '
 405                echo "${HC}ab:abc" >expected &&
 406                git \
 407                        -c grep.extendedRegexp=true \
 408                        -c grep.patternType=default \
 409                        grep "a+b*c" $H ab >actual &&
 410                test_cmp expected actual
 411        '
 412
 413        test_expect_success "grep $L with grep.patternType=extended and grep.extendedRegexp=false" '
 414                echo "${HC}ab:abc" >expected &&
 415                git \
 416                        -c grep.patternType=extended \
 417                        -c grep.extendedRegexp=false \
 418                        grep "a+b*c" $H ab >actual &&
 419                test_cmp expected actual
 420        '
 421
 422        test_expect_success "grep $L with grep.patternType=basic and grep.extendedRegexp=true" '
 423                echo "${HC}ab:a+bc" >expected &&
 424                git \
 425                        -c grep.patternType=basic \
 426                        -c grep.extendedRegexp=true \
 427                        grep "a+b*c" $H ab >actual &&
 428                test_cmp expected actual
 429        '
 430
 431        test_expect_success "grep $L with grep.extendedRegexp=false and grep.patternType=extended" '
 432                echo "${HC}ab:abc" >expected &&
 433                git \
 434                        -c grep.extendedRegexp=false \
 435                        -c grep.patternType=extended \
 436                        grep "a+b*c" $H ab >actual &&
 437                test_cmp expected actual
 438        '
 439
 440        test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=basic" '
 441                echo "${HC}ab:a+bc" >expected &&
 442                git \
 443                        -c grep.extendedRegexp=true \
 444                        -c grep.patternType=basic \
 445                        grep "a+b*c" $H ab >actual &&
 446                test_cmp expected actual
 447        '
 448
 449        test_expect_success "grep --count $L" '
 450                echo ${HC}ab:3 >expected &&
 451                git grep --count -e b $H -- ab >actual &&
 452                test_cmp expected actual
 453        '
 454
 455        test_expect_success "grep --count -h $L" '
 456                echo 3 >expected &&
 457                git grep --count -h -e b $H -- ab >actual &&
 458                test_cmp expected actual
 459        '
 460done
 461
 462cat >expected <<EOF
 463file
 464EOF
 465test_expect_success 'grep -l -C' '
 466        git grep -l -C1 foo >actual &&
 467        test_cmp expected actual
 468'
 469
 470cat >expected <<EOF
 471file:5
 472EOF
 473test_expect_success 'grep -c -C' '
 474        git grep -c -C1 foo >actual &&
 475        test_cmp expected actual
 476'
 477
 478test_expect_success 'grep -L -C' '
 479        git ls-files >expected &&
 480        git grep -L -C1 nonexistent_string >actual &&
 481        test_cmp expected actual
 482'
 483
 484test_expect_success 'grep --files-without-match --quiet' '
 485        git grep --files-without-match --quiet nonexistent_string >actual &&
 486        test_cmp /dev/null actual
 487'
 488
 489cat >expected <<EOF
 490file:foo mmap bar_mmap
 491EOF
 492
 493test_expect_success 'grep -e A --and -e B' '
 494        git grep -e "foo mmap" --and -e bar_mmap >actual &&
 495        test_cmp expected actual
 496'
 497
 498cat >expected <<EOF
 499file:foo_mmap bar mmap
 500file:foo_mmap bar mmap baz
 501EOF
 502
 503
 504test_expect_success 'grep ( -e A --or -e B ) --and -e B' '
 505        git grep \( -e foo_ --or -e baz \) \
 506                --and -e " mmap" >actual &&
 507        test_cmp expected actual
 508'
 509
 510cat >expected <<EOF
 511file:foo mmap bar
 512EOF
 513
 514test_expect_success 'grep -e A --and --not -e B' '
 515        git grep -e "foo mmap" --and --not -e bar_mmap >actual &&
 516        test_cmp expected actual
 517'
 518
 519test_expect_success 'grep should ignore GREP_OPTIONS' '
 520        GREP_OPTIONS=-v git grep " mmap bar\$" >actual &&
 521        test_cmp expected actual
 522'
 523
 524test_expect_success 'grep -f, non-existent file' '
 525        test_must_fail git grep -f patterns
 526'
 527
 528cat >expected <<EOF
 529file:foo mmap bar
 530file:foo_mmap bar
 531file:foo_mmap bar mmap
 532file:foo mmap bar_mmap
 533file:foo_mmap bar mmap baz
 534EOF
 535
 536cat >pattern <<EOF
 537mmap
 538EOF
 539
 540test_expect_success 'grep -f, one pattern' '
 541        git grep -f pattern >actual &&
 542        test_cmp expected actual
 543'
 544
 545cat >expected <<EOF
 546file:foo mmap bar
 547file:foo_mmap bar
 548file:foo_mmap bar mmap
 549file:foo mmap bar_mmap
 550file:foo_mmap bar mmap baz
 551t/a/v:vvv
 552t/v:vvv
 553v:vvv
 554EOF
 555
 556cat >patterns <<EOF
 557mmap
 558vvv
 559EOF
 560
 561test_expect_success 'grep -f, multiple patterns' '
 562        git grep -f patterns >actual &&
 563        test_cmp expected actual
 564'
 565
 566test_expect_success 'grep, multiple patterns' '
 567        git grep "$(cat patterns)" >actual &&
 568        test_cmp expected actual
 569'
 570
 571cat >expected <<EOF
 572file:foo mmap bar
 573file:foo_mmap bar
 574file:foo_mmap bar mmap
 575file:foo mmap bar_mmap
 576file:foo_mmap bar mmap baz
 577t/a/v:vvv
 578t/v:vvv
 579v:vvv
 580EOF
 581
 582cat >patterns <<EOF
 583
 584mmap
 585
 586vvv
 587
 588EOF
 589
 590test_expect_success 'grep -f, ignore empty lines' '
 591        git grep -f patterns >actual &&
 592        test_cmp expected actual
 593'
 594
 595test_expect_success 'grep -f, ignore empty lines, read patterns from stdin' '
 596        git grep -f - <patterns >actual &&
 597        test_cmp expected actual
 598'
 599
 600cat >expected <<EOF
 601y:y yy
 602--
 603z:zzz
 604EOF
 605
 606test_expect_success 'grep -q, silently report matches' '
 607        >empty &&
 608        git grep -q mmap >actual &&
 609        test_cmp empty actual &&
 610        test_must_fail git grep -q qfwfq >actual &&
 611        test_cmp empty actual
 612'
 613
 614test_expect_success 'grep -C1 hunk mark between files' '
 615        git grep -C1 "^[yz]" >actual &&
 616        test_cmp expected actual
 617'
 618
 619test_expect_success 'log grep setup' '
 620        echo a >>file &&
 621        test_tick &&
 622        GIT_AUTHOR_NAME="With * Asterisk" \
 623        GIT_AUTHOR_EMAIL="xyzzy@frotz.com" \
 624        git commit -a -m "second" &&
 625
 626        echo a >>file &&
 627        test_tick &&
 628        git commit -a -m "third" &&
 629
 630        echo a >>file &&
 631        test_tick &&
 632        GIT_AUTHOR_NAME="Night Fall" \
 633        GIT_AUTHOR_EMAIL="nitfol@frobozz.com" \
 634        git commit -a -m "fourth"
 635'
 636
 637test_expect_success 'log grep (1)' '
 638        git log --author=author --pretty=tformat:%s >actual &&
 639        {
 640                echo third && echo initial
 641        } >expect &&
 642        test_cmp expect actual
 643'
 644
 645test_expect_success 'log grep (2)' '
 646        git log --author=" * " -F --pretty=tformat:%s >actual &&
 647        {
 648                echo second
 649        } >expect &&
 650        test_cmp expect actual
 651'
 652
 653test_expect_success 'log grep (3)' '
 654        git log --author="^A U" --pretty=tformat:%s >actual &&
 655        {
 656                echo third && echo initial
 657        } >expect &&
 658        test_cmp expect actual
 659'
 660
 661test_expect_success 'log grep (4)' '
 662        git log --author="frotz\.com>$" --pretty=tformat:%s >actual &&
 663        {
 664                echo second
 665        } >expect &&
 666        test_cmp expect actual
 667'
 668
 669test_expect_success 'log grep (5)' '
 670        git log --author=Thor -F --pretty=tformat:%s >actual &&
 671        {
 672                echo third && echo initial
 673        } >expect &&
 674        test_cmp expect actual
 675'
 676
 677test_expect_success 'log grep (6)' '
 678        git log --author=-0700  --pretty=tformat:%s >actual &&
 679        >expect &&
 680        test_cmp expect actual
 681'
 682
 683test_expect_success 'log grep (7)' '
 684        git log -g --grep-reflog="commit: third" --pretty=tformat:%s >actual &&
 685        echo third >expect &&
 686        test_cmp expect actual
 687'
 688
 689test_expect_success 'log grep (8)' '
 690        git log -g --grep-reflog="commit: third" --grep-reflog="commit: second" --pretty=tformat:%s >actual &&
 691        {
 692                echo third && echo second
 693        } >expect &&
 694        test_cmp expect actual
 695'
 696
 697test_expect_success 'log grep (9)' '
 698        git log -g --grep-reflog="commit: third" --author="Thor" --pretty=tformat:%s >actual &&
 699        echo third >expect &&
 700        test_cmp expect actual
 701'
 702
 703test_expect_success 'log grep (9)' '
 704        git log -g --grep-reflog="commit: third" --author="non-existent" --pretty=tformat:%s >actual &&
 705        : >expect &&
 706        test_cmp expect actual
 707'
 708
 709test_expect_success 'log --grep-reflog can only be used under -g' '
 710        test_must_fail git log --grep-reflog="commit: third"
 711'
 712
 713test_expect_success 'log with multiple --grep uses union' '
 714        git log --grep=i --grep=r --format=%s >actual &&
 715        {
 716                echo fourth && echo third && echo initial
 717        } >expect &&
 718        test_cmp expect actual
 719'
 720
 721test_expect_success 'log --all-match with multiple --grep uses intersection' '
 722        git log --all-match --grep=i --grep=r --format=%s >actual &&
 723        {
 724                echo third
 725        } >expect &&
 726        test_cmp expect actual
 727'
 728
 729test_expect_success 'log with multiple --author uses union' '
 730        git log --author="Thor" --author="Aster" --format=%s >actual &&
 731        {
 732            echo third && echo second && echo initial
 733        } >expect &&
 734        test_cmp expect actual
 735'
 736
 737test_expect_success 'log --all-match with multiple --author still uses union' '
 738        git log --all-match --author="Thor" --author="Aster" --format=%s >actual &&
 739        {
 740            echo third && echo second && echo initial
 741        } >expect &&
 742        test_cmp expect actual
 743'
 744
 745test_expect_success 'log --grep --author uses intersection' '
 746        # grep matches only third and fourth
 747        # author matches only initial and third
 748        git log --author="A U Thor" --grep=r --format=%s >actual &&
 749        {
 750                echo third
 751        } >expect &&
 752        test_cmp expect actual
 753'
 754
 755test_expect_success 'log --grep --grep --author takes union of greps and intersects with author' '
 756        # grep matches initial and second but not third
 757        # author matches only initial and third
 758        git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
 759        {
 760                echo initial
 761        } >expect &&
 762        test_cmp expect actual
 763'
 764
 765test_expect_success 'log ---all-match -grep --author --author still takes union of authors and intersects with grep' '
 766        # grep matches only initial and third
 767        # author matches all but second
 768        git log --all-match --author="Thor" --author="Night" --grep=i --format=%s >actual &&
 769        {
 770            echo third && echo initial
 771        } >expect &&
 772        test_cmp expect actual
 773'
 774
 775test_expect_success 'log --grep --author --author takes union of authors and intersects with grep' '
 776        # grep matches only initial and third
 777        # author matches all but second
 778        git log --author="Thor" --author="Night" --grep=i --format=%s >actual &&
 779        {
 780            echo third && echo initial
 781        } >expect &&
 782        test_cmp expect actual
 783'
 784
 785test_expect_success 'log --all-match --grep --grep --author takes intersection' '
 786        # grep matches only third
 787        # author matches only initial and third
 788        git log --all-match --author="A U Thor" --grep=i --grep=r --format=%s >actual &&
 789        {
 790                echo third
 791        } >expect &&
 792        test_cmp expect actual
 793'
 794
 795test_expect_success 'log --author does not search in timestamp' '
 796        : >expect &&
 797        git log --author="$GIT_AUTHOR_DATE" >actual &&
 798        test_cmp expect actual
 799'
 800
 801test_expect_success 'log --committer does not search in timestamp' '
 802        : >expect &&
 803        git log --committer="$GIT_COMMITTER_DATE" >actual &&
 804        test_cmp expect actual
 805'
 806
 807test_expect_success 'grep with CE_VALID file' '
 808        git update-index --assume-unchanged t/t &&
 809        rm t/t &&
 810        test "$(git grep test)" = "t/t:test" &&
 811        git update-index --no-assume-unchanged t/t &&
 812        git checkout t/t
 813'
 814
 815cat >expected <<EOF
 816hello.c=#include <stdio.h>
 817hello.c:        return 0;
 818EOF
 819
 820test_expect_success 'grep -p with userdiff' '
 821        git config diff.custom.funcname "^#" &&
 822        echo "hello.c diff=custom" >.gitattributes &&
 823        git grep -p return >actual &&
 824        test_cmp expected actual
 825'
 826
 827cat >expected <<EOF
 828hello.c=int main(int argc, const char **argv)
 829hello.c:        return 0;
 830EOF
 831
 832test_expect_success 'grep -p' '
 833        rm -f .gitattributes &&
 834        git grep -p return >actual &&
 835        test_cmp expected actual
 836'
 837
 838cat >expected <<EOF
 839hello.c-#include <stdio.h>
 840hello.c-
 841hello.c=int main(int argc, const char **argv)
 842hello.c-{
 843hello.c-        printf("Hello world.\n");
 844hello.c:        return 0;
 845EOF
 846
 847test_expect_success 'grep -p -B5' '
 848        git grep -p -B5 return >actual &&
 849        test_cmp expected actual
 850'
 851
 852cat >expected <<EOF
 853hello.c=int main(int argc, const char **argv)
 854hello.c-{
 855hello.c-        printf("Hello world.\n");
 856hello.c:        return 0;
 857hello.c-        /* char ?? */
 858hello.c-}
 859EOF
 860
 861test_expect_success 'grep -W' '
 862        git grep -W return >actual &&
 863        test_cmp expected actual
 864'
 865
 866cat >expected <<EOF
 867hello.c-#include <assert.h>
 868hello.c:#include <stdio.h>
 869EOF
 870
 871test_expect_success 'grep -W shows no trailing empty lines' '
 872        git grep -W stdio >actual &&
 873        test_cmp expected actual
 874'
 875
 876test_expect_success 'grep -W with userdiff' '
 877        test_when_finished "rm -f .gitattributes" &&
 878        git config diff.custom.xfuncname "^function .*$" &&
 879        echo "hello.ps1 diff=custom" >.gitattributes &&
 880        git grep -W echo >function-context-userdiff-actual
 881'
 882
 883test_expect_success ' includes preceding comment' '
 884        grep "# Say hello" function-context-userdiff-actual
 885'
 886
 887test_expect_success ' includes function line' '
 888        grep "=function hello" function-context-userdiff-actual
 889'
 890
 891test_expect_success ' includes matching line' '
 892        grep ":  echo" function-context-userdiff-actual
 893'
 894
 895test_expect_success ' includes last line of the function' '
 896        grep "} # hello" function-context-userdiff-actual
 897'
 898
 899for threads in $(test_seq 0 10)
 900do
 901        test_expect_success "grep --threads=$threads & -c grep.threads=$threads" "
 902                git grep --threads=$threads . >actual.$threads &&
 903                if test $threads -ge 1
 904                then
 905                        test_cmp actual.\$(($threads - 1)) actual.$threads
 906                fi &&
 907                git -c grep.threads=$threads grep . >actual.$threads &&
 908                if test $threads -ge 1
 909                then
 910                        test_cmp actual.\$(($threads - 1)) actual.$threads
 911                fi
 912        "
 913done
 914
 915test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'grep --threads=N or pack.threads=N warns when no pthreads' '
 916        git grep --threads=2 Hello hello_world 2>err &&
 917        grep ^warning: err >warnings &&
 918        test_line_count = 1 warnings &&
 919        grep -F "no threads support, ignoring --threads" err &&
 920        git -c grep.threads=2 grep Hello hello_world 2>err &&
 921        grep ^warning: err >warnings &&
 922        test_line_count = 1 warnings &&
 923        grep -F "no threads support, ignoring grep.threads" err &&
 924        git -c grep.threads=2 grep --threads=4 Hello hello_world 2>err &&
 925        grep ^warning: err >warnings &&
 926        test_line_count = 2 warnings &&
 927        grep -F "no threads support, ignoring --threads" err &&
 928        grep -F "no threads support, ignoring grep.threads" err &&
 929        git -c grep.threads=0 grep --threads=0 Hello hello_world 2>err &&
 930        test_line_count = 0 err
 931'
 932
 933test_expect_success 'grep from a subdirectory to search wider area (1)' '
 934        mkdir -p s &&
 935        (
 936                cd s && git grep "x x x" ..
 937        )
 938'
 939
 940test_expect_success 'grep from a subdirectory to search wider area (2)' '
 941        mkdir -p s &&
 942        (
 943                cd s || exit 1
 944                ( git grep xxyyzz .. >out ; echo $? >status )
 945                ! test -s out &&
 946                test 1 = $(cat status)
 947        )
 948'
 949
 950cat >expected <<EOF
 951hello.c:int main(int argc, const char **argv)
 952EOF
 953
 954test_expect_success 'grep -Fi' '
 955        git grep -Fi "CHAR *" >actual &&
 956        test_cmp expected actual
 957'
 958
 959test_expect_success 'outside of git repository' '
 960        rm -fr non &&
 961        mkdir -p non/git/sub &&
 962        echo hello >non/git/file1 &&
 963        echo world >non/git/sub/file2 &&
 964        {
 965                echo file1:hello &&
 966                echo sub/file2:world
 967        } >non/expect.full &&
 968        echo file2:world >non/expect.sub &&
 969        (
 970                GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
 971                export GIT_CEILING_DIRECTORIES &&
 972                cd non/git &&
 973                test_must_fail git grep o &&
 974                git grep --no-index o >../actual.full &&
 975                test_cmp ../expect.full ../actual.full &&
 976                cd sub &&
 977                test_must_fail git grep o &&
 978                git grep --no-index o >../../actual.sub &&
 979                test_cmp ../../expect.sub ../../actual.sub
 980        ) &&
 981
 982        echo ".*o*" >non/git/.gitignore &&
 983        (
 984                GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
 985                export GIT_CEILING_DIRECTORIES &&
 986                cd non/git &&
 987                test_must_fail git grep o &&
 988                git grep --no-index --exclude-standard o >../actual.full &&
 989                test_cmp ../expect.full ../actual.full &&
 990
 991                {
 992                        echo ".gitignore:.*o*" &&
 993                        cat ../expect.full
 994                } >../expect.with.ignored &&
 995                git grep --no-index --no-exclude o >../actual.full &&
 996                test_cmp ../expect.with.ignored ../actual.full
 997        )
 998'
 999
1000test_expect_success 'outside of git repository with fallbackToNoIndex' '
1001        rm -fr non &&
1002        mkdir -p non/git/sub &&
1003        echo hello >non/git/file1 &&
1004        echo world >non/git/sub/file2 &&
1005        cat <<-\EOF >non/expect.full &&
1006        file1:hello
1007        sub/file2:world
1008        EOF
1009        echo file2:world >non/expect.sub &&
1010        (
1011                GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1012                export GIT_CEILING_DIRECTORIES &&
1013                cd non/git &&
1014                test_must_fail git -c grep.fallbackToNoIndex=false grep o &&
1015                git -c grep.fallbackToNoIndex=true grep o >../actual.full &&
1016                test_cmp ../expect.full ../actual.full &&
1017                cd sub &&
1018                test_must_fail git -c grep.fallbackToNoIndex=false grep o &&
1019                git -c grep.fallbackToNoIndex=true grep o >../../actual.sub &&
1020                test_cmp ../../expect.sub ../../actual.sub
1021        ) &&
1022
1023        echo ".*o*" >non/git/.gitignore &&
1024        (
1025                GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1026                export GIT_CEILING_DIRECTORIES &&
1027                cd non/git &&
1028                test_must_fail git -c grep.fallbackToNoIndex=false grep o &&
1029                git -c grep.fallbackToNoIndex=true grep --exclude-standard o >../actual.full &&
1030                test_cmp ../expect.full ../actual.full &&
1031
1032                {
1033                        echo ".gitignore:.*o*" &&
1034                        cat ../expect.full
1035                } >../expect.with.ignored &&
1036                git -c grep.fallbackToNoIndex grep --no-exclude o >../actual.full &&
1037                test_cmp ../expect.with.ignored ../actual.full
1038        )
1039'
1040
1041test_expect_success 'inside git repository but with --no-index' '
1042        rm -fr is &&
1043        mkdir -p is/git/sub &&
1044        echo hello >is/git/file1 &&
1045        echo world >is/git/sub/file2 &&
1046        echo ".*o*" >is/git/.gitignore &&
1047        {
1048                echo file1:hello &&
1049                echo sub/file2:world
1050        } >is/expect.unignored &&
1051        {
1052                echo ".gitignore:.*o*" &&
1053                cat is/expect.unignored
1054        } >is/expect.full &&
1055        : >is/expect.empty &&
1056        echo file2:world >is/expect.sub &&
1057        (
1058                cd is/git &&
1059                git init &&
1060                test_must_fail git grep o >../actual.full &&
1061                test_cmp ../expect.empty ../actual.full &&
1062
1063                git grep --untracked o >../actual.unignored &&
1064                test_cmp ../expect.unignored ../actual.unignored &&
1065
1066                git grep --no-index o >../actual.full &&
1067                test_cmp ../expect.full ../actual.full &&
1068
1069                git grep --no-index --exclude-standard o >../actual.unignored &&
1070                test_cmp ../expect.unignored ../actual.unignored &&
1071
1072                cd sub &&
1073                test_must_fail git grep o >../../actual.sub &&
1074                test_cmp ../../expect.empty ../../actual.sub &&
1075
1076                git grep --no-index o >../../actual.sub &&
1077                test_cmp ../../expect.sub ../../actual.sub &&
1078
1079                git grep --untracked o >../../actual.sub &&
1080                test_cmp ../../expect.sub ../../actual.sub
1081        )
1082'
1083
1084test_expect_success 'grep --no-index descends into repos, but not .git' '
1085        rm -fr non &&
1086        mkdir -p non/git &&
1087        (
1088                GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1089                export GIT_CEILING_DIRECTORIES &&
1090                cd non/git &&
1091
1092                echo magic >file &&
1093                git init repo &&
1094                (
1095                        cd repo &&
1096                        echo magic >file &&
1097                        git add file &&
1098                        git commit -m foo &&
1099                        echo magic >.git/file
1100                ) &&
1101
1102                cat >expect <<-\EOF &&
1103                file
1104                repo/file
1105                EOF
1106                git grep -l --no-index magic >actual &&
1107                test_cmp expect actual
1108        )
1109'
1110
1111test_expect_success 'setup double-dash tests' '
1112cat >double-dash <<EOF &&
1113--
1114->
1115other
1116EOF
1117git add double-dash
1118'
1119
1120cat >expected <<EOF
1121double-dash:->
1122EOF
1123test_expect_success 'grep -- pattern' '
1124        git grep -- "->" >actual &&
1125        test_cmp expected actual
1126'
1127test_expect_success 'grep -- pattern -- pathspec' '
1128        git grep -- "->" -- double-dash >actual &&
1129        test_cmp expected actual
1130'
1131test_expect_success 'grep -e pattern -- path' '
1132        git grep -e "->" -- double-dash >actual &&
1133        test_cmp expected actual
1134'
1135
1136cat >expected <<EOF
1137double-dash:--
1138EOF
1139test_expect_success 'grep -e -- -- path' '
1140        git grep -e -- -- double-dash >actual &&
1141        test_cmp expected actual
1142'
1143
1144test_expect_success 'dashdash disambiguates rev as rev' '
1145        test_when_finished "rm -f master" &&
1146        echo content >master &&
1147        echo master:hello.c >expect &&
1148        git grep -l o master -- hello.c >actual &&
1149        test_cmp expect actual
1150'
1151
1152test_expect_success 'dashdash disambiguates pathspec as pathspec' '
1153        test_when_finished "git rm -f master" &&
1154        echo content >master &&
1155        git add master &&
1156        echo master:content >expect &&
1157        git grep o -- master >actual &&
1158        test_cmp expect actual
1159'
1160
1161test_expect_success 'report bogus arg without dashdash' '
1162        test_must_fail git grep o does-not-exist
1163'
1164
1165test_expect_success 'report bogus rev with dashdash' '
1166        test_must_fail git grep o hello.c --
1167'
1168
1169test_expect_success 'allow non-existent path with dashdash' '
1170        # We need a real match so grep exits with success.
1171        tree=$(git ls-tree HEAD |
1172               sed s/hello.c/not-in-working-tree/ |
1173               git mktree) &&
1174        git grep o "$tree" -- not-in-working-tree
1175'
1176
1177test_expect_success 'grep --no-index pattern -- path' '
1178        rm -fr non &&
1179        mkdir -p non/git &&
1180        (
1181                GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
1182                export GIT_CEILING_DIRECTORIES &&
1183                cd non/git &&
1184                echo hello >hello &&
1185                echo goodbye >goodbye &&
1186                echo hello:hello >expect &&
1187                git grep --no-index o -- hello >actual &&
1188                test_cmp expect actual
1189        )
1190'
1191
1192test_expect_success 'grep --no-index complains of revs' '
1193        test_must_fail git grep --no-index o master -- 2>err &&
1194        test_i18ngrep "cannot be used with revs" err
1195'
1196
1197test_expect_success 'grep --no-index prefers paths to revs' '
1198        test_when_finished "rm -f master" &&
1199        echo content >master &&
1200        echo master:content >expect &&
1201        git grep --no-index o master >actual &&
1202        test_cmp expect actual
1203'
1204
1205test_expect_success 'grep --no-index does not "diagnose" revs' '
1206        test_must_fail git grep --no-index o :1:hello.c 2>err &&
1207        test_i18ngrep ! -i "did you mean" err
1208'
1209
1210cat >expected <<EOF
1211hello.c:int main(int argc, const char **argv)
1212hello.c:        printf("Hello world.\n");
1213EOF
1214
1215test_expect_success PCRE 'grep --perl-regexp pattern' '
1216        git grep --perl-regexp "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1217        test_cmp expected actual
1218'
1219
1220test_expect_success !PCRE 'grep --perl-regexp pattern errors without PCRE' '
1221        test_must_fail git grep --perl-regexp "foo.*bar"
1222'
1223
1224test_expect_success PCRE 'grep -P pattern' '
1225        git grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1226        test_cmp expected actual
1227'
1228
1229test_expect_success LIBPCRE2 "grep -P with (*NO_JIT) doesn't error out" '
1230        git grep -P "(*NO_JIT)\p{Ps}.*?\p{Pe}" hello.c >actual &&
1231        test_cmp expected actual
1232
1233'
1234
1235test_expect_success !PCRE 'grep -P pattern errors without PCRE' '
1236        test_must_fail git grep -P "foo.*bar"
1237'
1238
1239test_expect_success 'grep pattern with grep.extendedRegexp=true' '
1240        >empty &&
1241        test_must_fail git -c grep.extendedregexp=true \
1242                grep "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1243        test_cmp empty actual
1244'
1245
1246test_expect_success PCRE 'grep -P pattern with grep.extendedRegexp=true' '
1247        git -c grep.extendedregexp=true \
1248                grep -P "\p{Ps}.*?\p{Pe}" hello.c >actual &&
1249        test_cmp expected actual
1250'
1251
1252test_expect_success PCRE 'grep -P -v pattern' '
1253        {
1254                echo "ab:a+b*c"
1255                echo "ab:a+bc"
1256        } >expected &&
1257        git grep -P -v "abc" ab >actual &&
1258        test_cmp expected actual
1259'
1260
1261test_expect_success PCRE 'grep -P -i pattern' '
1262        cat >expected <<-EOF &&
1263        hello.c:        printf("Hello world.\n");
1264        EOF
1265        git grep -P -i "PRINTF\([^\d]+\)" hello.c >actual &&
1266        test_cmp expected actual
1267'
1268
1269test_expect_success PCRE 'grep -P -w pattern' '
1270        {
1271                echo "hello_world:Hello world"
1272                echo "hello_world:HeLLo world"
1273        } >expected &&
1274        git grep -P -w "He((?i)ll)o" hello_world >actual &&
1275        test_cmp expected actual
1276'
1277
1278test_expect_success PCRE 'grep -P backreferences work (the PCRE NO_AUTO_CAPTURE flag is not set)' '
1279        git grep -P -h "(?P<one>.)(?P=one)" hello_world >actual &&
1280        test_cmp hello_world actual &&
1281        git grep -P -h "(.)\1" hello_world >actual &&
1282        test_cmp hello_world actual
1283'
1284
1285test_expect_success 'grep -G invalidpattern properly dies ' '
1286        test_must_fail git grep -G "a["
1287'
1288
1289test_expect_success 'grep invalidpattern properly dies with grep.patternType=basic' '
1290        test_must_fail git -c grep.patterntype=basic grep "a["
1291'
1292
1293test_expect_success 'grep -E invalidpattern properly dies ' '
1294        test_must_fail git grep -E "a["
1295'
1296
1297test_expect_success 'grep invalidpattern properly dies with grep.patternType=extended' '
1298        test_must_fail git -c grep.patterntype=extended grep "a["
1299'
1300
1301test_expect_success PCRE 'grep -P invalidpattern properly dies ' '
1302        test_must_fail git grep -P "a["
1303'
1304
1305test_expect_success PCRE 'grep invalidpattern properly dies with grep.patternType=perl' '
1306        test_must_fail git -c grep.patterntype=perl grep "a["
1307'
1308
1309test_expect_success 'grep -G -E -F pattern' '
1310        echo "ab:a+b*c" >expected &&
1311        git grep -G -E -F "a+b*c" ab >actual &&
1312        test_cmp expected actual
1313'
1314
1315test_expect_success 'grep pattern with grep.patternType=basic, =extended, =fixed' '
1316        echo "ab:a+b*c" >expected &&
1317        git \
1318                -c grep.patterntype=basic \
1319                -c grep.patterntype=extended \
1320                -c grep.patterntype=fixed \
1321                grep "a+b*c" ab >actual &&
1322        test_cmp expected actual
1323'
1324
1325test_expect_success 'grep -E -F -G pattern' '
1326        echo "ab:a+bc" >expected &&
1327        git grep -E -F -G "a+b*c" ab >actual &&
1328        test_cmp expected actual
1329'
1330
1331test_expect_success 'grep pattern with grep.patternType=extended, =fixed, =basic' '
1332        echo "ab:a+bc" >expected &&
1333        git \
1334                -c grep.patterntype=extended \
1335                -c grep.patterntype=fixed \
1336                -c grep.patterntype=basic \
1337                grep "a+b*c" ab >actual &&
1338        test_cmp expected actual
1339'
1340
1341test_expect_success 'grep -F -G -E pattern' '
1342        echo "ab:abc" >expected &&
1343        git grep -F -G -E "a+b*c" ab >actual &&
1344        test_cmp expected actual
1345'
1346
1347test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =extended' '
1348        echo "ab:abc" >expected &&
1349        git \
1350                -c grep.patterntype=fixed \
1351                -c grep.patterntype=basic \
1352                -c grep.patterntype=extended \
1353                grep "a+b*c" ab >actual &&
1354        test_cmp expected actual
1355'
1356
1357test_expect_success 'grep -G -F -P -E pattern' '
1358        echo "d0:d" >expected &&
1359        git grep -G -F -P -E "[\d]" d0 >actual &&
1360        test_cmp expected actual
1361'
1362
1363test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =extended' '
1364        echo "d0:d" >expected &&
1365        git \
1366                -c grep.patterntype=fixed \
1367                -c grep.patterntype=basic \
1368                -c grep.patterntype=perl \
1369                -c grep.patterntype=extended \
1370                grep "[\d]" d0 >actual &&
1371        test_cmp expected actual
1372'
1373
1374test_expect_success PCRE 'grep -G -F -E -P pattern' '
1375        echo "d0:0" >expected &&
1376        git grep -G -F -E -P "[\d]" d0 >actual &&
1377        test_cmp expected actual
1378'
1379
1380test_expect_success PCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' '
1381        echo "d0:0" >expected &&
1382        git \
1383                -c grep.patterntype=fixed \
1384                -c grep.patterntype=basic \
1385                -c grep.patterntype=extended \
1386                -c grep.patterntype=perl \
1387                grep "[\d]" d0 >actual &&
1388        test_cmp expected actual
1389'
1390
1391test_expect_success PCRE 'grep -P pattern with grep.patternType=fixed' '
1392        echo "ab:a+b*c" >expected &&
1393        git \
1394                -c grep.patterntype=fixed \
1395                grep -P "a\x{2b}b\x{2a}c" ab >actual &&
1396        test_cmp expected actual
1397'
1398
1399test_expect_success 'grep -F pattern with grep.patternType=basic' '
1400        echo "ab:a+b*c" >expected &&
1401        git \
1402                -c grep.patterntype=basic \
1403                grep -F "*c" ab >actual &&
1404        test_cmp expected actual
1405'
1406
1407test_expect_success 'grep -G pattern with grep.patternType=fixed' '
1408        {
1409                echo "ab:a+b*c"
1410                echo "ab:a+bc"
1411        } >expected &&
1412        git \
1413                -c grep.patterntype=fixed \
1414                grep -G "a+b" ab >actual &&
1415        test_cmp expected actual
1416'
1417
1418test_expect_success 'grep -E pattern with grep.patternType=fixed' '
1419        {
1420                echo "ab:a+b*c"
1421                echo "ab:a+bc"
1422                echo "ab:abc"
1423        } >expected &&
1424        git \
1425                -c grep.patterntype=fixed \
1426                grep -E "a+" ab >actual &&
1427        test_cmp expected actual
1428'
1429
1430cat >expected <<EOF
1431hello.c<RED>:<RESET>int main(int argc, const char **argv)
1432hello.c<RED>-<RESET>{
1433<RED>--<RESET>
1434hello.c<RED>:<RESET>    /* char ?? */
1435hello.c<RED>-<RESET>}
1436<RED>--<RESET>
1437hello_world<RED>:<RESET>Hello_world
1438hello_world<RED>-<RESET>HeLLo_world
1439EOF
1440
1441test_expect_success 'grep --color, separator' '
1442        test_config color.grep.context          normal &&
1443        test_config color.grep.filename         normal &&
1444        test_config color.grep.function         normal &&
1445        test_config color.grep.linenumber       normal &&
1446        test_config color.grep.match            normal &&
1447        test_config color.grep.selected         normal &&
1448        test_config color.grep.separator        red &&
1449
1450        git grep --color=always -A1 -e char -e lo_w hello.c hello_world |
1451        test_decode_color >actual &&
1452        test_cmp expected actual
1453'
1454
1455cat >expected <<EOF
1456hello.c:int main(int argc, const char **argv)
1457hello.c:        /* char ?? */
1458
1459hello_world:Hello_world
1460EOF
1461
1462test_expect_success 'grep --break' '
1463        git grep --break -e char -e lo_w hello.c hello_world >actual &&
1464        test_cmp expected actual
1465'
1466
1467cat >expected <<EOF
1468hello.c:int main(int argc, const char **argv)
1469hello.c-{
1470--
1471hello.c:        /* char ?? */
1472hello.c-}
1473
1474hello_world:Hello_world
1475hello_world-HeLLo_world
1476EOF
1477
1478test_expect_success 'grep --break with context' '
1479        git grep --break -A1 -e char -e lo_w hello.c hello_world >actual &&
1480        test_cmp expected actual
1481'
1482
1483cat >expected <<EOF
1484hello.c
1485int main(int argc, const char **argv)
1486        /* char ?? */
1487hello_world
1488Hello_world
1489EOF
1490
1491test_expect_success 'grep --heading' '
1492        git grep --heading -e char -e lo_w hello.c hello_world >actual &&
1493        test_cmp expected actual
1494'
1495
1496cat >expected <<EOF
1497<BOLD;GREEN>hello.c<RESET>
14984:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv)
14998:      /* <BLACK;BYELLOW>char<RESET> ?? */
1500
1501<BOLD;GREEN>hello_world<RESET>
15023:Hel<BLACK;BYELLOW>lo_w<RESET>orld
1503EOF
1504
1505test_expect_success 'mimic ack-grep --group' '
1506        test_config color.grep.context          normal &&
1507        test_config color.grep.filename         "bold green" &&
1508        test_config color.grep.function         normal &&
1509        test_config color.grep.linenumber       normal &&
1510        test_config color.grep.match            "black yellow" &&
1511        test_config color.grep.selected         normal &&
1512        test_config color.grep.separator        normal &&
1513
1514        git grep --break --heading -n --color \
1515                -e char -e lo_w hello.c hello_world |
1516        test_decode_color >actual &&
1517        test_cmp expected actual
1518'
1519
1520cat >expected <<EOF
1521space: line with leading space1
1522space: line with leading space2
1523space: line with leading space3
1524EOF
1525
1526test_expect_success PCRE 'grep -E "^ "' '
1527        git grep -E "^ " space >actual &&
1528        test_cmp expected actual
1529'
1530
1531test_expect_success PCRE 'grep -P "^ "' '
1532        git grep -P "^ " space >actual &&
1533        test_cmp expected actual
1534'
1535
1536cat >expected <<EOF
1537space-line without leading space1
1538space: line <RED>with <RESET>leading space1
1539space: line <RED>with <RESET>leading <RED>space2<RESET>
1540space: line <RED>with <RESET>leading space3
1541space:line without leading <RED>space2<RESET>
1542EOF
1543
1544test_expect_success 'grep --color -e A -e B with context' '
1545        test_config color.grep.context          normal &&
1546        test_config color.grep.filename         normal &&
1547        test_config color.grep.function         normal &&
1548        test_config color.grep.linenumber       normal &&
1549        test_config color.grep.matchContext     normal &&
1550        test_config color.grep.matchSelected    red &&
1551        test_config color.grep.selected         normal &&
1552        test_config color.grep.separator        normal &&
1553
1554        git grep --color=always -C2 -e "with " -e space2  space |
1555        test_decode_color >actual &&
1556        test_cmp expected actual
1557'
1558
1559cat >expected <<EOF
1560space-line without leading space1
1561space- line with leading space1
1562space: line <RED>with <RESET>leading <RED>space2<RESET>
1563space- line with leading space3
1564space-line without leading space2
1565EOF
1566
1567test_expect_success 'grep --color -e A --and -e B with context' '
1568        test_config color.grep.context          normal &&
1569        test_config color.grep.filename         normal &&
1570        test_config color.grep.function         normal &&
1571        test_config color.grep.linenumber       normal &&
1572        test_config color.grep.matchContext     normal &&
1573        test_config color.grep.matchSelected    red &&
1574        test_config color.grep.selected         normal &&
1575        test_config color.grep.separator        normal &&
1576
1577        git grep --color=always -C2 -e "with " --and -e space2  space |
1578        test_decode_color >actual &&
1579        test_cmp expected actual
1580'
1581
1582cat >expected <<EOF
1583space-line without leading space1
1584space: line <RED>with <RESET>leading space1
1585space- line with leading space2
1586space: line <RED>with <RESET>leading space3
1587space-line without leading space2
1588EOF
1589
1590test_expect_success 'grep --color -e A --and --not -e B with context' '
1591        test_config color.grep.context          normal &&
1592        test_config color.grep.filename         normal &&
1593        test_config color.grep.function         normal &&
1594        test_config color.grep.linenumber       normal &&
1595        test_config color.grep.matchContext     normal &&
1596        test_config color.grep.matchSelected    red &&
1597        test_config color.grep.selected         normal &&
1598        test_config color.grep.separator        normal &&
1599
1600        git grep --color=always -C2 -e "with " --and --not -e space2  space |
1601        test_decode_color >actual &&
1602        test_cmp expected actual
1603'
1604
1605cat >expected <<EOF
1606hello.c-
1607hello.c=int main(int argc, const char **argv)
1608hello.c-{
1609hello.c:        pr<RED>int<RESET>f("<RED>Hello<RESET> world.\n");
1610hello.c-        return 0;
1611hello.c-        /* char ?? */
1612hello.c-}
1613EOF
1614
1615test_expect_success 'grep --color -e A --and -e B -p with context' '
1616        test_config color.grep.context          normal &&
1617        test_config color.grep.filename         normal &&
1618        test_config color.grep.function         normal &&
1619        test_config color.grep.linenumber       normal &&
1620        test_config color.grep.matchContext     normal &&
1621        test_config color.grep.matchSelected    red &&
1622        test_config color.grep.selected         normal &&
1623        test_config color.grep.separator        normal &&
1624
1625        git grep --color=always -p -C3 -e int --and -e Hello --no-index hello.c |
1626        test_decode_color >actual &&
1627        test_cmp expected actual
1628'
1629
1630test_expect_success 'grep can find things only in the work tree' '
1631        : >work-tree-only &&
1632        git add work-tree-only &&
1633        test_when_finished "git rm -f work-tree-only" &&
1634        echo "find in work tree" >work-tree-only &&
1635        git grep --quiet "find in work tree" &&
1636        test_must_fail git grep --quiet --cached "find in work tree" &&
1637        test_must_fail git grep --quiet "find in work tree" HEAD
1638'
1639
1640test_expect_success 'grep can find things only in the work tree (i-t-a)' '
1641        echo "intend to add this" >intend-to-add &&
1642        git add -N intend-to-add &&
1643        test_when_finished "git rm -f intend-to-add" &&
1644        git grep --quiet "intend to add this" &&
1645        test_must_fail git grep --quiet --cached "intend to add this" &&
1646        test_must_fail git grep --quiet "intend to add this" HEAD
1647'
1648
1649test_expect_success 'grep does not search work tree with assume unchanged' '
1650        echo "intend to add this" >intend-to-add &&
1651        git add -N intend-to-add &&
1652        git update-index --assume-unchanged intend-to-add &&
1653        test_when_finished "git rm -f intend-to-add" &&
1654        test_must_fail git grep --quiet "intend to add this" &&
1655        test_must_fail git grep --quiet --cached "intend to add this" &&
1656        test_must_fail git grep --quiet "intend to add this" HEAD
1657'
1658
1659test_expect_success 'grep can find things only in the index' '
1660        echo "only in the index" >cache-this &&
1661        git add cache-this &&
1662        rm cache-this &&
1663        test_when_finished "git rm --cached cache-this" &&
1664        test_must_fail git grep --quiet "only in the index" &&
1665        git grep --quiet --cached "only in the index" &&
1666        test_must_fail git grep --quiet "only in the index" HEAD
1667'
1668
1669test_expect_success 'grep does not report i-t-a with -L --cached' '
1670        echo "intend to add this" >intend-to-add &&
1671        git add -N intend-to-add &&
1672        test_when_finished "git rm -f intend-to-add" &&
1673        git ls-files | grep -v "^intend-to-add\$" >expected &&
1674        git grep -L --cached "nonexistent_string" >actual &&
1675        test_cmp expected actual
1676'
1677
1678test_expect_success 'grep does not report i-t-a and assume unchanged with -L' '
1679        echo "intend to add this" >intend-to-add-assume-unchanged &&
1680        git add -N intend-to-add-assume-unchanged &&
1681        test_when_finished "git rm -f intend-to-add-assume-unchanged" &&
1682        git update-index --assume-unchanged intend-to-add-assume-unchanged &&
1683        git ls-files | grep -v "^intend-to-add-assume-unchanged\$" >expected &&
1684        git grep -L "nonexistent_string" >actual &&
1685        test_cmp expected actual
1686'
1687
1688test_done