t / t1005-read-tree-m-2way-emu23.shon commit Abstract out the "name <email> date" handling of commit-tree.c (6aa33f4)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Junio C Hamano
   4#
   5
   6test_description='Two way merge with read-tree --emu23 $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-rev-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 --emu23 "$1" "$2" &&
  27    git-ls-files --stage &&
  28    git-merge-cache git-merge-one-file-script -a &&
  29    git-ls-files --stage
  30}
  31
  32_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
  33_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
  34compare_change () {
  35        sed -n >current \
  36            -e '/^--- /d; /^+++ /d; /^@@ /d;' \
  37            -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
  38            "$1"
  39        diff -u expected current
  40}
  41
  42check_cache_at () {
  43        clean_if_empty=`git-diff-files "$1"`
  44        case "$clean_if_empty" in
  45        '')  echo "$1: clean" ;;
  46        ?*)  echo "$1: dirty" ;;
  47        esac
  48        case "$2,$clean_if_empty" in
  49        clean,)         :     ;;
  50        clean,?*)       false ;;
  51        dirty,)         false ;;
  52        dirty,?*)       :     ;;
  53        esac
  54}
  55
  56check_stages () {
  57    cat >expected_stages
  58    git-ls-files --stage | sed -e "s/ $_x40 / X /" >current_stages
  59    diff -u expected_stages current_stages
  60}
  61
  62cat >bozbar-old <<\EOF
  63This is a sample file used in two-way fast forward merge
  64tests.  Its second line ends with a magic word bozbar
  65which will be modified by the merged head to gnusto.
  66It has some extra lines so that external tools can
  67successfully merge independent changes made to later
  68lines (such as this one), avoiding line conflicts.
  69EOF
  70
  71sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
  72
  73test_expect_success \
  74    setup \
  75    'echo frotz >frotz &&
  76     echo nitfol >nitfol &&
  77     cat bozbar-old >bozbar &&
  78     echo rezrov >rezrov &&
  79     echo yomin >yomin &&
  80     git-update-cache --add nitfol bozbar rezrov &&
  81     treeH=`git-write-tree` &&
  82     echo treeH $treeH &&
  83     git-ls-tree $treeH &&
  84
  85     cat bozbar-new >bozbar &&
  86     git-update-cache --add frotz bozbar --force-remove rezrov &&
  87     git-ls-files --stage >M.out &&
  88     treeM=`git-write-tree` &&
  89     echo treeM $treeM &&
  90     git-ls-tree $treeM &&
  91     git-diff-tree $treeH $treeM'
  92
  93# "read-tree -m H I+H M" but I is empty so this is "read-tree -m H H M".
  94#
  95# bozbar [O && A && B && O==A && O!=B (#14) ==> B] take M by read-tree
  96# frotz  [!O && !A && B (#2) ==> B]                take M by read-tree
  97# nitfol [O && A && B && O==A && O==B (#15) ==> B] take M by read-tree
  98# rezrov [O && A && !B && O==A (#10) ==> no merge] removed by script
  99#
 100# Earlier one did not have #2ALT so taking M was done by the script,
 101# which also updated the work tree and making frotz clean.  With #2ALT,
 102# this is resolved by read-tree itself and the path is left dirty
 103# because we are not testing "read-tree -u --emu23".
 104test_expect_success \
 105    '1, 2, 3 - no carry forward' \
 106    'rm -f .git/index &&
 107     read_tree_twoway $treeH $treeM &&
 108     git-ls-files --stage >1-3.out &&
 109     diff -u M.out 1-3.out &&
 110     check_cache_at bozbar dirty &&
 111     check_cache_at frotz dirty && # same as pure 2-way again.
 112     check_cache_at nitfol dirty'
 113
 114echo '+100644 X 0       yomin' >expected
 115
 116test_expect_success \
 117    '4 - carry forward local addition.' \
 118    'rm -f .git/index &&
 119     git-read-tree $treeH &&
 120     git-checkout-cache -u -f -q -a &&
 121     git-update-cache --add yomin &&
 122     read_tree_twoway $treeH $treeM &&
 123     git-ls-files --stage >4.out || exit
 124     diff -u M.out 4.out >4diff.out
 125     compare_change 4diff.out expected &&
 126     check_cache_at yomin clean'
 127
 128# "read-tree -m H I+H M" where !H && !M; so (I+H) not being up-to-date
 129# should not matter.  Thanks to #3ALT, this is now possible.
 130test_expect_success \
 131    '5 - carry forward local addition.' \
 132    'rm -f .git/index &&
 133     git-read-tree $treeH &&
 134     git-checkout-cache -u -f -q -a &&
 135     echo yomin >yomin &&
 136     git-update-cache --add yomin &&
 137     echo yomin yomin >yomin &&
 138     read_tree_twoway $treeH $treeM &&
 139     git-ls-files --stage >5.out || exit
 140     diff -u M.out 5.out >5diff.out
 141     compare_change 5diff.out expected &&
 142     check_cache_at yomin dirty'
 143
 144# "read-tree -m H I+H M" where !H && M && (I+H) == M, so this should
 145# succeed (even the entry is clean), now thanks to #5ALT.
 146test_expect_success \
 147    '6 - local addition already has the same.' \
 148    'rm -f .git/index &&
 149     git-read-tree $treeH &&
 150     git-checkout-cache -u -f -q -a &&
 151     git-update-cache --add frotz &&
 152     read_tree_twoway $treeH $treeM &&
 153     git-ls-files --stage >6.out &&
 154     diff -u M.out 6.out &&
 155     check_cache_at frotz clean'
 156
 157# Exactly the same pattern as above but with dirty cache.  This also
 158# should succeed, now thanks to #5ALT.
 159test_expect_success \
 160    '7 - local addition already has the same.' \
 161    'rm -f .git/index &&
 162     git-read-tree $treeH &&
 163     git-checkout-cache -u -f -q -a &&
 164     echo frotz >frotz &&
 165     git-update-cache --add frotz &&
 166     echo frotz frotz >frotz &&
 167     read_tree_twoway $treeH $treeM &&
 168     git-ls-files --stage >7.out &&
 169     diff -u M.out 7.out &&
 170     check_cache_at frotz dirty'
 171
 172test_expect_success \
 173    '8 - conflicting addition.' \
 174    'rm -f .git/index &&
 175     git-read-tree $treeH &&
 176     git-checkout-cache -u -f -q -a &&
 177     echo frotz frotz >frotz &&
 178     git-update-cache --add frotz &&
 179     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 180
 181test_expect_success \
 182    '9 - conflicting addition.' \
 183    'rm -f .git/index &&
 184     git-read-tree $treeH &&
 185     git-checkout-cache -u -f -q -a &&
 186     echo frotz frotz >frotz &&
 187     git-update-cache --add frotz &&
 188     echo frotz >frotz &&
 189     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 190
 191test_expect_success \
 192    '10 - path removed.' \
 193    'rm -f .git/index &&
 194     git-read-tree $treeH &&
 195     git-checkout-cache -u -f -q -a &&
 196     echo rezrov >rezrov &&
 197     git-update-cache --add rezrov &&
 198     read_tree_twoway $treeH $treeM &&
 199     git-ls-files --stage >10.out &&
 200     diff -u M.out 10.out'
 201
 202test_expect_success \
 203    '11 - dirty path removed.' \
 204    'rm -f .git/index &&
 205     git-read-tree $treeH &&
 206     git-checkout-cache -u -f -q -a &&
 207     echo rezrov >rezrov &&
 208     git-update-cache --add rezrov &&
 209     echo rezrov rezrov >rezrov &&
 210     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 211
 212test_expect_success \
 213    '12 - unmatching local changes being removed.' \
 214    'rm -f .git/index &&
 215     git-read-tree $treeH &&
 216     git-checkout-cache -u -f -q -a &&
 217     echo rezrov rezrov >rezrov &&
 218     git-update-cache --add rezrov &&
 219     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 220
 221test_expect_success \
 222    '13 - unmatching local changes being removed.' \
 223    'rm -f .git/index &&
 224     git-read-tree $treeH &&
 225     git-checkout-cache -u -f -q -a &&
 226     echo rezrov rezrov >rezrov &&
 227     git-update-cache --add rezrov &&
 228     echo rezrov >rezrov &&
 229     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 230
 231cat >expected <<EOF
 232-100644 X 0     nitfol
 233+100644 X 0     nitfol
 234EOF
 235
 236test_expect_success \
 237    '14 - unchanged in two heads.' \
 238    'rm -f .git/index &&
 239     git-read-tree $treeH &&
 240     git-checkout-cache -u -f -q -a &&
 241     echo nitfol nitfol >nitfol &&
 242     git-update-cache --add nitfol &&
 243     read_tree_twoway $treeH $treeM &&
 244     git-ls-files --stage >14.out || exit
 245     diff -u M.out 14.out >14diff.out
 246     compare_change 14diff.out expected &&
 247     check_cache_at nitfol clean'
 248
 249test_expect_success \
 250    '15 - unchanged in two heads.' \
 251    'rm -f .git/index &&
 252     git-read-tree $treeH &&
 253     git-checkout-cache -u -f -q -a &&
 254     echo nitfol nitfol >nitfol &&
 255     git-update-cache --add nitfol &&
 256     echo nitfol nitfol nitfol >nitfol &&
 257     read_tree_twoway $treeH $treeM &&
 258     git-ls-files --stage >15.out || exit
 259     diff -u M.out 15.out >15diff.out
 260     compare_change 15diff.out expected &&
 261     check_cache_at nitfol dirty'
 262
 263# This is different from straight 2-way merge in that it leaves
 264# three stages of bozbar in the index file without failing, so
 265# the user can run git-diff-stages to examine the situation.
 266# With #2ALT, frotz is resolved internally.
 267test_expect_success \
 268    '16 - conflicting local change.' \
 269    'rm -f .git/index &&
 270     git-read-tree $treeH &&
 271     git-checkout-cache -u -f -q -a &&
 272     echo bozbar bozbar >bozbar &&
 273     git-update-cache --add bozbar &&
 274     git-read-tree --emu23 $treeH $treeM &&
 275     check_stages' <<\EOF
 276100644 X 1      bozbar
 277100644 X 2      bozbar
 278100644 X 3      bozbar
 279100644 X 0      frotz
 280100644 X 0      nitfol
 281100644 X 1      rezrov
 282100644 X 2      rezrov
 283EOF
 284
 285test_expect_success \
 286    '17 - conflicting local change.' \
 287    'rm -f .git/index &&
 288     git-read-tree $treeH &&
 289     git-checkout-cache -u -f -q -a &&
 290     echo bozbar bozbar >bozbar &&
 291     git-update-cache --add bozbar &&
 292     echo bozbar bozbar bozbar >bozbar &&
 293     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 294
 295test_expect_success \
 296    '18 - local change already having a good result.' \
 297    'rm -f .git/index &&
 298     git-read-tree $treeH &&
 299     git-checkout-cache -u -f -q -a &&
 300     cat bozbar-new >bozbar &&
 301     git-update-cache --add bozbar &&
 302     read_tree_twoway $treeH $treeM &&
 303     git-ls-files --stage >18.out &&
 304     diff -u M.out 18.out &&
 305     check_cache_at bozbar clean'
 306
 307test_expect_success \
 308    '19 - local change already having a good result, further modified.' \
 309    'rm -f .git/index &&
 310     git-read-tree $treeH &&
 311     git-checkout-cache -u -f -q -a &&
 312     cat bozbar-new >bozbar &&
 313     git-update-cache --add bozbar &&
 314     echo gnusto gnusto >bozbar &&
 315     read_tree_twoway $treeH $treeM &&
 316     git-ls-files --stage >19.out &&
 317     diff -u M.out 19.out &&
 318     check_cache_at bozbar dirty'
 319
 320test_expect_success \
 321    '20 - no local change, use new tree.' \
 322    'rm -f .git/index &&
 323     git-read-tree $treeH &&
 324     git-checkout-cache -u -f -q -a &&
 325     cat bozbar-old >bozbar &&
 326     git-update-cache --add bozbar &&
 327     read_tree_twoway $treeH $treeM &&
 328     git-ls-files --stage >20.out &&
 329     diff -u M.out 20.out &&
 330     check_cache_at bozbar dirty'
 331
 332test_expect_success \
 333    '21 - no local change, dirty cache.' \
 334    'rm -f .git/index &&
 335     git-read-tree $treeH &&
 336     git-checkout-cache -u -f -q -a &&
 337     cat bozbar-old >bozbar &&
 338     git-update-cache --add bozbar &&
 339     echo gnusto gnusto >bozbar &&
 340     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 341
 342echo '-100644 X 0       bozbar
 343+100644 X 0     bozbar' >expected
 344
 345# This fails with straight two-way fast forward, but emu23
 346# can merge them.
 347test_expect_success \
 348    '22 - local change cache updated.' \
 349    'rm -f .git/index &&
 350     git-read-tree $treeH &&
 351     git-checkout-cache -u -f -q -a &&
 352     sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
 353     git-update-cache --add bozbar &&
 354     read_tree_twoway $treeH $treeM &&
 355     git-ls-files --stage >22.out || exit
 356     diff -u M.out 22.out >22diff.out
 357     compare_change 22diff.out &&
 358     check_cache_at bozbar clean'
 359
 360# Also make sure we did not break DF vs DF/DF case.
 361test_expect_success \
 362    'DF vs DF/DF case setup.' \
 363    'rm -f .git/index &&
 364     echo DF >DF &&
 365     git-update-cache --add DF &&
 366     treeDF=`git-write-tree` &&
 367     echo treeDF $treeDF &&
 368     git-ls-tree $treeDF &&
 369     git-ls-files --stage >DF.out
 370
 371     rm -f DF &&
 372     mkdir DF &&
 373     echo DF/DF >DF/DF &&
 374     git-update-cache --add --remove DF DF/DF &&
 375     treeDFDF=`git-write-tree` &&
 376     echo treeDFDF $treeDFDF &&
 377     git-ls-tree $treeDFDF &&
 378     git-ls-files --stage >DFDF.out'
 379
 380test_expect_success \
 381    'DF vs DF/DF case test (#1)' \
 382    'rm -f .git/index &&
 383     rm -fr DF &&
 384     echo DF >DF &&
 385     git-update-cache --add DF &&
 386     read_tree_twoway $treeDF $treeDFDF &&
 387     git-ls-files --stage >DFDFcheck.out &&
 388     diff -u DFDF.out DFDFcheck.out &&
 389     check_cache_at DF/DF clean && # different from pure 2-way
 390     :'
 391
 392# The other way around
 393test_expect_success \
 394    'DF vs DF/DF case test (#2)' \
 395    'rm -f .git/index &&
 396     rm -fr DF &&
 397     mkdir DF &&
 398     echo DF/DF >DF/DF &&
 399     git-update-cache --add DF/DF &&
 400     read_tree_twoway $treeDFDF $treeDF &&
 401     git-ls-files --stage >DFDFcheck.out &&
 402     diff -u DF.out DFDFcheck.out &&
 403     check_cache_at DF clean && # different from pure 2-way
 404     :'
 405
 406# Emu23 can grok I having more than H.  Make sure we did not
 407# botch the conflict tests (fixed).
 408test_expect_success \
 409    'DF vs DF/DF case test (#3).' \
 410    'rm -f .git/index &&
 411     rm -fr DF &&
 412     mkdir DF &&
 413     echo DF/DF >DF/DF &&
 414     git-update-cache --add DF/DF &&
 415     # This should fail because I and H have a conflict
 416     # at DF.
 417     if git-read-tree --emu23 $treeDF $treeDFDF
 418     then false
 419     else true
 420     fi'
 421
 422test_done