t / t6046-merge-skip-unneeded-updates.shon commit t5552: suppress upload-pack trace output (b6e7fc4)
   1#!/bin/sh
   2
   3test_description="merge cases"
   4
   5# The setup for all of them, pictorially, is:
   6#
   7#      A
   8#      o
   9#     / \
  10#  O o   ?
  11#     \ /
  12#      o
  13#      B
  14#
  15# To help make it easier to follow the flow of tests, they have been
  16# divided into sections and each test will start with a quick explanation
  17# of what commits O, A, and B contain.
  18#
  19# Notation:
  20#    z/{b,c}   means  files z/b and z/c both exist
  21#    x/d_1     means  file x/d exists with content d1.  (Purpose of the
  22#                     underscore notation is to differentiate different
  23#                     files that might be renamed into each other's paths.)
  24
  25. ./test-lib.sh
  26
  27
  28###########################################################################
  29# SECTION 1: Cases involving no renames (one side has subset of changes of
  30#            the other side)
  31###########################################################################
  32
  33# Testcase 1a, Changes on A, subset of changes on B
  34#   Commit O: b_1
  35#   Commit A: b_2
  36#   Commit B: b_3
  37#   Expected: b_2
  38
  39test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' '
  40        test_create_repo 1a &&
  41        (
  42                cd 1a &&
  43
  44                test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
  45                git add b &&
  46                test_tick &&
  47                git commit -m "O" &&
  48
  49                git branch O &&
  50                git branch A &&
  51                git branch B &&
  52
  53                git checkout A &&
  54                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
  55                git add b &&
  56                test_tick &&
  57                git commit -m "A" &&
  58
  59                git checkout B &&
  60                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
  61                git add b &&
  62                test_tick &&
  63                git commit -m "B"
  64        )
  65'
  66
  67test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' '
  68        test_when_finished "git -C 1a reset --hard" &&
  69        test_when_finished "git -C 1a clean -fd" &&
  70        (
  71                cd 1a &&
  72
  73                git checkout A^0 &&
  74
  75                test-tool chmtime =31337 b &&
  76                test-tool chmtime -v +0 b >expected-mtime &&
  77
  78                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
  79
  80                test_i18ngrep "Skipped b" out &&
  81                test_must_be_empty err &&
  82
  83                test-tool chmtime -v +0 b >actual-mtime &&
  84                test_cmp expected-mtime actual-mtime &&
  85
  86                git ls-files -s >index_files &&
  87                test_line_count = 1 index_files &&
  88
  89                git rev-parse >actual HEAD:b &&
  90                git rev-parse >expect A:b &&
  91                test_cmp expect actual &&
  92
  93                git hash-object b   >actual &&
  94                git rev-parse   A:b >expect &&
  95                test_cmp expect actual
  96        )
  97'
  98
  99test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' '
 100        test_when_finished "git -C 1a reset --hard" &&
 101        test_when_finished "git -C 1a clean -fd" &&
 102        (
 103                cd 1a &&
 104
 105                git checkout B^0 &&
 106
 107                GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
 108
 109                test_i18ngrep "Auto-merging b" out &&
 110                test_must_be_empty err &&
 111
 112                git ls-files -s >index_files &&
 113                test_line_count = 1 index_files &&
 114
 115                git rev-parse >actual HEAD:b &&
 116                git rev-parse >expect A:b &&
 117                test_cmp expect actual &&
 118
 119                git hash-object b   >actual &&
 120                git rev-parse   A:b >expect &&
 121                test_cmp expect actual
 122        )
 123'
 124
 125
 126###########################################################################
 127# SECTION 2: Cases involving basic renames
 128###########################################################################
 129
 130# Testcase 2a, Changes on A, rename on B
 131#   Commit O: b_1
 132#   Commit A: b_2
 133#   Commit B: c_1
 134#   Expected: c_2
 135
 136test_expect_success '2a-setup: Modify(A)/rename(B)' '
 137        test_create_repo 2a &&
 138        (
 139                cd 2a &&
 140
 141                test_seq 1 10 >b &&
 142                git add b &&
 143                test_tick &&
 144                git commit -m "O" &&
 145
 146                git branch O &&
 147                git branch A &&
 148                git branch B &&
 149
 150                git checkout A &&
 151                test_seq 1 11 >b &&
 152                git add b &&
 153                test_tick &&
 154                git commit -m "A" &&
 155
 156                git checkout B &&
 157                git mv b c &&
 158                test_tick &&
 159                git commit -m "B"
 160        )
 161'
 162
 163test_expect_success '2a-check-L: Modify/rename, merge into modify side' '
 164        test_when_finished "git -C 2a reset --hard" &&
 165        test_when_finished "git -C 2a clean -fd" &&
 166        (
 167                cd 2a &&
 168
 169                git checkout A^0 &&
 170
 171                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
 172
 173                test_i18ngrep ! "Skipped c" out &&
 174                test_must_be_empty err &&
 175
 176                git ls-files -s >index_files &&
 177                test_line_count = 1 index_files &&
 178
 179                git rev-parse >actual HEAD:c &&
 180                git rev-parse >expect A:b &&
 181                test_cmp expect actual &&
 182
 183                git hash-object c   >actual &&
 184                git rev-parse   A:b >expect &&
 185                test_cmp expect actual &&
 186
 187                test_must_fail git rev-parse HEAD:b &&
 188                test_path_is_missing b
 189        )
 190'
 191
 192test_expect_success '2a-check-R: Modify/rename, merge into rename side' '
 193        test_when_finished "git -C 2a reset --hard" &&
 194        test_when_finished "git -C 2a clean -fd" &&
 195        (
 196                cd 2a &&
 197
 198                git checkout B^0 &&
 199
 200                GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
 201
 202                test_i18ngrep ! "Skipped c" out &&
 203                test_must_be_empty err &&
 204
 205                git ls-files -s >index_files &&
 206                test_line_count = 1 index_files &&
 207
 208                git rev-parse >actual HEAD:c &&
 209                git rev-parse >expect A:b &&
 210                test_cmp expect actual &&
 211
 212                git hash-object c   >actual &&
 213                git rev-parse   A:b >expect &&
 214                test_cmp expect actual &&
 215
 216                test_must_fail git rev-parse HEAD:b &&
 217                test_path_is_missing b
 218        )
 219'
 220
 221# Testcase 2b, Changed and renamed on A, subset of changes on B
 222#   Commit O: b_1
 223#   Commit A: c_2
 224#   Commit B: b_3
 225#   Expected: c_2
 226
 227test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' '
 228        test_create_repo 2b &&
 229        (
 230                cd 2b &&
 231
 232                test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
 233                git add b &&
 234                test_tick &&
 235                git commit -m "O" &&
 236
 237                git branch O &&
 238                git branch A &&
 239                git branch B &&
 240
 241                git checkout A &&
 242                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
 243                git add b &&
 244                git mv b c &&
 245                test_tick &&
 246                git commit -m "A" &&
 247
 248                git checkout B &&
 249                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
 250                git add b &&
 251                test_tick &&
 252                git commit -m "B"
 253        )
 254'
 255
 256test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
 257        test_when_finished "git -C 2b reset --hard" &&
 258        test_when_finished "git -C 2b clean -fd" &&
 259        (
 260                cd 2b &&
 261
 262                git checkout A^0 &&
 263
 264                test-tool chmtime =31337 c &&
 265                test-tool chmtime -v +0 c >expected-mtime &&
 266
 267                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
 268
 269                test_i18ngrep "Skipped c" out &&
 270                test_must_be_empty err &&
 271
 272                test-tool chmtime -v +0 c >actual-mtime &&
 273                test_cmp expected-mtime actual-mtime &&
 274
 275                git ls-files -s >index_files &&
 276                test_line_count = 1 index_files &&
 277
 278                git rev-parse >actual HEAD:c &&
 279                git rev-parse >expect A:c &&
 280                test_cmp expect actual &&
 281
 282                git hash-object c   >actual &&
 283                git rev-parse   A:c >expect &&
 284                test_cmp expect actual &&
 285
 286                test_must_fail git rev-parse HEAD:b &&
 287                test_path_is_missing b
 288        )
 289'
 290
 291test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
 292        test_when_finished "git -C 2b reset --hard" &&
 293        test_when_finished "git -C 2b clean -fd" &&
 294        (
 295                cd 2b &&
 296
 297                git checkout B^0 &&
 298
 299                GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
 300
 301                test_i18ngrep "Auto-merging c" out &&
 302                test_must_be_empty err &&
 303
 304                git ls-files -s >index_files &&
 305                test_line_count = 1 index_files &&
 306
 307                git rev-parse >actual HEAD:c &&
 308                git rev-parse >expect A:c &&
 309                test_cmp expect actual &&
 310
 311                git hash-object c   >actual &&
 312                git rev-parse   A:c >expect &&
 313                test_cmp expect actual &&
 314
 315                test_must_fail git rev-parse HEAD:b &&
 316                test_path_is_missing b
 317        )
 318'
 319
 320# Testcase 2c, Changes on A, rename on B
 321#   Commit O: b_1
 322#   Commit A: b_2, c_3
 323#   Commit B: c_1
 324#   Expected: rename/add conflict c_2 vs c_3
 325#
 326#   NOTE: Since A modified b_1->b_2, and B renamed b_1->c_1, the threeway
 327#         merge of those files should result in c_2.  We then should have a
 328#         rename/add conflict between c_2 and c_3.  However, if we note in
 329#         merge_content() that A had the right contents (b_2 has same
 330#         contents as c_2, just at a different name), and that A had the
 331#         right path present (c_3 existed) and thus decides that it can
 332#         skip the update, then we're in trouble.  This test verifies we do
 333#         not make that particular mistake.
 334
 335test_expect_success '2c-setup: Modify b & add c VS rename b->c' '
 336        test_create_repo 2c &&
 337        (
 338                cd 2c &&
 339
 340                test_seq 1 10 >b &&
 341                git add b &&
 342                test_tick &&
 343                git commit -m "O" &&
 344
 345                git branch O &&
 346                git branch A &&
 347                git branch B &&
 348
 349                git checkout A &&
 350                test_seq 1 11 >b &&
 351                echo whatever >c &&
 352                git add b c &&
 353                test_tick &&
 354                git commit -m "A" &&
 355
 356                git checkout B &&
 357                git mv b c &&
 358                test_tick &&
 359                git commit -m "B"
 360        )
 361'
 362
 363test_expect_success '2c-check: Modify b & add c VS rename b->c' '
 364        (
 365                cd 2c &&
 366
 367                git checkout A^0 &&
 368
 369                GIT_MERGE_VERBOSITY=3 test_must_fail git merge -s recursive B^0 >out 2>err &&
 370
 371                test_i18ngrep "CONFLICT (rename/add): Rename b->c" out &&
 372                test_i18ngrep ! "Skipped c" out &&
 373                test_must_be_empty err
 374
 375                # FIXME: rename/add conflicts are horribly broken right now;
 376                # when I get back to my patch series fixing it and
 377                # rename/rename(2to1) conflicts to bring them in line with
 378                # how add/add conflicts behave, then checks like the below
 379                # could be added.  But that patch series is waiting until
 380                # the rename-directory-detection series lands, which this
 381                # is part of.  And in the mean time, I do not want to further
 382                # enforce broken behavior.  So for now, the main test is the
 383                # one above that err is an empty file.
 384
 385                #git ls-files -s >index_files &&
 386                #test_line_count = 2 index_files &&
 387
 388                #git rev-parse >actual :2:c :3:c &&
 389                #git rev-parse >expect A:b  A:c  &&
 390                #test_cmp expect actual &&
 391
 392                #git cat-file -p A:b >>merged &&
 393                #git cat-file -p A:c >>merge-me &&
 394                #>empty &&
 395                #test_must_fail git merge-file \
 396                #       -L "Temporary merge branch 1" \
 397                #       -L "" \
 398                #       -L "Temporary merge branch 2" \
 399                #       merged empty merge-me &&
 400                #sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal &&
 401
 402                #git hash-object c               >actual &&
 403                #git hash-object merged-internal >expect &&
 404                #test_cmp expect actual &&
 405
 406                #test_path_is_missing b
 407        )
 408'
 409
 410
 411###########################################################################
 412# SECTION 3: Cases involving directory renames
 413#
 414# NOTE:
 415#   Directory renames only apply when one side renames a directory, and the
 416#   other side adds or renames a path into that directory.  Applying the
 417#   directory rename to that new path creates a new pathname that didn't
 418#   exist on either side of history.  Thus, it is impossible for the
 419#   merge contents to already be at the right path, so all of these checks
 420#   exist just to make sure that updates are not skipped.
 421###########################################################################
 422
 423# Testcase 3a, Change + rename into dir foo on A, dir rename foo->bar on B
 424#   Commit O: bq_1, foo/whatever
 425#   Commit A: foo/{bq_2, whatever}
 426#   Commit B: bq_1, bar/whatever
 427#   Expected: bar/{bq_2, whatever}
 428
 429test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
 430        test_create_repo 3a &&
 431        (
 432                cd 3a &&
 433
 434                mkdir foo &&
 435                test_seq 1 10 >bq &&
 436                test_write_lines a b c d e f g h i j k >foo/whatever &&
 437                git add bq foo/whatever &&
 438                test_tick &&
 439                git commit -m "O" &&
 440
 441                git branch O &&
 442                git branch A &&
 443                git branch B &&
 444
 445                git checkout A &&
 446                test_seq 1 11 >bq &&
 447                git add bq &&
 448                git mv bq foo/ &&
 449                test_tick &&
 450                git commit -m "A" &&
 451
 452                git checkout B &&
 453                git mv foo/ bar/ &&
 454                test_tick &&
 455                git commit -m "B"
 456        )
 457'
 458
 459test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
 460        test_when_finished "git -C 3a reset --hard" &&
 461        test_when_finished "git -C 3a clean -fd" &&
 462        (
 463                cd 3a &&
 464
 465                git checkout A^0 &&
 466
 467                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
 468
 469                test_i18ngrep ! "Skipped bar/bq" out &&
 470                test_must_be_empty err &&
 471
 472                git ls-files -s >index_files &&
 473                test_line_count = 2 index_files &&
 474
 475                git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
 476                git rev-parse >expect A:foo/bq    A:foo/whatever &&
 477                test_cmp expect actual &&
 478
 479                git hash-object bar/bq   bar/whatever   >actual &&
 480                git rev-parse   A:foo/bq A:foo/whatever >expect &&
 481                test_cmp expect actual &&
 482
 483                test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
 484                test_path_is_missing bq foo/bq foo/whatever
 485        )
 486'
 487
 488test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
 489        test_when_finished "git -C 3a reset --hard" &&
 490        test_when_finished "git -C 3a clean -fd" &&
 491        (
 492                cd 3a &&
 493
 494                git checkout B^0 &&
 495
 496                GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
 497
 498                test_i18ngrep ! "Skipped bar/bq" out &&
 499                test_must_be_empty err &&
 500
 501                git ls-files -s >index_files &&
 502                test_line_count = 2 index_files &&
 503
 504                git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
 505                git rev-parse >expect A:foo/bq    A:foo/whatever &&
 506                test_cmp expect actual &&
 507
 508                git hash-object bar/bq   bar/whatever   >actual &&
 509                git rev-parse   A:foo/bq A:foo/whatever >expect &&
 510                test_cmp expect actual &&
 511
 512                test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
 513                test_path_is_missing bq foo/bq foo/whatever
 514        )
 515'
 516
 517# Testcase 3b, rename into dir foo on A, dir rename foo->bar + change on B
 518#   Commit O: bq_1, foo/whatever
 519#   Commit A: foo/{bq_1, whatever}
 520#   Commit B: bq_2, bar/whatever
 521#   Expected: bar/{bq_2, whatever}
 522
 523test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
 524        test_create_repo 3b &&
 525        (
 526                cd 3b &&
 527
 528                mkdir foo &&
 529                test_seq 1 10 >bq &&
 530                test_write_lines a b c d e f g h i j k >foo/whatever &&
 531                git add bq foo/whatever &&
 532                test_tick &&
 533                git commit -m "O" &&
 534
 535                git branch O &&
 536                git branch A &&
 537                git branch B &&
 538
 539                git checkout A &&
 540                git mv bq foo/ &&
 541                test_tick &&
 542                git commit -m "A" &&
 543
 544                git checkout B &&
 545                test_seq 1 11 >bq &&
 546                git add bq &&
 547                git mv foo/ bar/ &&
 548                test_tick &&
 549                git commit -m "B"
 550        )
 551'
 552
 553test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
 554        test_when_finished "git -C 3b reset --hard" &&
 555        test_when_finished "git -C 3b clean -fd" &&
 556        (
 557                cd 3b &&
 558
 559                git checkout A^0 &&
 560
 561                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
 562
 563                test_i18ngrep ! "Skipped bar/bq" out &&
 564                test_must_be_empty err &&
 565
 566                git ls-files -s >index_files &&
 567                test_line_count = 2 index_files &&
 568
 569                git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
 570                git rev-parse >expect B:bq        A:foo/whatever &&
 571                test_cmp expect actual &&
 572
 573                git hash-object bar/bq bar/whatever   >actual &&
 574                git rev-parse   B:bq   A:foo/whatever >expect &&
 575                test_cmp expect actual &&
 576
 577                test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
 578                test_path_is_missing bq foo/bq foo/whatever
 579        )
 580'
 581
 582test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
 583        test_when_finished "git -C 3b reset --hard" &&
 584        test_when_finished "git -C 3b clean -fd" &&
 585        (
 586                cd 3b &&
 587
 588                git checkout B^0 &&
 589
 590                GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
 591
 592                test_i18ngrep ! "Skipped bar/bq" out &&
 593                test_must_be_empty err &&
 594
 595                git ls-files -s >index_files &&
 596                test_line_count = 2 index_files &&
 597
 598                git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
 599                git rev-parse >expect B:bq        A:foo/whatever &&
 600                test_cmp expect actual &&
 601
 602                git hash-object bar/bq bar/whatever   >actual &&
 603                git rev-parse   B:bq   A:foo/whatever >expect &&
 604                test_cmp expect actual &&
 605
 606                test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
 607                test_path_is_missing bq foo/bq foo/whatever
 608        )
 609'
 610
 611###########################################################################
 612# SECTION 4: Cases involving dirty changes
 613###########################################################################
 614
 615# Testcase 4a, Changed on A, subset of changes on B, locally modified
 616#   Commit O: b_1
 617#   Commit A: b_2
 618#   Commit B: b_3
 619#   Working copy: b_4
 620#   Expected: b_2 for merge, b_4 in working copy
 621
 622test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods present' '
 623        test_create_repo 4a &&
 624        (
 625                cd 4a &&
 626
 627                test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
 628                git add b &&
 629                test_tick &&
 630                git commit -m "O" &&
 631
 632                git branch O &&
 633                git branch A &&
 634                git branch B &&
 635
 636                git checkout A &&
 637                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
 638                git add b &&
 639                test_tick &&
 640                git commit -m "A" &&
 641
 642                git checkout B &&
 643                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
 644                git add b &&
 645                test_tick &&
 646                git commit -m "B"
 647        )
 648'
 649
 650# NOTE: For as long as we continue using unpack_trees() without index_only
 651#   set to true, it will error out on a case like this claiming the the locally
 652#   modified file would be overwritten by the merge.  Getting this testcase
 653#   correct requires doing the merge in-memory first, then realizing that no
 654#   updates to the file are necessary, and thus that we can just leave the path
 655#   alone.
 656test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods present' '
 657        test_when_finished "git -C 4a reset --hard" &&
 658        test_when_finished "git -C 4a clean -fd" &&
 659        (
 660                cd 4a &&
 661
 662                git checkout A^0 &&
 663                echo "File rewritten" >b &&
 664
 665                test-tool chmtime =31337 b &&
 666                test-tool chmtime -v +0 b >expected-mtime &&
 667
 668                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
 669
 670                test_i18ngrep "Skipped b" out &&
 671                test_must_be_empty err &&
 672
 673                test-tool chmtime -v +0 b >actual-mtime &&
 674                test_cmp expected-mtime actual-mtime &&
 675
 676                git ls-files -s >index_files &&
 677                test_line_count = 1 index_files &&
 678
 679                git rev-parse >actual :0:b &&
 680                git rev-parse >expect A:b &&
 681                test_cmp expect actual &&
 682
 683                git hash-object b >actual &&
 684                echo "File rewritten" | git hash-object --stdin >expect &&
 685                test_cmp expect actual
 686        )
 687'
 688
 689# Testcase 4b, Changed+renamed on A, subset of changes on B, locally modified
 690#   Commit O: b_1
 691#   Commit A: c_2
 692#   Commit B: b_3
 693#   Working copy: c_4
 694#   Expected: c_2
 695
 696test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
 697        test_create_repo 4b &&
 698        (
 699                cd 4b &&
 700
 701                test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
 702                git add b &&
 703                test_tick &&
 704                git commit -m "O" &&
 705
 706                git branch O &&
 707                git branch A &&
 708                git branch B &&
 709
 710                git checkout A &&
 711                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
 712                git add b &&
 713                git mv b c &&
 714                test_tick &&
 715                git commit -m "A" &&
 716
 717                git checkout B &&
 718                test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
 719                git add b &&
 720                test_tick &&
 721                git commit -m "B"
 722        )
 723'
 724
 725test_expect_success '4b-check: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
 726        test_when_finished "git -C 4b reset --hard" &&
 727        test_when_finished "git -C 4b clean -fd" &&
 728        (
 729                cd 4b &&
 730
 731                git checkout A^0 &&
 732                echo "File rewritten" >c &&
 733
 734                test-tool chmtime =31337 c &&
 735                test-tool chmtime -v +0 c >expected-mtime &&
 736
 737                GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
 738
 739                test_i18ngrep "Skipped c" out &&
 740                test_must_be_empty err &&
 741
 742                test-tool chmtime -v +0 c >actual-mtime &&
 743                test_cmp expected-mtime actual-mtime &&
 744
 745                git ls-files -s >index_files &&
 746                test_line_count = 1 index_files &&
 747
 748                git rev-parse >actual :0:c &&
 749                git rev-parse >expect A:c &&
 750                test_cmp expect actual &&
 751
 752                git hash-object c >actual &&
 753                echo "File rewritten" | git hash-object --stdin >expect &&
 754                test_cmp expect actual &&
 755
 756                test_must_fail git rev-parse HEAD:b &&
 757                test_path_is_missing b
 758        )
 759'
 760
 761test_done