git-clone documentation
[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 _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"
31 compare_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
39 check_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
53 cat >bozbar-old <<\EOF
54 This is a sample file used in two-way fast forward merge
55 tests.  Its second line ends with a magic word bozbar
56 which will be modified by the merged head to gnusto.
57 It has some extra lines so that external tools can
58 successfully merge independent changes made to later
59 lines (such as this one), avoiding line conflicts.
60 EOF
61
62 sed -e 's/bozbar/gnusto (earlier bozbar)/' bozbar-old >bozbar-new
63
64 test_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
84 test_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
94 echo '+100644 X 0       yomin' >expected
95
96 test_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
108 test_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
122 test_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
133 test_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
146 test_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
155 test_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
165 test_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
176 test_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
186 test_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
195 test_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
205 cat >expected <<EOF
206 -100644 X 0     nitfol
207 +100644 X 0     nitfol
208 EOF
209
210 test_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
223 test_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
237 test_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
246 test_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
256 test_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
268 test_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
281 test_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
293 test_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.
304 test_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.
314 test_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
332 test_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
344 test_done