t / t1001-read-tree-m-2way.shon commit Make the tab width used for whitespace checks configurable (f4b05a4)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5
   6test_description='Two way merge with read-tree -m $H $M
   7
   8This test tries two-way merge (aka fast-forward with carry forward).
   9
  10There is the head (called H) and another commit (called M), which is
  11simply ahead of H.  The index and the work tree contains a state that
  12is derived from H, but may also have local changes.  This test checks
  13all the combinations described in the two-tree merge "carry forward"
  14rules, found in <Documentation/git read-tree.txt>.
  15
  16In the test, these paths are used:
  17        bozbar  - in H, stays in M, modified from bozbar to gnusto
  18        frotz   - not in H added in M
  19        nitfol  - in H, stays in M unmodified
  20        rezrov  - in H, deleted in M
  21        yomin   - not in H nor M
  22'
  23. ./test-lib.sh
  24
  25read_tree_twoway () {
  26    git read-tree -m "$1" "$2" && git ls-files --stage
  27}
  28
  29compare_change () {
  30        sed -n >current \
  31            -e '/^--- /d; /^+++ /d; /^@@ /d;' \
  32            -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
  33            "$1"
  34        test_cmp expected current
  35}
  36
  37check_cache_at () {
  38        clean_if_empty=`git diff-files -- "$1"`
  39        case "$clean_if_empty" in
  40        '')  echo "$1: clean" ;;
  41        ?*)  echo "$1: dirty" ;;
  42        esac
  43        case "$2,$clean_if_empty" in
  44        clean,)         :     ;;
  45        clean,?*)       false ;;
  46        dirty,)         false ;;
  47        dirty,?*)       :     ;;
  48        esac
  49}
  50
  51cat >bozbar-old <<\EOF
  52This is a sample file used in two-way fast-forward merge
  53tests.  Its second line ends with a magic word bozbar
  54which will be modified by the merged head to gnusto.
  55It has some extra lines so that external tools can
  56successfully merge independent changes made to later
  57lines (such as this one), avoiding line conflicts.
  58EOF
  59
  60sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
  61
  62test_expect_success \
  63    setup \
  64    'echo frotz >frotz &&
  65     echo nitfol >nitfol &&
  66     cat bozbar-old >bozbar &&
  67     echo rezrov >rezrov &&
  68     echo yomin >yomin &&
  69     git update-index --add nitfol bozbar rezrov &&
  70     treeH=`git write-tree` &&
  71     echo treeH $treeH &&
  72     git ls-tree $treeH &&
  73
  74     cat bozbar-new >bozbar &&
  75     git update-index --add frotz bozbar --force-remove rezrov &&
  76     git ls-files --stage >M.out &&
  77     treeM=`git write-tree` &&
  78     echo treeM $treeM &&
  79     git ls-tree $treeM &&
  80     git diff-tree $treeH $treeM'
  81
  82test_expect_success \
  83    '1, 2, 3 - no carry forward' \
  84    'rm -f .git/index &&
  85     read_tree_twoway $treeH $treeM &&
  86     git ls-files --stage >1-3.out &&
  87     test_cmp M.out 1-3.out &&
  88     check_cache_at bozbar dirty &&
  89     check_cache_at frotz dirty &&
  90     check_cache_at nitfol dirty'
  91
  92echo '+100644 X 0       yomin' >expected
  93
  94test_expect_success \
  95    '4 - carry forward local addition.' \
  96    'rm -f .git/index &&
  97     git read-tree $treeH &&
  98     git checkout-index -u -f -q -a &&
  99     git update-index --add yomin &&
 100     read_tree_twoway $treeH $treeM &&
 101     git ls-files --stage >4.out &&
 102     test_must_fail git diff --no-index M.out 4.out >4diff.out &&
 103     compare_change 4diff.out expected &&
 104     check_cache_at yomin clean'
 105
 106test_expect_success \
 107    '5 - carry forward local addition.' \
 108    'rm -f .git/index &&
 109     git read-tree $treeH &&
 110     git checkout-index -u -f -q -a &&
 111     echo yomin >yomin &&
 112     git update-index --add yomin &&
 113     echo yomin yomin >yomin &&
 114     read_tree_twoway $treeH $treeM &&
 115     git ls-files --stage >5.out &&
 116     test_must_fail git diff --no-index M.out 5.out >5diff.out &&
 117     compare_change 5diff.out expected &&
 118     check_cache_at yomin dirty'
 119
 120test_expect_success \
 121    '6 - local addition already has the same.' \
 122    'rm -f .git/index &&
 123     git read-tree $treeH &&
 124     git checkout-index -u -f -q -a &&
 125     git update-index --add frotz &&
 126     read_tree_twoway $treeH $treeM &&
 127     git ls-files --stage >6.out &&
 128     test_cmp M.out 6.out &&
 129     check_cache_at frotz clean'
 130
 131test_expect_success \
 132    '7 - local addition already has the same.' \
 133    'rm -f .git/index &&
 134     git read-tree $treeH &&
 135     git checkout-index -u -f -q -a &&
 136     echo frotz >frotz &&
 137     git update-index --add frotz &&
 138     echo frotz frotz >frotz &&
 139     read_tree_twoway $treeH $treeM &&
 140     git ls-files --stage >7.out &&
 141     test_cmp M.out 7.out &&
 142     check_cache_at frotz dirty'
 143
 144test_expect_success \
 145    '8 - conflicting addition.' \
 146    'rm -f .git/index &&
 147     git read-tree $treeH &&
 148     git checkout-index -u -f -q -a &&
 149     echo frotz frotz >frotz &&
 150     git update-index --add frotz &&
 151     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 152
 153test_expect_success \
 154    '9 - conflicting addition.' \
 155    'rm -f .git/index &&
 156     git read-tree $treeH &&
 157     git checkout-index -u -f -q -a &&
 158     echo frotz frotz >frotz &&
 159     git update-index --add frotz &&
 160     echo frotz >frotz &&
 161     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 162
 163test_expect_success \
 164    '10 - path removed.' \
 165    'rm -f .git/index &&
 166     git read-tree $treeH &&
 167     git checkout-index -u -f -q -a &&
 168     echo rezrov >rezrov &&
 169     git update-index --add rezrov &&
 170     read_tree_twoway $treeH $treeM &&
 171     git ls-files --stage >10.out &&
 172     test_cmp M.out 10.out'
 173
 174test_expect_success \
 175    '11 - dirty path removed.' \
 176    'rm -f .git/index &&
 177     git read-tree $treeH &&
 178     git checkout-index -u -f -q -a &&
 179     echo rezrov >rezrov &&
 180     git update-index --add rezrov &&
 181     echo rezrov rezrov >rezrov &&
 182     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 183
 184test_expect_success \
 185    '12 - unmatching local changes being removed.' \
 186    'rm -f .git/index &&
 187     git read-tree $treeH &&
 188     git checkout-index -u -f -q -a &&
 189     echo rezrov rezrov >rezrov &&
 190     git update-index --add rezrov &&
 191     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 192
 193test_expect_success \
 194    '13 - unmatching local changes being removed.' \
 195    'rm -f .git/index &&
 196     git read-tree $treeH &&
 197     git checkout-index -u -f -q -a &&
 198     echo rezrov rezrov >rezrov &&
 199     git update-index --add rezrov &&
 200     echo rezrov >rezrov &&
 201     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 202
 203cat >expected <<EOF
 204-100644 X 0     nitfol
 205+100644 X 0     nitfol
 206EOF
 207
 208test_expect_success \
 209    '14 - unchanged in two heads.' \
 210    'rm -f .git/index &&
 211     git read-tree $treeH &&
 212     git checkout-index -u -f -q -a &&
 213     echo nitfol nitfol >nitfol &&
 214     git update-index --add nitfol &&
 215     read_tree_twoway $treeH $treeM &&
 216     git ls-files --stage >14.out &&
 217     test_must_fail git diff --no-index M.out 14.out >14diff.out &&
 218     compare_change 14diff.out expected &&
 219     check_cache_at nitfol clean'
 220
 221test_expect_success \
 222    '15 - unchanged in two heads.' \
 223    'rm -f .git/index &&
 224     git read-tree $treeH &&
 225     git checkout-index -u -f -q -a &&
 226     echo nitfol nitfol >nitfol &&
 227     git update-index --add nitfol &&
 228     echo nitfol nitfol nitfol >nitfol &&
 229     read_tree_twoway $treeH $treeM &&
 230     git ls-files --stage >15.out &&
 231     test_must_fail git diff --no-index M.out 15.out >15diff.out &&
 232     compare_change 15diff.out expected &&
 233     check_cache_at nitfol dirty'
 234
 235test_expect_success \
 236    '16 - conflicting local change.' \
 237    'rm -f .git/index &&
 238     git read-tree $treeH &&
 239     git checkout-index -u -f -q -a &&
 240     echo bozbar bozbar >bozbar &&
 241     git update-index --add bozbar &&
 242     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 243
 244test_expect_success \
 245    '17 - conflicting local change.' \
 246    'rm -f .git/index &&
 247     git read-tree $treeH &&
 248     git checkout-index -u -f -q -a &&
 249     echo bozbar bozbar >bozbar &&
 250     git update-index --add bozbar &&
 251     echo bozbar bozbar bozbar >bozbar &&
 252     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 253
 254test_expect_success \
 255    '18 - local change already having a good result.' \
 256    'rm -f .git/index &&
 257     git read-tree $treeH &&
 258     git checkout-index -u -f -q -a &&
 259     cat bozbar-new >bozbar &&
 260     git update-index --add bozbar &&
 261     read_tree_twoway $treeH $treeM &&
 262     git ls-files --stage >18.out &&
 263     test_cmp M.out 18.out &&
 264     check_cache_at bozbar clean'
 265
 266test_expect_success \
 267    '19 - local change already having a good result, further modified.' \
 268    'rm -f .git/index &&
 269     git read-tree $treeH &&
 270     git checkout-index -u -f -q -a &&
 271     cat bozbar-new >bozbar &&
 272     git update-index --add bozbar &&
 273     echo gnusto gnusto >bozbar &&
 274     read_tree_twoway $treeH $treeM &&
 275     git ls-files --stage >19.out &&
 276     test_cmp M.out 19.out &&
 277     check_cache_at bozbar dirty'
 278
 279test_expect_success \
 280    '20 - no local change, use new tree.' \
 281    'rm -f .git/index &&
 282     git read-tree $treeH &&
 283     git checkout-index -u -f -q -a &&
 284     cat bozbar-old >bozbar &&
 285     git update-index --add bozbar &&
 286     read_tree_twoway $treeH $treeM &&
 287     git ls-files --stage >20.out &&
 288     test_cmp M.out 20.out &&
 289     check_cache_at bozbar dirty'
 290
 291test_expect_success \
 292    '21 - no local change, dirty cache.' \
 293    'rm -f .git/index &&
 294     git read-tree $treeH &&
 295     git checkout-index -u -f -q -a &&
 296     cat bozbar-old >bozbar &&
 297     git update-index --add bozbar &&
 298     echo gnusto gnusto >bozbar &&
 299     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 300
 301# This fails with straight two-way fast-forward.
 302test_expect_success \
 303    '22 - local change cache updated.' \
 304    'rm -f .git/index &&
 305     git read-tree $treeH &&
 306     git checkout-index -u -f -q -a &&
 307     sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
 308     git update-index --add bozbar &&
 309     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 310
 311# Also make sure we did not break DF vs DF/DF case.
 312test_expect_success \
 313    'DF vs DF/DF case setup.' \
 314    'rm -f .git/index &&
 315     echo DF >DF &&
 316     git update-index --add DF &&
 317     treeDF=`git write-tree` &&
 318     echo treeDF $treeDF &&
 319     git ls-tree $treeDF &&
 320
 321     rm -f DF &&
 322     mkdir DF &&
 323     echo DF/DF >DF/DF &&
 324     git update-index --add --remove DF DF/DF &&
 325     treeDFDF=`git write-tree` &&
 326     echo treeDFDF $treeDFDF &&
 327     git ls-tree $treeDFDF &&
 328     git ls-files --stage >DFDF.out'
 329
 330test_expect_success \
 331    'DF vs DF/DF case test.' \
 332    'rm -f .git/index &&
 333     rm -fr DF &&
 334     echo DF >DF &&
 335     git update-index --add DF &&
 336     read_tree_twoway $treeDF $treeDFDF &&
 337     git ls-files --stage >DFDFcheck.out &&
 338     test_cmp DFDF.out DFDFcheck.out &&
 339     check_cache_at DF/DF dirty &&
 340     :'
 341
 342test_expect_success \
 343    'a/b (untracked) vs a case setup.' \
 344    'rm -f .git/index &&
 345     : >a &&
 346     git update-index --add a &&
 347     treeM=`git write-tree` &&
 348     echo treeM $treeM &&
 349     git ls-tree $treeM &&
 350     git ls-files --stage >treeM.out &&
 351
 352     rm -f a &&
 353     git update-index --remove a &&
 354     mkdir a &&
 355     : >a/b &&
 356     treeH=`git write-tree` &&
 357     echo treeH $treeH &&
 358     git ls-tree $treeH'
 359
 360test_expect_success \
 361    'a/b (untracked) vs a, plus c/d case test.' \
 362    'test_must_fail git read-tree -u -m "$treeH" "$treeM" &&
 363     git ls-files --stage &&
 364     test -f a/b'
 365
 366test_expect_success \
 367    'a/b vs a, plus c/d case setup.' \
 368    'rm -f .git/index &&
 369     rm -fr a &&
 370     : >a &&
 371     mkdir c &&
 372     : >c/d &&
 373     git update-index --add a c/d &&
 374     treeM=`git write-tree` &&
 375     echo treeM $treeM &&
 376     git ls-tree $treeM &&
 377     git ls-files --stage >treeM.out &&
 378
 379     rm -f a &&
 380     mkdir a &&
 381     : >a/b &&
 382     git update-index --add --remove a a/b &&
 383     treeH=`git write-tree` &&
 384     echo treeH $treeH &&
 385     git ls-tree $treeH'
 386
 387test_expect_success \
 388    'a/b vs a, plus c/d case test.' \
 389    'git read-tree -u -m "$treeH" "$treeM" &&
 390     git ls-files --stage | tee >treeMcheck.out &&
 391     test_cmp treeM.out treeMcheck.out'
 392
 393test_expect_success '-m references the correct modified tree' '
 394        echo >file-a &&
 395        echo >file-b &&
 396        git add file-a file-b &&
 397        git commit -a -m "test for correct modified tree" &&
 398        git branch initial-mod &&
 399        echo b >file-b &&
 400        git commit -a -m "B" &&
 401        echo a >file-a &&
 402        git add file-a &&
 403        git ls-tree $(git write-tree) file-a >expect &&
 404        git read-tree -m HEAD initial-mod &&
 405        git ls-tree $(git write-tree) file-a >actual &&
 406        test_cmp expect actual
 407'
 408
 409test_done