e5f167a06eeb4c14d779021e003f3833c227b73d
   1#!/bin/sh
   2
   3test_description='recursive merge corner cases involving criss-cross merges'
   4
   5. ./test-lib.sh
   6
   7get_clean_checkout () {
   8        git reset --hard &&
   9        git clean -fdqx &&
  10        git checkout "$1"
  11}
  12
  13#
  14#  L1  L2
  15#   o---o
  16#  / \ / \
  17# o   X   ?
  18#  \ / \ /
  19#   o---o
  20#  R1  R2
  21#
  22
  23test_expect_success 'setup basic criss-cross + rename with no modifications' '
  24        test_create_repo basic-rename &&
  25        (
  26                cd basic-rename &&
  27
  28                ten="0 1 2 3 4 5 6 7 8 9" &&
  29                for i in $ten
  30                do
  31                        echo line $i in a sample file
  32                done >one &&
  33                for i in $ten
  34                do
  35                        echo line $i in another sample file
  36                done >two &&
  37                git add one two &&
  38                test_tick && git commit -m initial &&
  39
  40                git branch L1 &&
  41                git checkout -b R1 &&
  42                git mv one three &&
  43                test_tick && git commit -m R1 &&
  44
  45                git checkout L1 &&
  46                git mv two three &&
  47                test_tick && git commit -m L1 &&
  48
  49                git checkout L1^0 &&
  50                test_tick && git merge -s ours R1 &&
  51                git tag L2 &&
  52
  53                git checkout R1^0 &&
  54                test_tick && git merge -s ours L1 &&
  55                git tag R2
  56        )
  57'
  58
  59test_expect_success 'merge simple rename+criss-cross with no modifications' '
  60        (
  61                cd basic-rename &&
  62
  63                git reset --hard &&
  64                git checkout L2^0 &&
  65
  66                test_must_fail git merge -s recursive R2^0 &&
  67
  68                git ls-files -s >out &&
  69                test_line_count = 2 out &&
  70                git ls-files -u >out &&
  71                test_line_count = 2 out &&
  72                git ls-files -o >out &&
  73                test_line_count = 3 out &&
  74
  75                git rev-parse >expect       \
  76                        L2:three   R2:three \
  77                        L2:three   R2:three &&
  78                git rev-parse   >actual     \
  79                        :2:three   :3:three &&
  80                git hash-object >>actual    \
  81                        three~HEAD three~R2^0
  82                test_cmp expect actual
  83        )
  84'
  85
  86#
  87# Same as before, but modify L1 slightly:
  88#
  89#  L1m L2
  90#   o---o
  91#  / \ / \
  92# o   X   ?
  93#  \ / \ /
  94#   o---o
  95#  R1  R2
  96#
  97
  98test_expect_success 'setup criss-cross + rename merges with basic modification' '
  99        test_create_repo rename-modify &&
 100        (
 101                cd rename-modify &&
 102
 103                ten="0 1 2 3 4 5 6 7 8 9" &&
 104                for i in $ten
 105                do
 106                        echo line $i in a sample file
 107                done >one &&
 108                for i in $ten
 109                do
 110                        echo line $i in another sample file
 111                done >two &&
 112                git add one two &&
 113                test_tick && git commit -m initial &&
 114
 115                git branch L1 &&
 116                git checkout -b R1 &&
 117                git mv one three &&
 118                echo more >>two &&
 119                git add two &&
 120                test_tick && git commit -m R1 &&
 121
 122                git checkout L1 &&
 123                git mv two three &&
 124                test_tick && git commit -m L1 &&
 125
 126                git checkout L1^0 &&
 127                test_tick && git merge -s ours R1 &&
 128                git tag L2 &&
 129
 130                git checkout R1^0 &&
 131                test_tick && git merge -s ours L1 &&
 132                git tag R2
 133        )
 134'
 135
 136test_expect_success 'merge criss-cross + rename merges with basic modification' '
 137        (
 138                cd rename-modify &&
 139
 140                git checkout L2^0 &&
 141
 142                test_must_fail git merge -s recursive R2^0 &&
 143
 144                git ls-files -s >out &&
 145                test_line_count = 2 out &&
 146                git ls-files -u >out &&
 147                test_line_count = 2 out &&
 148                git ls-files -o >out &&
 149                test_line_count = 3 out &&
 150
 151                git rev-parse >expect       \
 152                        L2:three   R2:three \
 153                        L2:three   R2:three &&
 154                git rev-parse   >actual     \
 155                        :2:three   :3:three &&
 156                git hash-object >>actual    \
 157                        three~HEAD three~R2^0
 158                test_cmp expect actual
 159        )
 160'
 161
 162#
 163# For the next test, we start with three commits in two lines of development
 164# which setup a rename/add conflict:
 165#   Commit A: File 'a' exists
 166#   Commit B: Rename 'a' -> 'new_a'
 167#   Commit C: Modify 'a', create different 'new_a'
 168# Later, two different people merge and resolve differently:
 169#   Commit D: Merge B & C, ignoring separately created 'new_a'
 170#   Commit E: Merge B & C making use of some piece of secondary 'new_a'
 171# Finally, someone goes to merge D & E.  Does git detect the conflict?
 172#
 173#      B   D
 174#      o---o
 175#     / \ / \
 176#  A o   X   ? F
 177#     \ / \ /
 178#      o---o
 179#      C   E
 180#
 181
 182test_expect_success 'setup differently handled merges of rename/add conflict' '
 183        test_create_repo rename-add &&
 184        (
 185                cd rename-add &&
 186
 187                printf "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" >a &&
 188                git add a &&
 189                test_tick && git commit -m A &&
 190
 191                git branch B &&
 192                git checkout -b C &&
 193                echo 10 >>a &&
 194                echo "other content" >>new_a &&
 195                git add a new_a &&
 196                test_tick && git commit -m C &&
 197
 198                git checkout B &&
 199                git mv a new_a &&
 200                test_tick && git commit -m B &&
 201
 202                git checkout B^0 &&
 203                test_must_fail git merge C &&
 204                git clean -f &&
 205                test_tick && git commit -m D &&
 206                git tag D &&
 207
 208                git checkout C^0 &&
 209                test_must_fail git merge B &&
 210                rm new_a~HEAD new_a &&
 211                printf "Incorrectly merged content" >>new_a &&
 212                git add -u &&
 213                test_tick && git commit -m E &&
 214                git tag E
 215        )
 216'
 217
 218test_expect_success 'git detects differently handled merges conflict' '
 219        (
 220                cd rename-add &&
 221
 222                git checkout D^0 &&
 223
 224                test_must_fail git merge -s recursive E^0 &&
 225
 226                git ls-files -s >out &&
 227                test_line_count = 3 out &&
 228                git ls-files -u >out &&
 229                test_line_count = 3 out &&
 230                git ls-files -o >out &&
 231                test_line_count = 1 out &&
 232
 233                git rev-parse >expect       \
 234                        D:new_a  E:new_a &&
 235                git rev-parse   >actual     \
 236                        :2:new_a :3:new_a &&
 237                test_cmp expect actual
 238
 239                git cat-file -p B:new_a >ours &&
 240                git cat-file -p C:new_a >theirs &&
 241                >empty &&
 242                test_must_fail git merge-file \
 243                        -L "Temporary merge branch 2" \
 244                        -L "" \
 245                        -L "Temporary merge branch 1" \
 246                        ours empty theirs &&
 247                sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect &&
 248                git cat-file -p :1:new_a >actual &&
 249                test_cmp expect actual
 250        )
 251'
 252
 253#
 254# criss-cross + modify/delete:
 255#
 256#      B   D
 257#      o---o
 258#     / \ / \
 259#  A o   X   ? F
 260#     \ / \ /
 261#      o---o
 262#      C   E
 263#
 264#   Commit A: file with contents 'A\n'
 265#   Commit B: file with contents 'B\n'
 266#   Commit C: file not present
 267#   Commit D: file with contents 'B\n'
 268#   Commit E: file not present
 269#
 270# Merging commits D & E should result in modify/delete conflict.
 271
 272test_expect_success 'setup criss-cross + modify/delete resolved differently' '
 273        test_create_repo modify-delete &&
 274        (
 275                cd modify-delete &&
 276
 277                echo A >file &&
 278                git add file &&
 279                test_tick &&
 280                git commit -m A &&
 281
 282                git branch B &&
 283                git checkout -b C &&
 284                git rm file &&
 285                test_tick &&
 286                git commit -m C &&
 287
 288                git checkout B &&
 289                echo B >file &&
 290                git add file &&
 291                test_tick &&
 292                git commit -m B &&
 293
 294                git checkout B^0 &&
 295                test_must_fail git merge C &&
 296                echo B >file &&
 297                git add file &&
 298                test_tick &&
 299                git commit -m D &&
 300                git tag D &&
 301
 302                git checkout C^0 &&
 303                test_must_fail git merge B &&
 304                git rm file &&
 305                test_tick &&
 306                git commit -m E &&
 307                git tag E
 308        )
 309'
 310
 311test_expect_success 'git detects conflict merging criss-cross+modify/delete' '
 312        (
 313                cd modify-delete &&
 314
 315                git checkout D^0 &&
 316
 317                test_must_fail git merge -s recursive E^0 &&
 318
 319                git ls-files -s >out &&
 320                test_line_count = 2 out &&
 321                git ls-files -u >out &&
 322                test_line_count = 2 out &&
 323
 324                git rev-parse >expect       \
 325                        master:file  B:file &&
 326                git rev-parse   >actual      \
 327                        :1:file      :2:file &&
 328                test_cmp expect actual
 329        )
 330'
 331
 332test_expect_success 'git detects conflict merging criss-cross+modify/delete, reverse direction' '
 333        (
 334                cd modify-delete &&
 335
 336                git reset --hard &&
 337                git checkout E^0 &&
 338
 339                test_must_fail git merge -s recursive D^0 &&
 340
 341                git ls-files -s >out &&
 342                test_line_count = 2 out &&
 343                git ls-files -u >out &&
 344                test_line_count = 2 out &&
 345
 346                git rev-parse >expect       \
 347                        master:file  B:file &&
 348                git rev-parse   >actual      \
 349                        :1:file      :3:file &&
 350                test_cmp expect actual
 351        )
 352'
 353
 354#
 355# criss-cross + d/f conflict via add/add:
 356#   Commit A: Neither file 'a' nor directory 'a/' exists.
 357#   Commit B: Introduce 'a'
 358#   Commit C: Introduce 'a/file'
 359#   Commit D: Merge B & C, keeping 'a' and deleting 'a/'
 360#
 361# Two different later cases:
 362#   Commit E1: Merge B & C, deleting 'a' but keeping 'a/file'
 363#   Commit E2: Merge B & C, deleting 'a' but keeping a slightly modified 'a/file'
 364#
 365#      B   D
 366#      o---o
 367#     / \ / \
 368#  A o   X   ? F
 369#     \ / \ /
 370#      o---o
 371#      C   E1 or E2
 372#
 373# Merging D & E1 requires we first create a virtual merge base X from
 374# merging A & B in memory.  Now, if X could keep both 'a' and 'a/file' in
 375# the index, then the merge of D & E1 could be resolved cleanly with both
 376# 'a' and 'a/file' removed.  Since git does not currently allow creating
 377# such a tree, the best we can do is have X contain both 'a~<unique>' and
 378# 'a/file' resulting in the merge of D and E1 having a rename/delete
 379# conflict for 'a'.  (Although this merge appears to be unsolvable with git
 380# currently, git could do a lot better than it currently does with these
 381# d/f conflicts, which is the purpose of this test.)
 382#
 383# Merge of D & E2 has similar issues for path 'a', but should always result
 384# in a modify/delete conflict for path 'a/file'.
 385#
 386# We run each merge in both directions, to check for directional issues
 387# with D/F conflict handling.
 388#
 389
 390test_expect_success 'setup differently handled merges of directory/file conflict' '
 391        test_create_repo directory-file &&
 392        (
 393                cd directory-file &&
 394
 395                >ignore-me &&
 396                git add ignore-me &&
 397                test_tick &&
 398                git commit -m A &&
 399                git tag A &&
 400
 401                git branch B &&
 402                git checkout -b C &&
 403                mkdir a &&
 404                echo 10 >a/file &&
 405                git add a/file &&
 406                test_tick &&
 407                git commit -m C &&
 408
 409                git checkout B &&
 410                echo 5 >a &&
 411                git add a &&
 412                test_tick &&
 413                git commit -m B &&
 414
 415                git checkout B^0 &&
 416                test_must_fail git merge C &&
 417                git clean -f &&
 418                rm -rf a/ &&
 419                echo 5 >a &&
 420                git add a &&
 421                test_tick &&
 422                git commit -m D &&
 423                git tag D &&
 424
 425                git checkout C^0 &&
 426                test_must_fail git merge B &&
 427                git clean -f &&
 428                git rm --cached a &&
 429                echo 10 >a/file &&
 430                git add a/file &&
 431                test_tick &&
 432                git commit -m E1 &&
 433                git tag E1 &&
 434
 435                git checkout C^0 &&
 436                test_must_fail git merge B &&
 437                git clean -f &&
 438                git rm --cached a &&
 439                printf "10\n11\n" >a/file &&
 440                git add a/file &&
 441                test_tick &&
 442                git commit -m E2 &&
 443                git tag E2
 444        )
 445'
 446
 447test_expect_success 'merge of D & E1 fails but has appropriate contents' '
 448        (
 449                cd directory-file &&
 450
 451                get_clean_checkout D^0 &&
 452
 453                test_must_fail git merge -s recursive E1^0 &&
 454
 455                git ls-files -s >out &&
 456                test_line_count = 2 out &&
 457                git ls-files -u >out &&
 458                test_line_count = 1 out &&
 459                git ls-files -o >out &&
 460                test_line_count = 1 out &&
 461
 462                git rev-parse >expect    \
 463                        A:ignore-me  B:a &&
 464                git rev-parse   >actual   \
 465                        :0:ignore-me :2:a &&
 466                test_cmp expect actual
 467        )
 468'
 469
 470test_expect_success 'merge of E1 & D fails but has appropriate contents' '
 471        (
 472                cd directory-file &&
 473
 474                get_clean_checkout E1^0 &&
 475
 476                test_must_fail git merge -s recursive D^0 &&
 477
 478                git ls-files -s >out &&
 479                test_line_count = 2 out &&
 480                git ls-files -u >out &&
 481                test_line_count = 1 out &&
 482                git ls-files -o >out &&
 483                test_line_count = 1 out &&
 484
 485                git rev-parse >expect    \
 486                        A:ignore-me  B:a &&
 487                git rev-parse   >actual   \
 488                        :0:ignore-me :3:a &&
 489                test_cmp expect actual
 490        )
 491'
 492
 493test_expect_success 'merge of D & E2 fails but has appropriate contents' '
 494        (
 495                cd directory-file &&
 496
 497                get_clean_checkout D^0 &&
 498
 499                test_must_fail git merge -s recursive E2^0 &&
 500
 501                git ls-files -s >out &&
 502                test_line_count = 4 out &&
 503                git ls-files -u >out &&
 504                test_line_count = 3 out &&
 505                git ls-files -o >out &&
 506                test_line_count = 2 out &&
 507
 508                git rev-parse >expect    \
 509                        B:a   E2:a/file  c:a/file   A:ignore-me &&
 510                git rev-parse   >actual   \
 511                        :2:a  :3:a/file  :1:a/file  :0:ignore-me &&
 512                test_cmp expect actual
 513
 514                test_path_is_file a~HEAD
 515        )
 516'
 517
 518test_expect_success 'merge of E2 & D fails but has appropriate contents' '
 519        (
 520                cd directory-file &&
 521
 522                get_clean_checkout E2^0 &&
 523
 524                test_must_fail git merge -s recursive D^0 &&
 525
 526                git ls-files -s >out &&
 527                test_line_count = 4 out &&
 528                git ls-files -u >out &&
 529                test_line_count = 3 out &&
 530                git ls-files -o >out &&
 531                test_line_count = 2 out &&
 532
 533                git rev-parse >expect    \
 534                        B:a   E2:a/file  c:a/file   A:ignore-me &&
 535                git rev-parse   >actual   \
 536                        :3:a  :2:a/file  :1:a/file  :0:ignore-me &&
 537                test_cmp expect actual
 538
 539                test_path_is_file a~D^0
 540        )
 541'
 542
 543#
 544# criss-cross with rename/rename(1to2)/modify followed by
 545# rename/rename(2to1)/modify:
 546#
 547#      B   D
 548#      o---o
 549#     / \ / \
 550#  A o   X   ? F
 551#     \ / \ /
 552#      o---o
 553#      C   E
 554#
 555#   Commit A: new file: a
 556#   Commit B: rename a->b, modifying by adding a line
 557#   Commit C: rename a->c
 558#   Commit D: merge B&C, resolving conflict by keeping contents in newname
 559#   Commit E: merge B&C, resolving conflict similar to D but adding another line
 560#
 561# There is a conflict merging B & C, but one of filename not of file
 562# content.  Whoever created D and E chose specific resolutions for that
 563# conflict resolution.  Now, since: (1) there is no content conflict
 564# merging B & C, (2) D does not modify that merged content further, and (3)
 565# both D & E resolve the name conflict in the same way, the modification to
 566# newname in E should not cause any conflicts when it is merged with D.
 567# (Note that this can be accomplished by having the virtual merge base have
 568# the merged contents of b and c stored in a file named a, which seems like
 569# the most logical choice anyway.)
 570#
 571# Comment from Junio: I do not necessarily agree with the choice "a", but
 572# it feels sound to say "B and C do not agree what the final pathname
 573# should be, but we know this content was derived from the common A:a so we
 574# use one path whose name is arbitrary in the virtual merge base X between
 575# D and E" and then further let the rename detection to notice that that
 576# arbitrary path gets renamed between X-D to "newname" and X-E also to
 577# "newname" to resolve it as both sides renaming it to the same new
 578# name. It is akin to what we do at the content level, i.e. "B and C do not
 579# agree what the final contents should be, so we leave the conflict marker
 580# but that may cancel out at the final merge stage".
 581
 582test_expect_success 'setup rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
 583        test_create_repo rename-squared-squared &&
 584        (
 585                cd rename-squared-squared &&
 586
 587                printf "1\n2\n3\n4\n5\n6\n" >a &&
 588                git add a &&
 589                git commit -m A &&
 590                git tag A &&
 591
 592                git checkout -b B A &&
 593                git mv a b &&
 594                echo 7 >>b &&
 595                git add -u &&
 596                git commit -m B &&
 597
 598                git checkout -b C A &&
 599                git mv a c &&
 600                git commit -m C &&
 601
 602                git checkout -q B^0 &&
 603                git merge --no-commit -s ours C^0 &&
 604                git mv b newname &&
 605                git commit -m "Merge commit C^0 into HEAD" &&
 606                git tag D &&
 607
 608                git checkout -q C^0 &&
 609                git merge --no-commit -s ours B^0 &&
 610                git mv c newname &&
 611                printf "7\n8\n" >>newname &&
 612                git add -u &&
 613                git commit -m "Merge commit B^0 into HEAD" &&
 614                git tag E
 615        )
 616'
 617
 618test_expect_success 'handle rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
 619        (
 620                cd rename-squared-squared &&
 621
 622                git checkout D^0 &&
 623
 624                git merge -s recursive E^0 &&
 625
 626                git ls-files -s >out &&
 627                test_line_count = 1 out &&
 628                git ls-files -u >out &&
 629                test_line_count = 0 out &&
 630                git ls-files -o >out &&
 631                test_line_count = 1 out &&
 632
 633                test $(git rev-parse HEAD:newname) = $(git rev-parse E:newname)
 634        )
 635'
 636
 637#
 638# criss-cross with rename/rename(1to2)/add-source + resolvable modify/modify:
 639#
 640#      B   D
 641#      o---o
 642#     / \ / \
 643#  A o   X   ? F
 644#     \ / \ /
 645#      o---o
 646#      C   E
 647#
 648#   Commit A: new file: a
 649#   Commit B: rename a->b
 650#   Commit C: rename a->c, add different a
 651#   Commit D: merge B&C, keeping b&c and (new) a modified at beginning
 652#   Commit E: merge B&C, keeping b&c and (new) a modified at end
 653#
 654# Merging commits D & E should result in no conflict; doing so correctly
 655# requires getting the virtual merge base (from merging B&C) right, handling
 656# renaming carefully (both in the virtual merge base and later), and getting
 657# content merge handled.
 658
 659test_expect_success 'setup criss-cross + rename/rename/add-source + modify/modify' '
 660        test_create_repo rename-rename-add-source &&
 661        (
 662                cd rename-rename-add-source &&
 663
 664                printf "lots\nof\nwords\nand\ncontent\n" >a &&
 665                git add a &&
 666                git commit -m A &&
 667                git tag A &&
 668
 669                git checkout -b B A &&
 670                git mv a b &&
 671                git commit -m B &&
 672
 673                git checkout -b C A &&
 674                git mv a c &&
 675                printf "2\n3\n4\n5\n6\n7\n" >a &&
 676                git add a &&
 677                git commit -m C &&
 678
 679                git checkout B^0 &&
 680                git merge --no-commit -s ours C^0 &&
 681                git checkout C -- a c &&
 682                mv a old_a &&
 683                echo 1 >a &&
 684                cat old_a >>a &&
 685                rm old_a &&
 686                git add -u &&
 687                git commit -m "Merge commit C^0 into HEAD" &&
 688                git tag D &&
 689
 690                git checkout C^0 &&
 691                git merge --no-commit -s ours B^0 &&
 692                git checkout B -- b &&
 693                echo 8 >>a &&
 694                git add -u &&
 695                git commit -m "Merge commit B^0 into HEAD" &&
 696                git tag E
 697        )
 698'
 699
 700test_expect_failure 'detect rename/rename/add-source for virtual merge-base' '
 701        (
 702                cd rename-rename-add-source &&
 703
 704                git checkout D^0 &&
 705
 706                git merge -s recursive E^0 &&
 707
 708                git ls-files -s >out &&
 709                test_line_count = 3 out &&
 710                git ls-files -u >out &&
 711                test_line_count = 0 out &&
 712                git ls-files -o >out &&
 713                test_line_count = 1 out &&
 714
 715                printf "1\n2\n3\n4\n5\n6\n7\n8\n" >correct &&
 716                git rev-parse >expect \
 717                        A:a   A:a     \
 718                        correct       &&
 719                git rev-parse   >actual  \
 720                        :0:b  :0:c       &&
 721                git hash-object >>actual \
 722                        a                &&
 723                test_cmp expect actual
 724        )
 725'
 726
 727#
 728# criss-cross with rename/rename(1to2)/add-dest + simple modify:
 729#
 730#      B   D
 731#      o---o
 732#     / \ / \
 733#  A o   X   ? F
 734#     \ / \ /
 735#      o---o
 736#      C   E
 737#
 738#   Commit A: new file: a
 739#   Commit B: rename a->b, add c
 740#   Commit C: rename a->c
 741#   Commit D: merge B&C, keeping A:a and B:c
 742#   Commit E: merge B&C, keeping A:a and slightly modified c from B
 743#
 744# Merging commits D & E should result in no conflict.  The virtual merge
 745# base of B & C needs to not delete B:c for that to work, though...
 746
 747test_expect_success 'setup criss-cross+rename/rename/add-dest + simple modify' '
 748        test_create_repo rename-rename-add-dest &&
 749        (
 750                cd rename-rename-add-dest &&
 751
 752                >a &&
 753                git add a &&
 754                git commit -m A &&
 755                git tag A &&
 756
 757                git checkout -b B A &&
 758                git mv a b &&
 759                printf "1\n2\n3\n4\n5\n6\n7\n" >c &&
 760                git add c &&
 761                git commit -m B &&
 762
 763                git checkout -b C A &&
 764                git mv a c &&
 765                git commit -m C &&
 766
 767                git checkout B^0 &&
 768                git merge --no-commit -s ours C^0 &&
 769                git mv b a &&
 770                git commit -m "D is like B but renames b back to a" &&
 771                git tag D &&
 772
 773                git checkout B^0 &&
 774                git merge --no-commit -s ours C^0 &&
 775                git mv b a &&
 776                echo 8 >>c &&
 777                git add c &&
 778                git commit -m "E like D but has mod in c" &&
 779                git tag E
 780        )
 781'
 782
 783test_expect_success 'virtual merge base handles rename/rename(1to2)/add-dest' '
 784        (
 785                cd rename-rename-add-dest &&
 786
 787                git checkout D^0 &&
 788
 789                git merge -s recursive E^0 &&
 790
 791                git ls-files -s >out &&
 792                test_line_count = 2 out &&
 793                git ls-files -u >out &&
 794                test_line_count = 0 out &&
 795                git ls-files -o >out &&
 796                test_line_count = 1 out &&
 797
 798                git rev-parse >expect \
 799                        A:a   E:c     &&
 800                git rev-parse   >actual \
 801                        :0:a  :0:c      &&
 802                test_cmp expect actual
 803        )
 804'
 805
 806test_done