t / t1001-read-tree-m-2way.shon commit Merge git://git.kernel.org/pub/scm/gitk/gitk (67e31d6)
   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
  29_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
  30_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
  31compare_change () {
  32        sed -n >current \
  33            -e '/^--- /d; /^+++ /d; /^@@ /d;' \
  34            -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
  35            "$1"
  36        diff -u expected current
  37}
  38
  39check_cache_at () {
  40        clean_if_empty=`git-diff-files -- "$1"`
  41        case "$clean_if_empty" in
  42        '')  echo "$1: clean" ;;
  43        ?*)  echo "$1: dirty" ;;
  44        esac
  45        case "$2,$clean_if_empty" in
  46        clean,)         :     ;;
  47        clean,?*)       false ;;
  48        dirty,)         false ;;
  49        dirty,?*)       :     ;;
  50        esac
  51}
  52
  53cat >bozbar-old <<\EOF
  54This is a sample file used in two-way fast forward merge
  55tests.  Its second line ends with a magic word bozbar
  56which will be modified by the merged head to gnusto.
  57It has some extra lines so that external tools can
  58successfully merge independent changes made to later
  59lines (such as this one), avoiding line conflicts.
  60EOF
  61
  62sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
  63
  64test_expect_success \
  65    setup \
  66    'echo frotz >frotz &&
  67     echo nitfol >nitfol &&
  68     cat bozbar-old >bozbar &&
  69     echo rezrov >rezrov &&
  70     echo yomin >yomin &&
  71     git-update-index --add nitfol bozbar rezrov &&
  72     treeH=`git-write-tree` &&
  73     echo treeH $treeH &&
  74     git-ls-tree $treeH &&
  75
  76     cat bozbar-new >bozbar &&
  77     git-update-index --add frotz bozbar --force-remove rezrov &&
  78     git-ls-files --stage >M.out &&
  79     treeM=`git-write-tree` &&
  80     echo treeM $treeM &&
  81     git-ls-tree $treeM &&
  82     git-diff-tree $treeH $treeM'
  83
  84test_expect_success \
  85    '1, 2, 3 - no carry forward' \
  86    'rm -f .git/index &&
  87     read_tree_twoway $treeH $treeM &&
  88     git-ls-files --stage >1-3.out &&
  89     diff -u M.out 1-3.out &&
  90     check_cache_at bozbar dirty &&
  91     check_cache_at frotz dirty &&
  92     check_cache_at nitfol dirty'
  93
  94echo '+100644 X 0       yomin' >expected
  95
  96test_expect_success \
  97    '4 - carry forward local addition.' \
  98    'rm -f .git/index &&
  99     git-read-tree $treeH &&
 100     git-checkout-index -u -f -q -a &&
 101     git-update-index --add yomin &&
 102     read_tree_twoway $treeH $treeM &&
 103     git-ls-files --stage >4.out || return 1
 104     diff -u M.out 4.out >4diff.out
 105     compare_change 4diff.out expected &&
 106     check_cache_at yomin clean'
 107
 108test_expect_success \
 109    '5 - carry forward local addition.' \
 110    'rm -f .git/index &&
 111     git-read-tree $treeH &&
 112     git-checkout-index -u -f -q -a &&
 113     echo yomin >yomin &&
 114     git-update-index --add yomin &&
 115     echo yomin yomin >yomin &&
 116     read_tree_twoway $treeH $treeM &&
 117     git-ls-files --stage >5.out || return 1
 118     diff -u M.out 5.out >5diff.out
 119     compare_change 5diff.out expected &&
 120     check_cache_at yomin dirty'
 121
 122test_expect_success \
 123    '6 - local addition already has the same.' \
 124    'rm -f .git/index &&
 125     git-read-tree $treeH &&
 126     git-checkout-index -u -f -q -a &&
 127     git-update-index --add frotz &&
 128     read_tree_twoway $treeH $treeM &&
 129     git-ls-files --stage >6.out &&
 130     diff -u M.out 6.out &&
 131     check_cache_at frotz clean'
 132
 133test_expect_success \
 134    '7 - local addition already has the same.' \
 135    'rm -f .git/index &&
 136     git-read-tree $treeH &&
 137     git-checkout-index -u -f -q -a &&
 138     echo frotz >frotz &&
 139     git-update-index --add frotz &&
 140     echo frotz frotz >frotz &&
 141     read_tree_twoway $treeH $treeM &&
 142     git-ls-files --stage >7.out &&
 143     diff -u M.out 7.out &&
 144     check_cache_at frotz dirty'
 145
 146test_expect_success \
 147    '8 - conflicting addition.' \
 148    'rm -f .git/index &&
 149     git-read-tree $treeH &&
 150     git-checkout-index -u -f -q -a &&
 151     echo frotz frotz >frotz &&
 152     git-update-index --add frotz &&
 153     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 154
 155test_expect_success \
 156    '9 - conflicting addition.' \
 157    'rm -f .git/index &&
 158     git-read-tree $treeH &&
 159     git-checkout-index -u -f -q -a &&
 160     echo frotz frotz >frotz &&
 161     git-update-index --add frotz &&
 162     echo frotz >frotz &&
 163     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 164
 165test_expect_success \
 166    '10 - path removed.' \
 167    'rm -f .git/index &&
 168     git-read-tree $treeH &&
 169     git-checkout-index -u -f -q -a &&
 170     echo rezrov >rezrov &&
 171     git-update-index --add rezrov &&
 172     read_tree_twoway $treeH $treeM &&
 173     git-ls-files --stage >10.out &&
 174     diff -u M.out 10.out'
 175
 176test_expect_success \
 177    '11 - dirty path removed.' \
 178    'rm -f .git/index &&
 179     git-read-tree $treeH &&
 180     git-checkout-index -u -f -q -a &&
 181     echo rezrov >rezrov &&
 182     git-update-index --add rezrov &&
 183     echo rezrov rezrov >rezrov &&
 184     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 185
 186test_expect_success \
 187    '12 - unmatching local changes being removed.' \
 188    'rm -f .git/index &&
 189     git-read-tree $treeH &&
 190     git-checkout-index -u -f -q -a &&
 191     echo rezrov rezrov >rezrov &&
 192     git-update-index --add rezrov &&
 193     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 194
 195test_expect_success \
 196    '13 - unmatching local changes being removed.' \
 197    'rm -f .git/index &&
 198     git-read-tree $treeH &&
 199     git-checkout-index -u -f -q -a &&
 200     echo rezrov rezrov >rezrov &&
 201     git-update-index --add rezrov &&
 202     echo rezrov >rezrov &&
 203     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 204
 205cat >expected <<EOF
 206-100644 X 0     nitfol
 207+100644 X 0     nitfol
 208EOF
 209
 210test_expect_success \
 211    '14 - unchanged in two heads.' \
 212    'rm -f .git/index &&
 213     git-read-tree $treeH &&
 214     git-checkout-index -u -f -q -a &&
 215     echo nitfol nitfol >nitfol &&
 216     git-update-index --add nitfol &&
 217     read_tree_twoway $treeH $treeM &&
 218     git-ls-files --stage >14.out || return 1
 219     diff -u M.out 14.out >14diff.out
 220     compare_change 14diff.out expected &&
 221     check_cache_at nitfol clean'
 222
 223test_expect_success \
 224    '15 - unchanged in two heads.' \
 225    'rm -f .git/index &&
 226     git-read-tree $treeH &&
 227     git-checkout-index -u -f -q -a &&
 228     echo nitfol nitfol >nitfol &&
 229     git-update-index --add nitfol &&
 230     echo nitfol nitfol nitfol >nitfol &&
 231     read_tree_twoway $treeH $treeM &&
 232     git-ls-files --stage >15.out || return 1
 233     diff -u M.out 15.out >15diff.out
 234     compare_change 15diff.out expected &&
 235     check_cache_at nitfol dirty'
 236
 237test_expect_success \
 238    '16 - conflicting local change.' \
 239    'rm -f .git/index &&
 240     git-read-tree $treeH &&
 241     git-checkout-index -u -f -q -a &&
 242     echo bozbar bozbar >bozbar &&
 243     git-update-index --add bozbar &&
 244     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 245
 246test_expect_success \
 247    '17 - conflicting local change.' \
 248    'rm -f .git/index &&
 249     git-read-tree $treeH &&
 250     git-checkout-index -u -f -q -a &&
 251     echo bozbar bozbar >bozbar &&
 252     git-update-index --add bozbar &&
 253     echo bozbar bozbar bozbar >bozbar &&
 254     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 255
 256test_expect_success \
 257    '18 - local change already having a good result.' \
 258    'rm -f .git/index &&
 259     git-read-tree $treeH &&
 260     git-checkout-index -u -f -q -a &&
 261     cat bozbar-new >bozbar &&
 262     git-update-index --add bozbar &&
 263     read_tree_twoway $treeH $treeM &&
 264     git-ls-files --stage >18.out &&
 265     diff -u M.out 18.out &&
 266     check_cache_at bozbar clean'
 267
 268test_expect_success \
 269    '19 - local change already having a good result, further modified.' \
 270    'rm -f .git/index &&
 271     git-read-tree $treeH &&
 272     git-checkout-index -u -f -q -a &&
 273     cat bozbar-new >bozbar &&
 274     git-update-index --add bozbar &&
 275     echo gnusto gnusto >bozbar &&
 276     read_tree_twoway $treeH $treeM &&
 277     git-ls-files --stage >19.out &&
 278     diff -u M.out 19.out &&
 279     check_cache_at bozbar dirty'
 280
 281test_expect_success \
 282    '20 - no local change, use new tree.' \
 283    'rm -f .git/index &&
 284     git-read-tree $treeH &&
 285     git-checkout-index -u -f -q -a &&
 286     cat bozbar-old >bozbar &&
 287     git-update-index --add bozbar &&
 288     read_tree_twoway $treeH $treeM &&
 289     git-ls-files --stage >20.out &&
 290     diff -u M.out 20.out &&
 291     check_cache_at bozbar dirty'
 292
 293test_expect_success \
 294    '21 - no local change, dirty cache.' \
 295    'rm -f .git/index &&
 296     git-read-tree $treeH &&
 297     git-checkout-index -u -f -q -a &&
 298     cat bozbar-old >bozbar &&
 299     git-update-index --add bozbar &&
 300     echo gnusto gnusto >bozbar &&
 301     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 302
 303# This fails with straight two-way fast forward.
 304test_expect_success \
 305    '22 - local change cache updated.' \
 306    'rm -f .git/index &&
 307     git-read-tree $treeH &&
 308     git-checkout-index -u -f -q -a &&
 309     sed -e "s/such as/SUCH AS/" bozbar-old >bozbar &&
 310     git-update-index --add bozbar &&
 311     if read_tree_twoway $treeH $treeM; then false; else :; fi'
 312
 313# Also make sure we did not break DF vs DF/DF case.
 314test_expect_success \
 315    'DF vs DF/DF case setup.' \
 316    'rm -f .git/index &&
 317     echo DF >DF &&
 318     git-update-index --add DF &&
 319     treeDF=`git-write-tree` &&
 320     echo treeDF $treeDF &&
 321     git-ls-tree $treeDF &&
 322
 323     rm -f DF &&
 324     mkdir DF &&
 325     echo DF/DF >DF/DF &&
 326     git-update-index --add --remove DF DF/DF &&
 327     treeDFDF=`git-write-tree` &&
 328     echo treeDFDF $treeDFDF &&
 329     git-ls-tree $treeDFDF &&
 330     git-ls-files --stage >DFDF.out'
 331
 332test_expect_success \
 333    'DF vs DF/DF case test.' \
 334    'rm -f .git/index &&
 335     rm -fr DF &&
 336     echo DF >DF &&
 337     git-update-index --add DF &&
 338     read_tree_twoway $treeDF $treeDFDF &&
 339     git-ls-files --stage >DFDFcheck.out &&
 340     diff -u DFDF.out DFDFcheck.out &&
 341     check_cache_at DF/DF dirty &&
 342     :'
 343
 344test_done