t / t7600-merge.shon commit Documentation: add "Fighting regressions with git bisect" article (69a9cd3)
   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 c1 with c2' '
 247        git reset --hard c1 &&
 248        test_tick &&
 249        git merge c2 &&
 250        verify_merge file result.1-5 msg.1-5 &&
 251        verify_parents $c1 $c2
 252'
 253
 254test_debug 'gitk --all'
 255
 256test_expect_success 'merge c1 with c2 and c3' '
 257        git reset --hard c1 &&
 258        test_tick &&
 259        git merge c2 c3 &&
 260        verify_merge file result.1-5-9 msg.1-5-9 &&
 261        verify_parents $c1 $c2 $c3
 262'
 263
 264test_debug 'gitk --all'
 265
 266test_expect_success 'merge c0 with c1 (no-commit)' '
 267        git reset --hard c0 &&
 268        git merge --no-commit c1 &&
 269        verify_merge file result.1 &&
 270        verify_head $c1
 271'
 272
 273test_debug 'gitk --all'
 274
 275test_expect_success 'merge c1 with c2 (no-commit)' '
 276        git reset --hard c1 &&
 277        git merge --no-commit c2 &&
 278        verify_merge file result.1-5 &&
 279        verify_head $c1 &&
 280        verify_mergeheads $c2
 281'
 282
 283test_debug 'gitk --all'
 284
 285test_expect_success 'merge c1 with c2 and c3 (no-commit)' '
 286        git reset --hard c1 &&
 287        git merge --no-commit c2 c3 &&
 288        verify_merge file result.1-5-9 &&
 289        verify_head $c1 &&
 290        verify_mergeheads $c2 $c3
 291'
 292
 293test_debug 'gitk --all'
 294
 295test_expect_success 'merge c0 with c1 (squash)' '
 296        git reset --hard c0 &&
 297        git merge --squash c1 &&
 298        verify_merge file result.1 &&
 299        verify_head $c0 &&
 300        verify_no_mergehead &&
 301        verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message"
 302'
 303
 304test_debug 'gitk --all'
 305
 306test_expect_success 'merge c1 with c2 (squash)' '
 307        git reset --hard c1 &&
 308        git merge --squash c2 &&
 309        verify_merge file result.1-5 &&
 310        verify_head $c1 &&
 311        verify_no_mergehead &&
 312        verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message"
 313'
 314
 315test_debug 'gitk --all'
 316
 317test_expect_success 'merge c1 with c2 and c3 (squash)' '
 318        git reset --hard c1 &&
 319        git merge --squash c2 c3 &&
 320        verify_merge file result.1-5-9 &&
 321        verify_head $c1 &&
 322        verify_no_mergehead &&
 323        verify_diff squash.1-5-9 .git/SQUASH_MSG "[OOPS] bad squash message"
 324'
 325
 326test_debug 'gitk --all'
 327
 328test_expect_success 'merge c1 with c2 (no-commit in config)' '
 329        git reset --hard c1 &&
 330        git config branch.master.mergeoptions "--no-commit" &&
 331        git merge c2 &&
 332        verify_merge file result.1-5 &&
 333        verify_head $c1 &&
 334        verify_mergeheads $c2
 335'
 336
 337test_debug 'gitk --all'
 338
 339test_expect_success 'merge c1 with c2 (squash in config)' '
 340        git reset --hard c1 &&
 341        git config branch.master.mergeoptions "--squash" &&
 342        git merge c2 &&
 343        verify_merge file result.1-5 &&
 344        verify_head $c1 &&
 345        verify_no_mergehead &&
 346        verify_diff squash.1-5 .git/SQUASH_MSG "[OOPS] bad squash message"
 347'
 348
 349test_debug 'gitk --all'
 350
 351test_expect_success 'override config option -n with --summary' '
 352        git reset --hard c1 &&
 353        git config branch.master.mergeoptions "-n" &&
 354        test_tick &&
 355        git merge --summary c2 >diffstat.txt &&
 356        verify_merge file result.1-5 msg.1-5 &&
 357        verify_parents $c1 $c2 &&
 358        if ! grep "^ file |  *2 +-$" diffstat.txt
 359        then
 360                echo "[OOPS] diffstat was not generated with --summary"
 361                false
 362        fi
 363'
 364
 365test_expect_success 'override config option -n with --stat' '
 366        git reset --hard c1 &&
 367        git config branch.master.mergeoptions "-n" &&
 368        test_tick &&
 369        git merge --stat c2 >diffstat.txt &&
 370        verify_merge file result.1-5 msg.1-5 &&
 371        verify_parents $c1 $c2 &&
 372        if ! grep "^ file |  *2 +-$" diffstat.txt
 373        then
 374                echo "[OOPS] diffstat was not generated with --stat"
 375                false
 376        fi
 377'
 378
 379test_debug 'gitk --all'
 380
 381test_expect_success 'override config option --stat' '
 382        git reset --hard c1 &&
 383        git config branch.master.mergeoptions "--stat" &&
 384        test_tick &&
 385        git merge -n c2 >diffstat.txt &&
 386        verify_merge file result.1-5 msg.1-5 &&
 387        verify_parents $c1 $c2 &&
 388        if grep "^ file |  *2 +-$" diffstat.txt
 389        then
 390                echo "[OOPS] diffstat was generated"
 391                false
 392        fi
 393'
 394
 395test_debug 'gitk --all'
 396
 397test_expect_success 'merge c1 with c2 (override --no-commit)' '
 398        git reset --hard c1 &&
 399        git config branch.master.mergeoptions "--no-commit" &&
 400        test_tick &&
 401        git merge --commit c2 &&
 402        verify_merge file result.1-5 msg.1-5 &&
 403        verify_parents $c1 $c2
 404'
 405
 406test_debug 'gitk --all'
 407
 408test_expect_success 'merge c1 with c2 (override --squash)' '
 409        git reset --hard c1 &&
 410        git config branch.master.mergeoptions "--squash" &&
 411        test_tick &&
 412        git merge --no-squash c2 &&
 413        verify_merge file result.1-5 msg.1-5 &&
 414        verify_parents $c1 $c2
 415'
 416
 417test_debug 'gitk --all'
 418
 419test_expect_success 'merge c0 with c1 (no-ff)' '
 420        git reset --hard c0 &&
 421        git config branch.master.mergeoptions "" &&
 422        test_tick &&
 423        git merge --no-ff c1 &&
 424        verify_merge file result.1 &&
 425        verify_parents $c0 $c1
 426'
 427
 428test_debug 'gitk --all'
 429
 430test_expect_success 'combining --squash and --no-ff is refused' '
 431        test_must_fail git merge --squash --no-ff c1 &&
 432        test_must_fail git merge --no-ff --squash c1
 433'
 434
 435test_expect_success 'merge c0 with c1 (ff overrides no-ff)' '
 436        git reset --hard c0 &&
 437        git config branch.master.mergeoptions "--no-ff" &&
 438        git merge --ff c1 &&
 439        verify_merge file result.1 &&
 440        verify_head $c1
 441'
 442
 443test_expect_success 'merge log message' '
 444        git reset --hard c0 &&
 445        git merge --no-log c2 &&
 446        git show -s --pretty=format:%b HEAD >msg.act &&
 447        verify_diff msg.nolog msg.act "[OOPS] bad merge log message" &&
 448
 449        git merge --log c3 &&
 450        git show -s --pretty=format:%b HEAD >msg.act &&
 451        verify_diff msg.log msg.act "[OOPS] bad merge log message" &&
 452
 453        git reset --hard HEAD^ &&
 454        git config merge.log yes &&
 455        git merge c3 &&
 456        git show -s --pretty=format:%b HEAD >msg.act &&
 457        verify_diff msg.log msg.act "[OOPS] bad merge log message"
 458'
 459
 460test_debug 'gitk --all'
 461
 462test_expect_success 'merge c1 with c0, c2, c0, and c1' '
 463       git reset --hard c1 &&
 464       git config branch.master.mergeoptions "" &&
 465       test_tick &&
 466       git merge c0 c2 c0 c1 &&
 467       verify_merge file result.1-5 &&
 468       verify_parents $c1 $c2
 469'
 470
 471test_debug 'gitk --all'
 472
 473test_expect_success 'merge c1 with c0, c2, c0, and c1' '
 474       git reset --hard c1 &&
 475       git config branch.master.mergeoptions "" &&
 476       test_tick &&
 477       git merge c0 c2 c0 c1 &&
 478       verify_merge file result.1-5 &&
 479       verify_parents $c1 $c2
 480'
 481
 482test_debug 'gitk --all'
 483
 484test_expect_success 'merge c1 with c1 and c2' '
 485       git reset --hard c1 &&
 486       git config branch.master.mergeoptions "" &&
 487       test_tick &&
 488       git merge c1 c2 &&
 489       verify_merge file result.1-5 &&
 490       verify_parents $c1 $c2
 491'
 492
 493test_debug 'gitk --all'
 494
 495test_expect_success 'merge fast-forward in a dirty tree' '
 496       git reset --hard c0 &&
 497       mv file file1 &&
 498       cat file1 >file &&
 499       rm -f file1 &&
 500       git merge c2
 501'
 502
 503test_debug 'gitk --all'
 504
 505test_expect_success 'in-index merge' '
 506        git reset --hard c0 &&
 507        git merge --no-ff -s resolve c1 > out &&
 508        grep "Wonderful." out &&
 509        verify_parents $c0 $c1
 510'
 511
 512test_debug 'gitk --all'
 513
 514test_expect_success 'refresh the index before merging' '
 515        git reset --hard c1 &&
 516        sleep 1 &&
 517        touch file &&
 518        git merge c3
 519'
 520
 521cat >expected <<EOF
 522Merge branch 'c5' (early part)
 523EOF
 524
 525test_expect_success 'merge early part of c2' '
 526        git reset --hard c3 &&
 527        echo c4 > c4.c &&
 528        git add c4.c &&
 529        git commit -m c4 &&
 530        git tag c4 &&
 531        echo c5 > c5.c &&
 532        git add c5.c &&
 533        git commit -m c5 &&
 534        git tag c5 &&
 535        git reset --hard c3 &&
 536        echo c6 > c6.c &&
 537        git add c6.c &&
 538        git commit -m c6 &&
 539        git tag c6 &&
 540        git merge c5~1 &&
 541        git show -s --pretty=format:%s HEAD > actual &&
 542        test_cmp actual expected
 543'
 544
 545test_debug 'gitk --all'
 546
 547test_expect_success 'merge --no-ff --no-commit && commit' '
 548        git reset --hard c0 &&
 549        git merge --no-ff --no-commit c1 &&
 550        EDITOR=: git commit &&
 551        verify_parents $c0 $c1
 552'
 553
 554test_debug 'gitk --all'
 555
 556test_expect_success 'amending no-ff merge commit' '
 557        EDITOR=: git commit --amend &&
 558        verify_parents $c0 $c1
 559'
 560
 561test_debug 'gitk --all'
 562
 563test_done