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