t / t7600-merge.shon commit Merge branch 'maint' to sync with 1.7.2.2 (c11969d)
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Lars Hjemli
   4#
   5
   6test_description='git merge
   7
   8Testing basic merge operations/option parsing.'
   9
  10. ./test-lib.sh
  11
  12cat >file <<EOF
  131
  142
  153
  164
  175
  186
  197
  208
  219
  22EOF
  23
  24cat >file.1 <<EOF
  251 X
  262
  273
  284
  295
  306
  317
  328
  339
  34EOF
  35
  36cat >file.5 <<EOF
  371
  382
  393
  404
  415 X
  426
  437
  448
  459
  46EOF
  47
  48cat >file.9 <<EOF
  491
  502
  513
  524
  535
  546
  557
  568
  579 X
  58EOF
  59
  60cat  >result.1 <<EOF
  611 X
  622
  633
  644
  655
  666
  677
  688
  699
  70EOF
  71
  72cat >result.1-5 <<EOF
  731 X
  742
  753
  764
  775 X
  786
  797
  808
  819
  82EOF
  83
  84cat >result.1-5-9 <<EOF
  851 X
  862
  873
  884
  895 X
  906
  917
  928
  939 X
  94EOF
  95
  96create_merge_msgs() {
  97        echo "Merge commit 'c2'" >msg.1-5 &&
  98        echo "Merge commit 'c2'; commit 'c3'" >msg.1-5-9 &&
  99        echo "Squashed commit of the following:" >squash.1 &&
 100        echo >>squash.1 &&
 101        git log --no-merges ^HEAD c1 >>squash.1 &&
 102        echo "Squashed commit of the following:" >squash.1-5 &&
 103        echo >>squash.1-5 &&
 104        git log --no-merges ^HEAD c2 >>squash.1-5 &&
 105        echo "Squashed commit of the following:" >squash.1-5-9 &&
 106        echo >>squash.1-5-9 &&
 107        git log --no-merges ^HEAD c2 c3 >>squash.1-5-9 &&
 108        echo > msg.nolog &&
 109        echo "* commit 'c3':" >msg.log &&
 110        echo "  commit 3" >>msg.log &&
 111        echo >>msg.log
 112}
 113
 114verify_diff() {
 115        if ! test_cmp "$1" "$2"
 116        then
 117                echo "$3"
 118                false
 119        fi
 120}
 121
 122verify_merge() {
 123        verify_diff "$2" "$1" "[OOPS] bad merge result" &&
 124        if test $(git ls-files -u | wc -l) -gt 0
 125        then
 126                echo "[OOPS] unmerged files"
 127                false
 128        fi &&
 129        if test_must_fail git diff --exit-code
 130        then
 131                echo "[OOPS] working tree != index"
 132                false
 133        fi &&
 134        if test -n "$3"
 135        then
 136                git show -s --pretty=format:%s HEAD >msg.act &&
 137                verify_diff "$3" msg.act "[OOPS] bad merge message"
 138        fi
 139}
 140
 141verify_head() {
 142        if test "$1" != "$(git rev-parse HEAD)"
 143        then
 144                echo "[OOPS] HEAD != $1"
 145                false
 146        fi
 147}
 148
 149verify_parents() {
 150        i=1
 151        while test $# -gt 0
 152        do
 153                if test "$1" != "$(git rev-parse HEAD^$i)"
 154                then
 155                        echo "[OOPS] HEAD^$i != $1"
 156                        return 1
 157                fi
 158                i=$(expr $i + 1)
 159                shift
 160        done
 161}
 162
 163verify_mergeheads() {
 164        i=1
 165        if ! test -f .git/MERGE_HEAD
 166        then
 167                echo "[OOPS] MERGE_HEAD is missing"
 168                false
 169        fi &&
 170        while test $# -gt 0
 171        do
 172                head=$(head -n $i .git/MERGE_HEAD | sed -ne \$p)
 173                if test "$1" != "$head"
 174                then
 175                        echo "[OOPS] MERGE_HEAD $i != $1"
 176                        return 1
 177                fi
 178                i=$(expr $i + 1)
 179                shift
 180        done
 181}
 182
 183verify_no_mergehead() {
 184        if test -f .git/MERGE_HEAD
 185        then
 186                echo "[OOPS] MERGE_HEAD exists"
 187                false
 188        fi
 189}
 190
 191
 192test_expect_success 'setup' '
 193        git add file &&
 194        test_tick &&
 195        git commit -m "commit 0" &&
 196        git tag c0 &&
 197        c0=$(git rev-parse HEAD) &&
 198        cp file.1 file &&
 199        git add file &&
 200        test_tick &&
 201        git commit -m "commit 1" &&
 202        git tag c1 &&
 203        c1=$(git rev-parse HEAD) &&
 204        git reset --hard "$c0" &&
 205        cp file.5 file &&
 206        git add file &&
 207        test_tick &&
 208        git commit -m "commit 2" &&
 209        git tag c2 &&
 210        c2=$(git rev-parse HEAD) &&
 211        git reset --hard "$c0" &&
 212        cp file.9 file &&
 213        git add file &&
 214        test_tick &&
 215        git commit -m "commit 3" &&
 216        git tag c3 &&
 217        c3=$(git rev-parse HEAD)
 218        git reset --hard "$c0" &&
 219        create_merge_msgs
 220'
 221
 222test_debug 'gitk --all'
 223
 224test_expect_success 'test option parsing' '
 225        test_must_fail git merge -$ c1 &&
 226        test_must_fail git merge --no-such c1 &&
 227        test_must_fail git merge -s foobar c1 &&
 228        test_must_fail git merge -s=foobar c1 &&
 229        test_must_fail git merge -m &&
 230        test_must_fail git merge
 231'
 232
 233test_expect_success 'reject non-strategy with a git-merge-foo name' '
 234        test_must_fail git merge -s index c1
 235'
 236
 237test_expect_success 'merge c0 with c1' '
 238        git reset --hard c0 &&
 239        git merge c1 &&
 240        verify_merge file result.1 &&
 241        verify_head "$c1"
 242'
 243
 244test_debug 'gitk --all'
 245
 246test_expect_success 'merge c0 with c1 with --ff-only' '
 247        git reset --hard c0 &&
 248        git merge --ff-only c1 &&
 249        git merge --ff-only HEAD c0 c1 &&
 250        verify_merge file result.1 &&
 251        verify_head "$c1"
 252'
 253
 254test_debug 'gitk --all'
 255
 256test_expect_success 'merge c1 with c2' '
 257        git reset --hard c1 &&
 258        test_tick &&
 259        git merge c2 &&
 260        verify_merge file result.1-5 msg.1-5 &&
 261        verify_parents $c1 $c2
 262'
 263
 264test_debug 'gitk --all'
 265
 266test_expect_success 'merge c1 with c2 and c3' '
 267        git reset --hard c1 &&
 268        test_tick &&
 269        git merge c2 c3 &&
 270        verify_merge file result.1-5-9 msg.1-5-9 &&
 271        verify_parents $c1 $c2 $c3
 272'
 273
 274test_debug 'gitk --all'
 275
 276test_expect_success 'failing merges with --ff-only' '
 277        git reset --hard c1 &&
 278        test_tick &&
 279        test_must_fail git merge --ff-only c2 &&
 280        test_must_fail git merge --ff-only c3 &&
 281        test_must_fail git merge --ff-only c2 c3
 282'
 283
 284test_expect_success 'merge c0 with c1 (no-commit)' '
 285        git reset --hard c0 &&
 286        git merge --no-commit c1 &&
 287        verify_merge file result.1 &&
 288        verify_head $c1
 289'
 290
 291test_debug 'gitk --all'
 292
 293test_expect_success 'merge c1 with c2 (no-commit)' '
 294        git reset --hard c1 &&
 295        git merge --no-commit c2 &&
 296        verify_merge file result.1-5 &&
 297        verify_head $c1 &&
 298        verify_mergeheads $c2
 299'
 300
 301test_debug 'gitk --all'
 302
 303test_expect_success 'merge c1 with c2 and c3 (no-commit)' '
 304        git reset --hard c1 &&
 305        git merge --no-commit c2 c3 &&
 306        verify_merge file result.1-5-9 &&
 307        verify_head $c1 &&
 308        verify_mergeheads $c2 $c3
 309'
 310
 311test_debug 'gitk --all'
 312
 313test_expect_success 'merge c0 with c1 (squash)' '
 314        git reset --hard c0 &&
 315        git merge --squash c1 &&
 316        verify_merge file result.1 &&
 317        verify_head $c0 &&
 318        verify_no_mergehead &&
 319        verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message"
 320'
 321
 322test_debug 'gitk --all'
 323
 324test_expect_success 'merge c0 with c1 (squash, ff-only)' '
 325        git reset --hard c0 &&
 326        git merge --squash --ff-only c1 &&
 327        verify_merge file result.1 &&
 328        verify_head $c0 &&
 329        verify_no_mergehead &&
 330        verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message"
 331'
 332
 333test_debug 'gitk --all'
 334
 335test_expect_success 'merge c1 with c2 (squash)' '
 336        git reset --hard c1 &&
 337        git merge --squash c2 &&
 338        verify_merge file result.1-5 &&
 339        verify_head $c1 &&
 340        verify_no_mergehead &&
 341        verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message"
 342'
 343
 344test_debug 'gitk --all'
 345
 346test_expect_success 'unsuccesful merge of c1 with c2 (squash, ff-only)' '
 347        git reset --hard c1 &&
 348        test_must_fail git merge --squash --ff-only c2
 349'
 350
 351test_debug 'gitk --all'
 352
 353test_expect_success 'merge c1 with c2 and c3 (squash)' '
 354        git reset --hard c1 &&
 355        git merge --squash c2 c3 &&
 356        verify_merge file result.1-5-9 &&
 357        verify_head $c1 &&
 358        verify_no_mergehead &&
 359        verify_diff squash.1-5-9 .git/SQUASH_MSG "[OOPS] bad squash message"
 360'
 361
 362test_debug 'gitk --all'
 363
 364test_expect_success 'merge c1 with c2 (no-commit in config)' '
 365        git reset --hard c1 &&
 366        git config branch.master.mergeoptions "--no-commit" &&
 367        git merge c2 &&
 368        verify_merge file result.1-5 &&
 369        verify_head $c1 &&
 370        verify_mergeheads $c2
 371'
 372
 373test_debug 'gitk --all'
 374
 375test_expect_success 'merge c1 with c2 (squash in config)' '
 376        git reset --hard c1 &&
 377        git config branch.master.mergeoptions "--squash" &&
 378        git merge c2 &&
 379        verify_merge file result.1-5 &&
 380        verify_head $c1 &&
 381        verify_no_mergehead &&
 382        verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message"
 383'
 384
 385test_debug 'gitk --all'
 386
 387test_expect_success 'override config option -n with --summary' '
 388        git reset --hard c1 &&
 389        git config branch.master.mergeoptions "-n" &&
 390        test_tick &&
 391        git merge --summary c2 >diffstat.txt &&
 392        verify_merge file result.1-5 msg.1-5 &&
 393        verify_parents $c1 $c2 &&
 394        if ! grep "^ file |  *2 +-$" diffstat.txt
 395        then
 396                echo "[OOPS] diffstat was not generated with --summary"
 397                false
 398        fi
 399'
 400
 401test_expect_success 'override config option -n with --stat' '
 402        git reset --hard c1 &&
 403        git config branch.master.mergeoptions "-n" &&
 404        test_tick &&
 405        git merge --stat c2 >diffstat.txt &&
 406        verify_merge file result.1-5 msg.1-5 &&
 407        verify_parents $c1 $c2 &&
 408        if ! grep "^ file |  *2 +-$" diffstat.txt
 409        then
 410                echo "[OOPS] diffstat was not generated with --stat"
 411                false
 412        fi
 413'
 414
 415test_debug 'gitk --all'
 416
 417test_expect_success 'override config option --stat' '
 418        git reset --hard c1 &&
 419        git config branch.master.mergeoptions "--stat" &&
 420        test_tick &&
 421        git merge -n c2 >diffstat.txt &&
 422        verify_merge file result.1-5 msg.1-5 &&
 423        verify_parents $c1 $c2 &&
 424        if grep "^ file |  *2 +-$" diffstat.txt
 425        then
 426                echo "[OOPS] diffstat was generated"
 427                false
 428        fi
 429'
 430
 431test_debug 'gitk --all'
 432
 433test_expect_success 'merge c1 with c2 (override --no-commit)' '
 434        git reset --hard c1 &&
 435        git config branch.master.mergeoptions "--no-commit" &&
 436        test_tick &&
 437        git merge --commit c2 &&
 438        verify_merge file result.1-5 msg.1-5 &&
 439        verify_parents $c1 $c2
 440'
 441
 442test_debug 'gitk --all'
 443
 444test_expect_success 'merge c1 with c2 (override --squash)' '
 445        git reset --hard c1 &&
 446        git config branch.master.mergeoptions "--squash" &&
 447        test_tick &&
 448        git merge --no-squash c2 &&
 449        verify_merge file result.1-5 msg.1-5 &&
 450        verify_parents $c1 $c2
 451'
 452
 453test_debug 'gitk --all'
 454
 455test_expect_success 'merge c0 with c1 (no-ff)' '
 456        git reset --hard c0 &&
 457        git config branch.master.mergeoptions "" &&
 458        test_tick &&
 459        git merge --no-ff c1 &&
 460        verify_merge file result.1 &&
 461        verify_parents $c0 $c1
 462'
 463
 464test_debug 'gitk --all'
 465
 466test_expect_success 'combining --squash and --no-ff is refused' '
 467        test_must_fail git merge --squash --no-ff c1 &&
 468        test_must_fail git merge --no-ff --squash c1
 469'
 470
 471test_expect_success 'combining --ff-only and --no-ff is refused' '
 472        test_must_fail git merge --ff-only --no-ff c1 &&
 473        test_must_fail git merge --no-ff --ff-only c1
 474'
 475
 476test_expect_success 'merge c0 with c1 (ff overrides no-ff)' '
 477        git reset --hard c0 &&
 478        git config branch.master.mergeoptions "--no-ff" &&
 479        git merge --ff c1 &&
 480        verify_merge file result.1 &&
 481        verify_head $c1
 482'
 483
 484test_expect_success 'merge log message' '
 485        git reset --hard c0 &&
 486        git merge --no-log c2 &&
 487        git show -s --pretty=format:%b HEAD >msg.act &&
 488        verify_diff msg.nolog msg.act "[OOPS] bad merge log message" &&
 489
 490        git merge --log c3 &&
 491        git show -s --pretty=format:%b HEAD >msg.act &&
 492        verify_diff msg.log msg.act "[OOPS] bad merge log message" &&
 493
 494        git reset --hard HEAD^ &&
 495        git config merge.log yes &&
 496        git merge c3 &&
 497        git show -s --pretty=format:%b HEAD >msg.act &&
 498        verify_diff msg.log msg.act "[OOPS] bad merge log message"
 499'
 500
 501test_debug 'gitk --all'
 502
 503test_expect_success 'merge c1 with c0, c2, c0, and c1' '
 504       git reset --hard c1 &&
 505       git config branch.master.mergeoptions "" &&
 506       test_tick &&
 507       git merge c0 c2 c0 c1 &&
 508       verify_merge file result.1-5 &&
 509       verify_parents $c1 $c2
 510'
 511
 512test_debug 'gitk --all'
 513
 514test_expect_success 'merge c1 with c0, c2, c0, and c1' '
 515       git reset --hard c1 &&
 516       git config branch.master.mergeoptions "" &&
 517       test_tick &&
 518       git merge c0 c2 c0 c1 &&
 519       verify_merge file result.1-5 &&
 520       verify_parents $c1 $c2
 521'
 522
 523test_debug 'gitk --all'
 524
 525test_expect_success 'merge c1 with c1 and c2' '
 526       git reset --hard c1 &&
 527       git config branch.master.mergeoptions "" &&
 528       test_tick &&
 529       git merge c1 c2 &&
 530       verify_merge file result.1-5 &&
 531       verify_parents $c1 $c2
 532'
 533
 534test_debug 'gitk --all'
 535
 536test_expect_success 'merge fast-forward in a dirty tree' '
 537       git reset --hard c0 &&
 538       mv file file1 &&
 539       cat file1 >file &&
 540       rm -f file1 &&
 541       git merge c2
 542'
 543
 544test_debug 'gitk --all'
 545
 546test_expect_success 'in-index merge' '
 547        git reset --hard c0 &&
 548        git merge --no-ff -s resolve c1 > out &&
 549        grep "Wonderful." out &&
 550        verify_parents $c0 $c1
 551'
 552
 553test_debug 'gitk --all'
 554
 555test_expect_success 'refresh the index before merging' '
 556        git reset --hard c1 &&
 557        cp file file.n && mv -f file.n file &&
 558        git merge c3
 559'
 560
 561cat >expected <<EOF
 562Merge branch 'c5' (early part)
 563EOF
 564
 565test_expect_success 'merge early part of c2' '
 566        git reset --hard c3 &&
 567        echo c4 > c4.c &&
 568        git add c4.c &&
 569        git commit -m c4 &&
 570        git tag c4 &&
 571        echo c5 > c5.c &&
 572        git add c5.c &&
 573        git commit -m c5 &&
 574        git tag c5 &&
 575        git reset --hard c3 &&
 576        echo c6 > c6.c &&
 577        git add c6.c &&
 578        git commit -m c6 &&
 579        git tag c6 &&
 580        git merge c5~1 &&
 581        git show -s --pretty=format:%s HEAD > actual &&
 582        test_cmp actual expected
 583'
 584
 585test_debug 'gitk --all'
 586
 587test_expect_success 'merge --no-ff --no-commit && commit' '
 588        git reset --hard c0 &&
 589        git merge --no-ff --no-commit c1 &&
 590        EDITOR=: git commit &&
 591        verify_parents $c0 $c1
 592'
 593
 594test_debug 'gitk --all'
 595
 596test_expect_success 'amending no-ff merge commit' '
 597        EDITOR=: git commit --amend &&
 598        verify_parents $c0 $c1
 599'
 600
 601test_debug 'gitk --all'
 602
 603test_done