bc38737b2a5ebd9b7ba20fcb92ac87c48b9496c8
   1#!/bin/sh
   2#
   3# Copyright (c) 2008 Charles Bailey
   4#
   5
   6test_description='git mergetool
   7
   8Testing basic merge tool invocation'
   9
  10. ./test-lib.sh
  11
  12# All the mergetool test work by checking out a temporary branch based
  13# off 'branch1' and then merging in master and checking the results of
  14# running mergetool
  15
  16test_expect_success 'setup' '
  17    git config rerere.enabled true &&
  18    echo master >file1 &&
  19    echo master spaced >"spaced name" &&
  20    echo master file11 >file11 &&
  21    echo master file12 >file12 &&
  22    echo master file13 >file13 &&
  23    echo master file14 >file14 &&
  24    mkdir subdir &&
  25    echo master sub >subdir/file3 &&
  26    test_create_repo submod &&
  27    (
  28        cd submod &&
  29        : >foo &&
  30        git add foo &&
  31        git commit -m "Add foo"
  32    ) &&
  33    git submodule add git://example.com/submod submod &&
  34    git add file1 "spaced name" file1[1-4] subdir/file3 .gitmodules submod &&
  35    git commit -m "add initial versions" &&
  36
  37    git checkout -b branch1 master &&
  38    git submodule update -N &&
  39    echo branch1 change >file1 &&
  40    echo branch1 newfile >file2 &&
  41    echo branch1 spaced >"spaced name" &&
  42    echo branch1 both added >both &&
  43    echo branch1 change file11 >file11 &&
  44    echo branch1 change file13 >file13 &&
  45    echo branch1 sub >subdir/file3 &&
  46    (
  47        cd submod &&
  48        echo branch1 submodule >bar &&
  49        git add bar &&
  50        git commit -m "Add bar on branch1" &&
  51        git checkout -b submod-branch1
  52    ) &&
  53    git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
  54    git add both &&
  55    git rm file12 &&
  56    git commit -m "branch1 changes" &&
  57
  58    git checkout -b stash1 master &&
  59    echo stash1 change file11 >file11 &&
  60    git add file11 &&
  61    git commit -m "stash1 changes" &&
  62
  63    git checkout -b stash2 master &&
  64    echo stash2 change file11 >file11 &&
  65    git add file11 &&
  66    git commit -m "stash2 changes" &&
  67
  68    git checkout master &&
  69    git submodule update -N &&
  70    echo master updated >file1 &&
  71    echo master new >file2 &&
  72    echo master updated spaced >"spaced name" &&
  73    echo master both added >both &&
  74    echo master updated file12 >file12 &&
  75    echo master updated file14 >file14 &&
  76    echo master new sub >subdir/file3 &&
  77    (
  78        cd submod &&
  79        echo master submodule >bar &&
  80        git add bar &&
  81        git commit -m "Add bar on master" &&
  82        git checkout -b submod-master
  83    ) &&
  84    git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
  85    git add both &&
  86    git rm file11 &&
  87    git commit -m "master updates" &&
  88
  89    git config merge.tool mytool &&
  90    git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
  91    git config mergetool.mytool.trustExitCode true &&
  92    git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
  93    git config mergetool.mybase.trustExitCode true
  94'
  95
  96test_expect_success 'custom mergetool' '
  97    git checkout -b test1 branch1 &&
  98    git submodule update -N &&
  99    test_must_fail git merge master >/dev/null 2>&1 &&
 100    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 101    ( yes "" | git mergetool file1 file1 ) &&
 102    ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
 103    ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
 104    ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
 105    ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
 106    ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
 107    test "$(cat file1)" = "master updated" &&
 108    test "$(cat file2)" = "master new" &&
 109    test "$(cat subdir/file3)" = "master new sub" &&
 110    test "$(cat submod/bar)" = "branch1 submodule" &&
 111    git commit -m "branch1 resolved with mergetool"
 112'
 113
 114test_expect_success 'mergetool crlf' '
 115    git config core.autocrlf true &&
 116    git checkout -b test2 branch1 &&
 117    test_must_fail git merge master >/dev/null 2>&1 &&
 118    ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
 119    ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
 120    ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
 121    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 122    ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
 123    ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
 124    ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
 125    ( yes "r" | git mergetool submod >/dev/null 2>&1 ) &&
 126    test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" &&
 127    test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" &&
 128    test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" &&
 129    git submodule update -N &&
 130    test "$(cat submod/bar)" = "master submodule" &&
 131    git commit -m "branch1 resolved with mergetool - autocrlf" &&
 132    git config core.autocrlf false &&
 133    git reset --hard
 134'
 135
 136test_expect_success 'mergetool in subdir' '
 137    git checkout -b test3 branch1 &&
 138    git submodule update -N &&
 139    (
 140        cd subdir &&
 141        test_must_fail git merge master >/dev/null 2>&1 &&
 142        ( yes "" | git mergetool file3 >/dev/null 2>&1 ) &&
 143        test "$(cat file3)" = "master new sub"
 144    )
 145'
 146
 147test_expect_success 'mergetool on file in parent dir' '
 148    (
 149        cd subdir &&
 150        ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
 151        ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
 152        ( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
 153        ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
 154        ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
 155        ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
 156        test "$(cat ../file1)" = "master updated" &&
 157        test "$(cat ../file2)" = "master new" &&
 158        test "$(cat ../submod/bar)" = "branch1 submodule" &&
 159        git commit -m "branch1 resolved with mergetool - subdir"
 160    )
 161'
 162
 163test_expect_success 'mergetool skips autoresolved' '
 164    git checkout -b test4 branch1 &&
 165    git submodule update -N &&
 166    test_must_fail git merge master &&
 167    test -n "$(git ls-files -u)" &&
 168    ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
 169    ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
 170    ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
 171    output="$(git mergetool --no-prompt)" &&
 172    test "$output" = "No files need merging" &&
 173    git reset --hard
 174'
 175
 176test_expect_success 'mergetool merges all from subdir' '
 177    (
 178        cd subdir &&
 179        git config rerere.enabled false &&
 180        test_must_fail git merge master &&
 181        ( yes "r" | git mergetool ../submod ) &&
 182        ( yes "d" "d" | git mergetool --no-prompt ) &&
 183        test "$(cat ../file1)" = "master updated" &&
 184        test "$(cat ../file2)" = "master new" &&
 185        test "$(cat file3)" = "master new sub" &&
 186        ( cd .. && git submodule update -N ) &&
 187        test "$(cat ../submod/bar)" = "master submodule" &&
 188        git commit -m "branch2 resolved by mergetool from subdir"
 189    )
 190'
 191
 192test_expect_success 'mergetool skips resolved paths when rerere is active' '
 193    git config rerere.enabled true &&
 194    rm -rf .git/rr-cache &&
 195    git checkout -b test5 branch1
 196    git submodule update -N &&
 197    test_must_fail git merge master >/dev/null 2>&1 &&
 198    ( yes "l" | git mergetool --no-prompt submod >/dev/null 2>&1 ) &&
 199    ( yes "d" "d" | git mergetool --no-prompt >/dev/null 2>&1 ) &&
 200    git submodule update -N &&
 201    output="$(yes "n" | git mergetool --no-prompt)" &&
 202    test "$output" = "No files need merging" &&
 203    git reset --hard
 204'
 205
 206test_expect_success 'conflicted stash sets up rerere'  '
 207    git config rerere.enabled true &&
 208    git checkout stash1 &&
 209    echo "Conflicting stash content" >file11 &&
 210    git stash &&
 211
 212    git checkout --detach stash2 &&
 213    test_must_fail git stash apply &&
 214
 215    test -n "$(git ls-files -u)" &&
 216    conflicts="$(git rerere remaining)" &&
 217    test "$conflicts" = "file11" &&
 218    output="$(git mergetool --no-prompt)" &&
 219    test "$output" != "No files need merging" &&
 220
 221    git commit -am "save the stash resolution" &&
 222
 223    git reset --hard stash2 &&
 224    test_must_fail git stash apply &&
 225
 226    test -n "$(git ls-files -u)" &&
 227    conflicts="$(git rerere remaining)" &&
 228    test -z "$conflicts" &&
 229    output="$(git mergetool --no-prompt)" &&
 230    test "$output" = "No files need merging"
 231'
 232
 233test_expect_success 'mergetool takes partial path' '
 234    git reset --hard
 235    git config rerere.enabled false &&
 236    git checkout -b test12 branch1 &&
 237    git submodule update -N &&
 238    test_must_fail git merge master &&
 239
 240    #shouldnt need these lines
 241    #( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
 242    #( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
 243    #( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
 244    #( yes "" | git mergetool file1 file2 >/dev/null 2>&1 ) &&
 245
 246    ( yes "" | git mergetool subdir ) &&
 247
 248    test "$(cat subdir/file3)" = "master new sub" &&
 249    git reset --hard
 250'
 251
 252test_expect_success 'deleted vs modified submodule' '
 253    git checkout -b test6 branch1 &&
 254    git submodule update -N &&
 255    mv submod submod-movedaside &&
 256    git rm submod &&
 257    git commit -m "Submodule deleted from branch" &&
 258    git checkout -b test6.a test6 &&
 259    test_must_fail git merge master &&
 260    test -n "$(git ls-files -u)" &&
 261    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 262    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 263    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 264    ( yes "r" | git mergetool submod ) &&
 265    rmdir submod && mv submod-movedaside submod &&
 266    test "$(cat submod/bar)" = "branch1 submodule" &&
 267    git submodule update -N &&
 268    test "$(cat submod/bar)" = "master submodule" &&
 269    output="$(git mergetool --no-prompt)" &&
 270    test "$output" = "No files need merging" &&
 271    git commit -m "Merge resolved by keeping module" &&
 272
 273    mv submod submod-movedaside &&
 274    git checkout -b test6.b test6 &&
 275    git submodule update -N &&
 276    test_must_fail git merge master &&
 277    test -n "$(git ls-files -u)" &&
 278    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 279    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 280    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 281    ( yes "l" | git mergetool submod ) &&
 282    test ! -e submod &&
 283    output="$(git mergetool --no-prompt)" &&
 284    test "$output" = "No files need merging" &&
 285    git commit -m "Merge resolved by deleting module" &&
 286
 287    mv submod-movedaside submod &&
 288    git checkout -b test6.c master &&
 289    git submodule update -N &&
 290    test_must_fail git merge test6 &&
 291    test -n "$(git ls-files -u)" &&
 292    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 293    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 294    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 295    ( yes "r" | git mergetool submod ) &&
 296    test ! -e submod &&
 297    test -d submod.orig &&
 298    git submodule update -N &&
 299    output="$(git mergetool --no-prompt)" &&
 300    test "$output" = "No files need merging" &&
 301    git commit -m "Merge resolved by deleting module" &&
 302    mv submod.orig submod &&
 303
 304    git checkout -b test6.d master &&
 305    git submodule update -N &&
 306    test_must_fail git merge test6 &&
 307    test -n "$(git ls-files -u)" &&
 308    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 309    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 310    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 311    ( yes "l" | git mergetool submod ) &&
 312    test "$(cat submod/bar)" = "master submodule" &&
 313    git submodule update -N &&
 314    test "$(cat submod/bar)" = "master submodule" &&
 315    output="$(git mergetool --no-prompt)" &&
 316    test "$output" = "No files need merging" &&
 317    git commit -m "Merge resolved by keeping module" &&
 318    git reset --hard HEAD
 319'
 320
 321test_expect_success 'file vs modified submodule' '
 322    git checkout -b test7 branch1 &&
 323    git submodule update -N &&
 324    mv submod submod-movedaside &&
 325    git rm submod &&
 326    echo not a submodule >submod &&
 327    git add submod &&
 328    git commit -m "Submodule path becomes file" &&
 329    git checkout -b test7.a branch1 &&
 330    test_must_fail git merge master &&
 331    test -n "$(git ls-files -u)" &&
 332    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 333    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 334    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 335    ( yes "r" | git mergetool submod ) &&
 336    rmdir submod && mv submod-movedaside submod &&
 337    test "$(cat submod/bar)" = "branch1 submodule" &&
 338    git submodule update -N &&
 339    test "$(cat submod/bar)" = "master submodule" &&
 340    output="$(git mergetool --no-prompt)" &&
 341    test "$output" = "No files need merging" &&
 342    git commit -m "Merge resolved by keeping module" &&
 343
 344    mv submod submod-movedaside &&
 345    git checkout -b test7.b test7 &&
 346    test_must_fail git merge master &&
 347    test -n "$(git ls-files -u)" &&
 348    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 349    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 350    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 351    ( yes "l" | git mergetool submod ) &&
 352    git submodule update -N &&
 353    test "$(cat submod)" = "not a submodule" &&
 354    output="$(git mergetool --no-prompt)" &&
 355    test "$output" = "No files need merging" &&
 356    git commit -m "Merge resolved by keeping file" &&
 357
 358    git checkout -b test7.c master &&
 359    rmdir submod && mv submod-movedaside submod &&
 360    test ! -e submod.orig &&
 361    git submodule update -N &&
 362    test_must_fail git merge test7 &&
 363    test -n "$(git ls-files -u)" &&
 364    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 365    ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
 366    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 367    ( yes "r" | git mergetool submod ) &&
 368    test -d submod.orig &&
 369    git submodule update -N &&
 370    test "$(cat submod)" = "not a submodule" &&
 371    output="$(git mergetool --no-prompt)" &&
 372    test "$output" = "No files need merging" &&
 373    git commit -m "Merge resolved by keeping file" &&
 374
 375    git checkout -b test7.d master &&
 376    rmdir submod && mv submod.orig submod &&
 377    git submodule update -N &&
 378    test_must_fail git merge test7 &&
 379    test -n "$(git ls-files -u)" &&
 380    ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
 381    ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
 382    ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
 383    ( yes "l" | git mergetool submod ) &&
 384    test "$(cat submod/bar)" = "master submodule" &&
 385    git submodule update -N &&
 386    test "$(cat submod/bar)" = "master submodule" &&
 387    output="$(git mergetool --no-prompt)" &&
 388    test "$output" = "No files need merging" &&
 389    git commit -m "Merge resolved by keeping module"
 390'
 391
 392test_expect_success 'submodule in subdirectory' '
 393    git checkout -b test10 branch1 &&
 394    git submodule update -N &&
 395    (
 396        cd subdir &&
 397        test_create_repo subdir_module &&
 398        (
 399            cd subdir_module &&
 400            : >file15 &&
 401            git add file15 &&
 402            git commit -m "add initial versions"
 403        )
 404    ) &&
 405    git submodule add git://example.com/subsubmodule subdir/subdir_module &&
 406    git add subdir/subdir_module &&
 407    git commit -m "add submodule in subdirectory" &&
 408
 409    git checkout -b test10.a test10 &&
 410    git submodule update -N &&
 411    (
 412        cd subdir/subdir_module &&
 413        git checkout -b super10.a &&
 414        echo test10.a >file15 &&
 415        git add file15 &&
 416        git commit -m "on branch 10.a"
 417    ) &&
 418    git add subdir/subdir_module &&
 419    git commit -m "change submodule in subdirectory on test10.a" &&
 420
 421    git checkout -b test10.b test10 &&
 422    git submodule update -N &&
 423    (
 424        cd subdir/subdir_module &&
 425        git checkout -b super10.b &&
 426        echo test10.b >file15 &&
 427        git add file15 &&
 428        git commit -m "on branch 10.b"
 429    ) &&
 430    git add subdir/subdir_module &&
 431    git commit -m "change submodule in subdirectory on test10.b" &&
 432
 433    test_must_fail git merge test10.a >/dev/null 2>&1 &&
 434    (
 435        cd subdir &&
 436        ( yes "l" | git mergetool subdir_module )
 437    ) &&
 438    test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
 439    git submodule update -N &&
 440    test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
 441    git reset --hard &&
 442    git submodule update -N &&
 443
 444    test_must_fail git merge test10.a >/dev/null 2>&1 &&
 445    ( yes "r" | git mergetool subdir/subdir_module ) &&
 446    test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
 447    git submodule update -N &&
 448    test "$(cat subdir/subdir_module/file15)" = "test10.a" &&
 449    git commit -m "branch1 resolved with mergetool" &&
 450    rm -rf subdir/subdir_module
 451'
 452
 453test_expect_success 'directory vs modified submodule' '
 454    git checkout -b test11 branch1 &&
 455    mv submod submod-movedaside &&
 456    git rm submod &&
 457    mkdir submod &&
 458    echo not a submodule >submod/file16 &&
 459    git add submod/file16 &&
 460    git commit -m "Submodule path becomes directory" &&
 461
 462    test_must_fail git merge master &&
 463    test -n "$(git ls-files -u)" &&
 464    ( yes "l" | git mergetool submod ) &&
 465    test "$(cat submod/file16)" = "not a submodule" &&
 466    rm -rf submod.orig &&
 467
 468    git reset --hard >/dev/null 2>&1 &&
 469    test_must_fail git merge master &&
 470    test -n "$(git ls-files -u)" &&
 471    test ! -e submod.orig &&
 472    ( yes "r" | git mergetool submod ) &&
 473    test -d submod.orig &&
 474    test "$(cat submod.orig/file16)" = "not a submodule" &&
 475    rm -r submod.orig &&
 476    mv submod-movedaside/.git submod &&
 477    ( cd submod && git clean -f && git reset --hard ) &&
 478    git submodule update -N &&
 479    test "$(cat submod/bar)" = "master submodule" &&
 480    git reset --hard >/dev/null 2>&1 && rm -rf submod-movedaside &&
 481
 482    git checkout -b test11.c master &&
 483    git submodule update -N &&
 484    test_must_fail git merge test11 &&
 485    test -n "$(git ls-files -u)" &&
 486    ( yes "l" | git mergetool submod ) &&
 487    git submodule update -N &&
 488    test "$(cat submod/bar)" = "master submodule" &&
 489
 490    git reset --hard >/dev/null 2>&1 &&
 491    git submodule update -N &&
 492    test_must_fail git merge test11 &&
 493    test -n "$(git ls-files -u)" &&
 494    test ! -e submod.orig &&
 495    ( yes "r" | git mergetool submod ) &&
 496    test "$(cat submod/file16)" = "not a submodule" &&
 497
 498    git reset --hard master >/dev/null 2>&1 &&
 499    ( cd submod && git clean -f && git reset --hard ) &&
 500    git submodule update -N
 501'
 502
 503test_expect_success 'file with no base' '
 504    git checkout -b test13 branch1 &&
 505    test_must_fail git merge master &&
 506    git mergetool --no-prompt --tool mybase -- both &&
 507    >expected &&
 508    test_cmp both expected &&
 509    git reset --hard master >/dev/null 2>&1
 510'
 511
 512test_expect_success 'custom commands override built-ins' '
 513    git checkout -b test14 branch1 &&
 514    git config mergetool.defaults.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
 515    git config mergetool.defaults.trustExitCode true &&
 516    test_must_fail git merge master &&
 517    git mergetool --no-prompt --tool defaults -- both &&
 518    echo master both added >expected &&
 519    test_cmp both expected &&
 520    git config --unset mergetool.defaults.cmd &&
 521    git config --unset mergetool.defaults.trustExitCode &&
 522    git reset --hard master >/dev/null 2>&1
 523'
 524
 525test_done