t / t7064-wtstatus-pv2.shon commit status: add status.aheadbehind setting (06b324c)
   1#!/bin/sh
   2
   3test_description='git status --porcelain=v2
   4
   5This test exercises porcelain V2 output for git status.'
   6
   7
   8. ./test-lib.sh
   9
  10
  11test_expect_success setup '
  12        test_tick &&
  13        git config core.autocrlf false &&
  14        echo x >file_x &&
  15        echo y >file_y &&
  16        echo z >file_z &&
  17        mkdir dir1 &&
  18        echo a >dir1/file_a &&
  19        echo b >dir1/file_b
  20'
  21
  22test_expect_success 'before initial commit, nothing added, only untracked' '
  23        cat >expect <<-EOF &&
  24        # branch.oid (initial)
  25        # branch.head master
  26        ? actual
  27        ? dir1/
  28        ? expect
  29        ? file_x
  30        ? file_y
  31        ? file_z
  32        EOF
  33
  34        git status --porcelain=v2 --branch --untracked-files=normal >actual &&
  35        test_cmp expect actual
  36'
  37
  38test_expect_success 'before initial commit, things added' '
  39        git add file_x file_y file_z dir1 &&
  40        OID_A=$(git hash-object -t blob -- dir1/file_a) &&
  41        OID_B=$(git hash-object -t blob -- dir1/file_b) &&
  42        OID_X=$(git hash-object -t blob -- file_x) &&
  43        OID_Y=$(git hash-object -t blob -- file_y) &&
  44        OID_Z=$(git hash-object -t blob -- file_z) &&
  45
  46        cat >expect <<-EOF &&
  47        # branch.oid (initial)
  48        # branch.head master
  49        1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a
  50        1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b
  51        1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x
  52        1 A. N... 000000 100644 100644 $ZERO_OID $OID_Y file_y
  53        1 A. N... 000000 100644 100644 $ZERO_OID $OID_Z file_z
  54        ? actual
  55        ? expect
  56        EOF
  57
  58        git status --porcelain=v2 --branch --untracked-files=all >actual &&
  59        test_cmp expect actual
  60'
  61
  62test_expect_success 'before initial commit, things added (-z)' '
  63        lf_to_nul >expect <<-EOF &&
  64        # branch.oid (initial)
  65        # branch.head master
  66        1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a
  67        1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b
  68        1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x
  69        1 A. N... 000000 100644 100644 $ZERO_OID $OID_Y file_y
  70        1 A. N... 000000 100644 100644 $ZERO_OID $OID_Z file_z
  71        ? actual
  72        ? expect
  73        EOF
  74
  75        git status -z --porcelain=v2 --branch --untracked-files=all >actual &&
  76        test_cmp expect actual
  77'
  78
  79test_expect_success 'make first commit, comfirm HEAD oid and branch' '
  80        git commit -m initial &&
  81        H0=$(git rev-parse HEAD) &&
  82        cat >expect <<-EOF &&
  83        # branch.oid $H0
  84        # branch.head master
  85        ? actual
  86        ? expect
  87        EOF
  88
  89        git status --porcelain=v2 --branch --untracked-files=all >actual &&
  90        test_cmp expect actual
  91'
  92
  93test_expect_success 'after first commit, create unstaged changes' '
  94        echo x >>file_x &&
  95        OID_X1=$(git hash-object -t blob -- file_x) &&
  96        rm file_z &&
  97        H0=$(git rev-parse HEAD) &&
  98
  99        cat >expect <<-EOF &&
 100        # branch.oid $H0
 101        # branch.head master
 102        1 .M N... 100644 100644 100644 $OID_X $OID_X file_x
 103        1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z
 104        ? actual
 105        ? expect
 106        EOF
 107
 108        git status --porcelain=v2 --branch --untracked-files=all >actual &&
 109        test_cmp expect actual
 110'
 111
 112test_expect_success 'after first commit but omit untracked files and branch' '
 113        cat >expect <<-EOF &&
 114        1 .M N... 100644 100644 100644 $OID_X $OID_X file_x
 115        1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z
 116        EOF
 117
 118        git status --porcelain=v2 --untracked-files=no >actual &&
 119        test_cmp expect actual
 120'
 121
 122test_expect_success 'after first commit, stage existing changes' '
 123        git add file_x &&
 124        git rm file_z &&
 125        H0=$(git rev-parse HEAD) &&
 126
 127        cat >expect <<-EOF &&
 128        # branch.oid $H0
 129        # branch.head master
 130        1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
 131        1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
 132        ? actual
 133        ? expect
 134        EOF
 135
 136        git status --porcelain=v2 --branch --untracked-files=all >actual &&
 137        test_cmp expect actual
 138'
 139
 140test_expect_success 'rename causes 2 path lines' '
 141        git mv file_y renamed_y &&
 142        H0=$(git rev-parse HEAD) &&
 143
 144        q_to_tab >expect <<-EOF &&
 145        # branch.oid $H0
 146        # branch.head master
 147        1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
 148        1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
 149        2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
 150        ? actual
 151        ? expect
 152        EOF
 153
 154        git status --porcelain=v2 --branch --untracked-files=all >actual &&
 155        test_cmp expect actual
 156'
 157
 158test_expect_success 'rename causes 2 path lines (-z)' '
 159        H0=$(git rev-parse HEAD) &&
 160
 161        ## Lines use NUL path separator and line terminator, so double transform here.
 162        q_to_nul <<-EOF | lf_to_nul >expect &&
 163        # branch.oid $H0
 164        # branch.head master
 165        1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
 166        1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
 167        2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
 168        ? actual
 169        ? expect
 170        EOF
 171
 172        git status --porcelain=v2 --branch --untracked-files=all -z >actual &&
 173        test_cmp expect actual
 174'
 175
 176test_expect_success 'make second commit, confirm clean and new HEAD oid' '
 177        git commit -m second &&
 178        H1=$(git rev-parse HEAD) &&
 179
 180        cat >expect <<-EOF &&
 181        # branch.oid $H1
 182        # branch.head master
 183        ? actual
 184        ? expect
 185        EOF
 186
 187        git status --porcelain=v2 --branch --untracked-files=all >actual &&
 188        test_cmp expect actual
 189'
 190
 191test_expect_success 'confirm ignored files are not printed' '
 192        test_when_finished "rm -f x.ign .gitignore" &&
 193        echo x.ign >.gitignore &&
 194        echo "ignore me" >x.ign &&
 195
 196        cat >expect <<-EOF &&
 197        ? .gitignore
 198        ? actual
 199        ? expect
 200        EOF
 201
 202        git status --porcelain=v2 --untracked-files=all >actual &&
 203        test_cmp expect actual
 204'
 205
 206test_expect_success 'ignored files are printed with --ignored' '
 207        test_when_finished "rm -f x.ign .gitignore" &&
 208        echo x.ign >.gitignore &&
 209        echo "ignore me" >x.ign &&
 210
 211        cat >expect <<-EOF &&
 212        ? .gitignore
 213        ? actual
 214        ? expect
 215        ! x.ign
 216        EOF
 217
 218        git status --porcelain=v2 --ignored --untracked-files=all >actual &&
 219        test_cmp expect actual
 220'
 221
 222test_expect_success 'create and commit permanent ignore file' '
 223        cat >.gitignore <<-EOF &&
 224        actual*
 225        expect*
 226        EOF
 227
 228        git add .gitignore &&
 229        git commit -m ignore_trash &&
 230        H1=$(git rev-parse HEAD) &&
 231
 232        cat >expect <<-EOF &&
 233        # branch.oid $H1
 234        # branch.head master
 235        EOF
 236
 237        git status --porcelain=v2 --branch >actual &&
 238        test_cmp expect actual
 239'
 240
 241test_expect_success 'verify --intent-to-add output' '
 242        test_when_finished "git rm -f intent1.add intent2.add" &&
 243        touch intent1.add &&
 244        echo test >intent2.add &&
 245
 246        git add --intent-to-add intent1.add intent2.add &&
 247
 248        cat >expect <<-EOF &&
 249        1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID intent1.add
 250        1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID intent2.add
 251        EOF
 252
 253        git status --porcelain=v2 >actual &&
 254        test_cmp expect actual
 255'
 256
 257test_expect_success 'verify AA (add-add) conflict' '
 258        test_when_finished "git reset --hard" &&
 259
 260        git branch AA_A master &&
 261        git checkout AA_A &&
 262        echo "Branch AA_A" >conflict.txt &&
 263        OID_AA_A=$(git hash-object -t blob -- conflict.txt) &&
 264        git add conflict.txt &&
 265        git commit -m "branch aa_a" &&
 266
 267        git branch AA_B master &&
 268        git checkout AA_B &&
 269        echo "Branch AA_B" >conflict.txt &&
 270        OID_AA_B=$(git hash-object -t blob -- conflict.txt) &&
 271        git add conflict.txt &&
 272        git commit -m "branch aa_b" &&
 273
 274        git branch AA_M AA_B &&
 275        git checkout AA_M &&
 276        test_must_fail git merge AA_A &&
 277
 278        HM=$(git rev-parse HEAD) &&
 279
 280        cat >expect <<-EOF &&
 281        # branch.oid $HM
 282        # branch.head AA_M
 283        u AA N... 000000 100644 100644 100644 $ZERO_OID $OID_AA_B $OID_AA_A conflict.txt
 284        EOF
 285
 286        git status --porcelain=v2 --branch --untracked-files=all >actual &&
 287        test_cmp expect actual
 288'
 289
 290test_expect_success 'verify UU (edit-edit) conflict' '
 291        test_when_finished "git reset --hard" &&
 292
 293        git branch UU_ANC master &&
 294        git checkout UU_ANC &&
 295        echo "Ancestor" >conflict.txt &&
 296        OID_UU_ANC=$(git hash-object -t blob -- conflict.txt) &&
 297        git add conflict.txt &&
 298        git commit -m "UU_ANC" &&
 299
 300        git branch UU_A UU_ANC &&
 301        git checkout UU_A &&
 302        echo "Branch UU_A" >conflict.txt &&
 303        OID_UU_A=$(git hash-object -t blob -- conflict.txt) &&
 304        git add conflict.txt &&
 305        git commit -m "branch uu_a" &&
 306
 307        git branch UU_B UU_ANC &&
 308        git checkout UU_B &&
 309        echo "Branch UU_B" >conflict.txt &&
 310        OID_UU_B=$(git hash-object -t blob -- conflict.txt) &&
 311        git add conflict.txt &&
 312        git commit -m "branch uu_b" &&
 313
 314        git branch UU_M UU_B &&
 315        git checkout UU_M &&
 316        test_must_fail git merge UU_A &&
 317
 318        HM=$(git rev-parse HEAD) &&
 319
 320        cat >expect <<-EOF &&
 321        # branch.oid $HM
 322        # branch.head UU_M
 323        u UU N... 100644 100644 100644 100644 $OID_UU_ANC $OID_UU_B $OID_UU_A conflict.txt
 324        EOF
 325
 326        git status --porcelain=v2 --branch --untracked-files=all >actual &&
 327        test_cmp expect actual
 328'
 329
 330test_expect_success 'verify upstream fields in branch header' '
 331        git checkout master &&
 332        test_when_finished "rm -rf sub_repo" &&
 333        git clone . sub_repo &&
 334        (
 335                ## Confirm local master tracks remote master.
 336                cd sub_repo &&
 337                HUF=$(git rev-parse HEAD) &&
 338
 339                cat >expect <<-EOF &&
 340                # branch.oid $HUF
 341                # branch.head master
 342                # branch.upstream origin/master
 343                # branch.ab +0 -0
 344                EOF
 345
 346                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 347                test_cmp expect actual &&
 348
 349                ## Test ahead/behind.
 350                echo xyz >file_xyz &&
 351                git add file_xyz &&
 352                git commit -m xyz &&
 353
 354                HUF=$(git rev-parse HEAD) &&
 355
 356                cat >expect <<-EOF &&
 357                # branch.oid $HUF
 358                # branch.head master
 359                # branch.upstream origin/master
 360                # branch.ab +1 -0
 361                EOF
 362
 363                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 364                test_cmp expect actual &&
 365
 366                ## Repeat the above but without --branch.
 367                git status --porcelain=v2 --untracked-files=all >actual &&
 368                test_must_be_empty actual &&
 369
 370                ## Test upstream-gone case. Fake this by pointing origin/master at
 371                ## a non-existing commit.
 372                OLD=$(git rev-parse origin/master) &&
 373                NEW=$ZERO_OID &&
 374                mv .git/packed-refs .git/old-packed-refs &&
 375                sed "s/$OLD/$NEW/g" <.git/old-packed-refs >.git/packed-refs &&
 376
 377                HUF=$(git rev-parse HEAD) &&
 378
 379                cat >expect <<-EOF &&
 380                # branch.oid $HUF
 381                # branch.head master
 382                # branch.upstream origin/master
 383                EOF
 384
 385                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 386                test_cmp expect actual
 387        )
 388'
 389
 390test_expect_success 'verify --[no-]ahead-behind with V2 format' '
 391        git checkout master &&
 392        test_when_finished "rm -rf sub_repo" &&
 393        git clone . sub_repo &&
 394        (
 395                ## Confirm local master tracks remote master.
 396                cd sub_repo &&
 397                HUF=$(git rev-parse HEAD) &&
 398
 399                # Confirm --no-ahead-behind reports traditional branch.ab with 0/0 for equal branches.
 400                cat >expect <<-EOF &&
 401                # branch.oid $HUF
 402                # branch.head master
 403                # branch.upstream origin/master
 404                # branch.ab +0 -0
 405                EOF
 406
 407                git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
 408                test_cmp expect actual &&
 409
 410                # Confirm --ahead-behind reports traditional branch.ab with 0/0.
 411                cat >expect <<-EOF &&
 412                # branch.oid $HUF
 413                # branch.head master
 414                # branch.upstream origin/master
 415                # branch.ab +0 -0
 416                EOF
 417
 418                git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
 419                test_cmp expect actual &&
 420
 421                ## Test non-equal ahead/behind.
 422                echo xyz >file_xyz &&
 423                git add file_xyz &&
 424                git commit -m xyz &&
 425
 426                HUF=$(git rev-parse HEAD) &&
 427
 428                # Confirm --no-ahead-behind reports branch.ab with ?/? for non-equal branches.
 429                cat >expect <<-EOF &&
 430                # branch.oid $HUF
 431                # branch.head master
 432                # branch.upstream origin/master
 433                # branch.ab +? -?
 434                EOF
 435
 436                git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
 437                test_cmp expect actual &&
 438
 439                # Confirmat that "status.aheadbehind" works on V2 format.
 440                git -c status.aheadbehind=false status --porcelain=v2 --branch --untracked-files=all >actual &&
 441                test_cmp expect actual &&
 442
 443                # Confirm --ahead-behind reports traditional branch.ab with 1/0.
 444                cat >expect <<-EOF &&
 445                # branch.oid $HUF
 446                # branch.head master
 447                # branch.upstream origin/master
 448                # branch.ab +1 -0
 449                EOF
 450
 451                git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
 452                test_cmp expect actual
 453        )
 454'
 455
 456test_expect_success 'create and add submodule, submodule appears clean (A. S...)' '
 457        git checkout master &&
 458        git clone . sub_repo &&
 459        git clone . super_repo &&
 460        (       cd super_repo &&
 461                git submodule add ../sub_repo sub1 &&
 462
 463                ## Confirm stage/add of clean submodule.
 464                HMOD=$(git hash-object -t blob -- .gitmodules) &&
 465                HSUP=$(git rev-parse HEAD) &&
 466                HSUB=$HSUP &&
 467
 468                cat >expect <<-EOF &&
 469                # branch.oid $HSUP
 470                # branch.head master
 471                # branch.upstream origin/master
 472                # branch.ab +0 -0
 473                1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
 474                1 A. S... 000000 160000 160000 $ZERO_OID $HSUB sub1
 475                EOF
 476
 477                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 478                test_cmp expect actual
 479        )
 480'
 481
 482test_expect_success 'untracked changes in added submodule (AM S..U)' '
 483        (       cd super_repo &&
 484                ## create untracked file in the submodule.
 485                (       cd sub1 &&
 486                        echo "xxxx" >file_in_sub
 487                ) &&
 488
 489                HMOD=$(git hash-object -t blob -- .gitmodules) &&
 490                HSUP=$(git rev-parse HEAD) &&
 491                HSUB=$HSUP &&
 492
 493                cat >expect <<-EOF &&
 494                # branch.oid $HSUP
 495                # branch.head master
 496                # branch.upstream origin/master
 497                # branch.ab +0 -0
 498                1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
 499                1 AM S..U 000000 160000 160000 $ZERO_OID $HSUB sub1
 500                EOF
 501
 502                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 503                test_cmp expect actual
 504        )
 505'
 506
 507test_expect_success 'staged changes in added submodule (AM S.M.)' '
 508        (       cd super_repo &&
 509                ## stage the changes in the submodule.
 510                (       cd sub1 &&
 511                        git add file_in_sub
 512                ) &&
 513
 514                HMOD=$(git hash-object -t blob -- .gitmodules) &&
 515                HSUP=$(git rev-parse HEAD) &&
 516                HSUB=$HSUP &&
 517
 518                cat >expect <<-EOF &&
 519                # branch.oid $HSUP
 520                # branch.head master
 521                # branch.upstream origin/master
 522                # branch.ab +0 -0
 523                1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
 524                1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1
 525                EOF
 526
 527                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 528                test_cmp expect actual
 529        )
 530'
 531
 532test_expect_success 'staged and unstaged changes in added (AM S.M.)' '
 533        (       cd super_repo &&
 534                (       cd sub1 &&
 535                        ## make additional unstaged changes (on the same file) in the submodule.
 536                        ## This does not cause us to get S.MU (because the submodule does not report
 537                        ## a "?" line for the unstaged changes).
 538                        echo "more changes" >>file_in_sub
 539                ) &&
 540
 541                HMOD=$(git hash-object -t blob -- .gitmodules) &&
 542                HSUP=$(git rev-parse HEAD) &&
 543                HSUB=$HSUP &&
 544
 545                cat >expect <<-EOF &&
 546                # branch.oid $HSUP
 547                # branch.head master
 548                # branch.upstream origin/master
 549                # branch.ab +0 -0
 550                1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
 551                1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1
 552                EOF
 553
 554                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 555                test_cmp expect actual
 556        )
 557'
 558
 559test_expect_success 'staged and untracked changes in added submodule (AM S.MU)' '
 560        (       cd super_repo &&
 561                (       cd sub1 &&
 562                        ## stage new changes in tracked file.
 563                        git add file_in_sub &&
 564                        ## create new untracked file.
 565                        echo "yyyy" >>another_file_in_sub
 566                ) &&
 567
 568                HMOD=$(git hash-object -t blob -- .gitmodules) &&
 569                HSUP=$(git rev-parse HEAD) &&
 570                HSUB=$HSUP &&
 571
 572                cat >expect <<-EOF &&
 573                # branch.oid $HSUP
 574                # branch.head master
 575                # branch.upstream origin/master
 576                # branch.ab +0 -0
 577                1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
 578                1 AM S.MU 000000 160000 160000 $ZERO_OID $HSUB sub1
 579                EOF
 580
 581                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 582                test_cmp expect actual
 583        )
 584'
 585
 586test_expect_success 'commit within the submodule appears as new commit in super (AM SC..)' '
 587        (       cd super_repo &&
 588                (       cd sub1 &&
 589                        ## Make a new commit in the submodule.
 590                        git add file_in_sub &&
 591                        rm -f another_file_in_sub &&
 592                        git commit -m "new commit"
 593                ) &&
 594
 595                HMOD=$(git hash-object -t blob -- .gitmodules) &&
 596                HSUP=$(git rev-parse HEAD) &&
 597                HSUB=$HSUP &&
 598
 599                cat >expect <<-EOF &&
 600                # branch.oid $HSUP
 601                # branch.head master
 602                # branch.upstream origin/master
 603                # branch.ab +0 -0
 604                1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
 605                1 AM SC.. 000000 160000 160000 $ZERO_OID $HSUB sub1
 606                EOF
 607
 608                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 609                test_cmp expect actual
 610        )
 611'
 612
 613test_expect_success 'stage submodule in super and commit' '
 614        (       cd super_repo &&
 615                ## Stage the new submodule commit in the super.
 616                git add sub1 &&
 617                ## Commit the super so that the sub no longer appears as added.
 618                git commit -m "super commit" &&
 619
 620                HSUP=$(git rev-parse HEAD) &&
 621
 622                cat >expect <<-EOF &&
 623                # branch.oid $HSUP
 624                # branch.head master
 625                # branch.upstream origin/master
 626                # branch.ab +1 -0
 627                EOF
 628
 629                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 630                test_cmp expect actual
 631        )
 632'
 633
 634test_expect_success 'make unstaged changes in existing submodule (.M S.M.)' '
 635        (       cd super_repo &&
 636                (       cd sub1 &&
 637                        echo "zzzz" >>file_in_sub
 638                ) &&
 639
 640                HSUP=$(git rev-parse HEAD) &&
 641                HSUB=$(cd sub1 && git rev-parse HEAD) &&
 642
 643                cat >expect <<-EOF &&
 644                # branch.oid $HSUP
 645                # branch.head master
 646                # branch.upstream origin/master
 647                # branch.ab +1 -0
 648                1 .M S.M. 160000 160000 160000 $HSUB $HSUB sub1
 649                EOF
 650
 651                git status --porcelain=v2 --branch --untracked-files=all >actual &&
 652                test_cmp expect actual
 653        )
 654'
 655
 656test_done