3 # Copyright (c) 2005 Junio C Hamano
6 test_description='Two way merge with read-tree --emu23 $H $M
8 This test tries two-way merge (aka fast forward with carry forward).
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-rev-tree.txt>.
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
26 git-read-tree --emu23 "$1" "$2" &&
27 git-ls-files --stage &&
28 git-merge-cache git-merge-one-file-script -a &&
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"
37 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
38 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
40 diff -u expected current
44 clean_if_empty=`git-diff-files "$1"`
45 case "$clean_if_empty" in
46 '') echo "$1: clean" ;;
47 ?*) echo "$1: dirty" ;;
49 case "$2,$clean_if_empty" in
59 git-ls-files --stage | sed -e "s/ $_x40 / X /" >current_stages
60 diff -u expected_stages current_stages
66 echo nitfol >nitfol &&
67 echo bozbar >bozbar &&
68 echo rezrov >rezrov &&
70 git-update-cache --add nitfol bozbar rezrov &&
71 treeH=`git-write-tree` &&
75 echo gnusto >bozbar &&
76 git-update-cache --add frotz bozbar --force-remove rezrov &&
77 git-ls-files --stage >M.out &&
78 treeM=`git-write-tree` &&
81 git-diff-tree $treeH $treeM'
84 '1, 2, 3 - no carry forward' \
86 read_tree_twoway $treeH $treeM &&
87 git-ls-files --stage >1-3.out &&
88 diff -u M.out 1-3.out &&
89 check_cache_at bozbar dirty &&
90 check_cache_at frotz clean && # different from pure 2-way
91 check_cache_at nitfol dirty'
93 echo '+100644 X 0 yomin' >expected
96 '4 - carry forward local addition.' \
98 git-update-cache --add yomin &&
99 read_tree_twoway $treeH $treeM &&
100 git-ls-files --stage >4.out || exit
101 diff -u M.out 4.out >4diff.out
102 compare_change 4diff.out expected &&
103 check_cache_at yomin clean'
105 # "read-tree -m H I+H M" where !H && !M; so (I+H) not being up-to-date
106 # should not matter, but without #3ALT this does not work.
107 : test_expect_success \
108 '5 - carry forward local addition.' \
111 git-update-cache --add yomin &&
112 echo yomin yomin >yomin &&
113 read_tree_twoway $treeH $treeM &&
114 git-ls-files --stage >5.out || exit
115 diff -u M.out 5.out >5diff.out
116 compare_change 5diff.out expected &&
117 check_cache_at yomin dirty'
119 # "read-tree -m H I+H M" where !H && M && (I+H) == M, so this should
120 # succeed (even the entry is clean), now thanks to #5ALT.
121 test_expect_success \
122 '6 - local addition already has the same.' \
124 git-update-cache --add frotz &&
125 read_tree_twoway $treeH $treeM &&
126 git-ls-files --stage >6.out &&
127 diff -u M.out 6.out &&
128 check_cache_at frotz clean'
130 # Exactly the same pattern as above but with dirty cache. This also
131 # should succeed, now thanks to #5ALT.
132 test_expect_success \
133 '7 - local addition already has the same.' \
136 git-update-cache --add frotz &&
137 echo frotz frotz >frotz &&
138 read_tree_twoway $treeH $treeM &&
139 git-ls-files --stage >7.out &&
140 diff -u M.out 7.out &&
141 check_cache_at frotz dirty'
143 test_expect_success \
144 '8 - conflicting addition.' \
146 echo frotz frotz >frotz &&
147 git-update-cache --add frotz &&
148 if read_tree_twoway $treeH $treeM; then false; else :; fi'
150 test_expect_success \
151 '9 - conflicting addition.' \
153 echo frotz frotz >frotz &&
154 git-update-cache --add frotz &&
156 if read_tree_twoway $treeH $treeM; then false; else :; fi'
158 test_expect_success \
159 '10 - path removed.' \
161 echo rezrov >rezrov &&
162 git-update-cache --add rezrov &&
163 read_tree_twoway $treeH $treeM &&
164 git-ls-files --stage >10.out &&
165 diff -u M.out 10.out'
167 test_expect_success \
168 '11 - dirty path removed.' \
170 echo rezrov >rezrov &&
171 git-update-cache --add rezrov &&
172 echo rezrov rezrov >rezrov &&
173 if read_tree_twoway $treeH $treeM; then false; else :; fi'
175 test_expect_success \
176 '12 - unmatching local changes being removed.' \
178 echo rezrov rezrov >rezrov &&
179 git-update-cache --add rezrov &&
180 if read_tree_twoway $treeH $treeM; then false; else :; fi'
182 test_expect_success \
183 '13 - unmatching local changes being removed.' \
185 echo rezrov rezrov >rezrov &&
186 git-update-cache --add rezrov &&
187 echo rezrov >rezrov &&
188 if read_tree_twoway $treeH $treeM; then false; else :; fi'
195 test_expect_success \
196 '14 - unchanged in two heads.' \
198 echo nitfol nitfol >nitfol &&
199 git-update-cache --add nitfol &&
200 read_tree_twoway $treeH $treeM &&
201 git-ls-files --stage >14.out || exit
202 diff -u M.out 14.out >14diff.out
203 compare_change 14diff.out expected &&
204 check_cache_at nitfol clean'
206 test_expect_success \
207 '15 - unchanged in two heads.' \
209 echo nitfol nitfol >nitfol &&
210 git-update-cache --add nitfol &&
211 echo nitfol nitfol nitfol >nitfol &&
212 read_tree_twoway $treeH $treeM &&
213 git-ls-files --stage >15.out || exit
214 diff -u M.out 15.out >15diff.out
215 compare_change 15diff.out expected &&
216 check_cache_at nitfol dirty'
218 # This is different from straight 2-way merge in that it leaves
219 # three stages of bozbar in the index file without failing, so
220 # the user can run git-diff-stages to examine the situation.
221 test_expect_success \
222 '16 - conflicting local change.' \
224 echo bozbar bozbar >bozbar &&
225 git-update-cache --add bozbar &&
226 git-read-tree --emu23 $treeH $treeM &&
237 test_expect_success \
238 '17 - conflicting local change.' \
240 echo bozbar bozbar >bozbar &&
241 git-update-cache --add bozbar &&
242 echo bozbar bozbar bozbar >bozbar &&
243 if read_tree_twoway $treeH $treeM; then false; else :; fi'
245 test_expect_success \
246 '18 - local change already having a good result.' \
248 echo gnusto >bozbar &&
249 git-update-cache --add bozbar &&
250 read_tree_twoway $treeH $treeM &&
251 git-ls-files --stage >18.out &&
252 diff -u M.out 18.out &&
253 check_cache_at bozbar clean'
255 test_expect_success \
256 '19 - local change already having a good result, further modified.' \
258 echo gnusto >bozbar &&
259 git-update-cache --add bozbar &&
260 echo gnusto gnusto >bozbar &&
261 read_tree_twoway $treeH $treeM &&
262 git-ls-files --stage >19.out &&
263 diff -u M.out 19.out &&
264 check_cache_at bozbar dirty'
266 test_expect_success \
267 '20 - no local change, use new tree.' \
269 echo bozbar >bozbar &&
270 git-update-cache --add bozbar &&
271 read_tree_twoway $treeH $treeM &&
272 git-ls-files --stage >20.out &&
273 diff -u M.out 20.out &&
274 check_cache_at bozbar dirty'
276 test_expect_success \
277 '21 - no local change, dirty cache.' \
279 echo bozbar >bozbar &&
280 git-update-cache --add bozbar &&
281 echo gnusto gnusto >bozbar &&
282 if read_tree_twoway $treeH $treeM; then false; else :; fi'
284 # Also make sure we did not break DF vs DF/DF case.
285 test_expect_success \
286 'DF vs DF/DF case setup.' \
289 git-update-cache --add DF &&
290 treeDF=`git-write-tree` &&
291 echo treeDF $treeDF &&
292 git-ls-tree $treeDF &&
297 git-update-cache --add --remove DF DF/DF &&
298 treeDFDF=`git-write-tree` &&
299 echo treeDFDF $treeDFDF &&
300 git-ls-tree $treeDFDF &&
301 git-ls-files --stage >DFDF.out'
303 test_expect_success \
304 'DF vs DF/DF case test.' \
308 git-update-cache --add DF &&
309 read_tree_twoway $treeDF $treeDFDF &&
310 git-ls-files --stage >DFDFcheck.out &&
311 diff -u DFDF.out DFDFcheck.out &&
312 check_cache_at DF/DF clean && # different from pure 2-way