Merge branch 'jn/show-num-walks'
[git] / t / t1001-read-tree-m-2way.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5
6 test_description='Two way merge with read-tree -m $H $M
7
8 This test tries two-way merge (aka fast-forward with carry forward).
9
10 There is the head (called H) and another commit (called M), which is
11 simply ahead of H.  The index and the work tree contains a state that
12 is derived from H, but may also have local changes.  This test checks
13 all the combinations described in the two-tree merge "carry forward"
14 rules, found in <Documentation/git read-tree.txt>.
15
16 In 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
25 read_tree_twoway () {
26     git read-tree -m "$1" "$2" && git ls-files --stage
27 }
28
29 compare_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
37 check_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
51 cat >bozbar-old <<\EOF
52 This is a sample file used in two-way fast-forward merge
53 tests.  Its second line ends with a magic word bozbar
54 which will be modified by the merged head to gnusto.
55 It has some extra lines so that external tools can
56 successfully merge independent changes made to later
57 lines (such as this one), avoiding line conflicts.
58 EOF
59
60 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
61
62 test_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
82 test_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
92 echo '+100644 X 0       yomin' >expected
93
94 test_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 || return 1
102      git diff --no-index M.out 4.out >4diff.out
103      compare_change 4diff.out expected &&
104      check_cache_at yomin clean'
105
106 test_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 || return 1
116      git diff --no-index M.out 5.out >5diff.out
117      compare_change 5diff.out expected &&
118      check_cache_at yomin dirty'
119
120 test_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
131 test_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
144 test_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
153 test_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
163 test_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
174 test_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
184 test_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
193 test_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
203 cat >expected <<EOF
204 -100644 X 0     nitfol
205 +100644 X 0     nitfol
206 EOF
207
208 test_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 || return 1
217      git diff --no-index M.out 14.out >14diff.out
218      compare_change 14diff.out expected &&
219      check_cache_at nitfol clean'
220
221 test_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 || return 1
231      git diff --no-index M.out 15.out >15diff.out
232      compare_change 15diff.out expected &&
233      check_cache_at nitfol dirty'
234
235 test_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
244 test_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
254 test_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
266 test_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
279 test_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
291 test_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.
302 test_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.
312 test_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
330 test_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
342 test_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
360 test_expect_success \
361     'a/b (untracked) vs a, plus c/d case test.' \
362     '! git read-tree -u -m "$treeH" "$treeM" &&
363      git ls-files --stage &&
364      test -f a/b'
365
366 test_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
387 test_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
393 test_done