1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
6 test_description='Two way merge with read-tree -m $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
22 '
23 . ./test-lib.sh
25 read_tree_twoway () {
26 git-read-tree -m "$1" "$2" && git-ls-files --stage
27 }
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 cat current
33 sed -n >current \
34 -e '/^--- /d; /^+++ /d; /^@@ /d;' \
35 -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
36 "$1"
37 diff -u expected current
38 }
40 check_cache_at () {
41 clean_if_empty=`git-diff-files "$1"`
42 case "$clean_if_empty" in
43 '') echo "$1: clean" ;;
44 ?*) echo "$1: dirty" ;;
45 esac
46 case "$2,$clean_if_empty" in
47 clean,) : ;;
48 clean,?*) false ;;
49 dirty,) false ;;
50 dirty,?*) : ;;
51 esac
52 }
54 test_expect_success \
55 setup \
56 'echo frotz >frotz &&
57 echo nitfol >nitfol &&
58 echo bozbar >bozbar &&
59 echo rezrov >rezrov &&
60 echo yomin >yomin &&
61 git-update-cache --add nitfol bozbar rezrov &&
62 treeH=`git-write-tree` &&
63 echo treeH $treeH &&
64 git-ls-tree $treeH &&
66 echo gnusto >bozbar &&
67 git-update-cache --add frotz bozbar --force-remove rezrov &&
68 git-ls-files --stage >M.out &&
69 treeM=`git-write-tree` &&
70 echo treeM $treeM &&
71 git-ls-tree $treeM &&
72 git-diff-tree $treeH $treeM'
74 test_expect_success \
75 '1, 2, 3 - no carry forward' \
76 'rm -f .git/index &&
77 read_tree_twoway $treeH $treeM &&
78 git-ls-files --stage >1-3.out &&
79 diff -u M.out 1-3.out &&
80 check_cache_at bozbar dirty &&
81 check_cache_at frotz dirty &&
82 check_cache_at nitfol dirty'
84 echo '+100644 X 0 yomin' >expected
86 test_expect_success \
87 '4 - carry forward local addition.' \
88 'rm -f .git/index &&
89 git-update-cache --add yomin &&
90 read_tree_twoway $treeH $treeM &&
91 git-ls-files --stage >4.out || exit
92 diff -u M.out 4.out >4diff.out
93 compare_change 4diff.out expected &&
94 check_cache_at yomin clean'
96 test_expect_success \
97 '5 - carry forward local addition.' \
98 'rm -f .git/index &&
99 echo yomin >yomin &&
100 git-update-cache --add yomin &&
101 echo yomin yomin >yomin &&
102 read_tree_twoway $treeH $treeM &&
103 git-ls-files --stage >5.out || exit
104 diff -u M.out 5.out >5diff.out
105 compare_change 5diff.out expected &&
106 check_cache_at yomin dirty'
108 test_expect_success \
109 '6 - local addition already has the same.' \
110 'rm -f .git/index &&
111 git-update-cache --add frotz &&
112 read_tree_twoway $treeH $treeM &&
113 git-ls-files --stage >6.out &&
114 diff -u M.out 6.out &&
115 check_cache_at frotz clean'
117 test_expect_success \
118 '7 - local addition already has the same.' \
119 'rm -f .git/index &&
120 echo frotz >frotz &&
121 git-update-cache --add frotz &&
122 echo frotz frotz >frotz &&
123 read_tree_twoway $treeH $treeM &&
124 git-ls-files --stage >7.out &&
125 diff -u M.out 7.out &&
126 check_cache_at frotz dirty'
128 test_expect_success \
129 '8 - conflicting addition.' \
130 'rm -f .git/index &&
131 echo frotz frotz >frotz &&
132 git-update-cache --add frotz &&
133 if read_tree_twoway $treeH $treeM; then false; else :; fi'
135 test_expect_success \
136 '9 - conflicting addition.' \
137 'rm -f .git/index &&
138 echo frotz frotz >frotz &&
139 git-update-cache --add frotz &&
140 echo frotz >frotz &&
141 if read_tree_twoway $treeH $treeM; then false; else :; fi'
143 test_expect_success \
144 '10 - path removed.' \
145 'rm -f .git/index &&
146 echo rezrov >rezrov &&
147 git-update-cache --add rezrov &&
148 read_tree_twoway $treeH $treeM &&
149 git-ls-files --stage >10.out &&
150 diff -u M.out 10.out'
152 test_expect_success \
153 '11 - dirty path removed.' \
154 'rm -f .git/index &&
155 echo rezrov >rezrov &&
156 git-update-cache --add rezrov &&
157 echo rezrov rezrov >rezrov &&
158 if read_tree_twoway $treeH $treeM; then false; else :; fi'
160 test_expect_success \
161 '12 - unmatching local changes being removed.' \
162 'rm -f .git/index &&
163 echo rezrov rezrov >rezrov &&
164 git-update-cache --add rezrov &&
165 if read_tree_twoway $treeH $treeM; then false; else :; fi'
167 test_expect_success \
168 '13 - unmatching local changes being removed.' \
169 'rm -f .git/index &&
170 echo rezrov rezrov >rezrov &&
171 git-update-cache --add rezrov &&
172 echo rezrov >rezrov &&
173 if read_tree_twoway $treeH $treeM; then false; else :; fi'
175 cat >expected <<EOF
176 -100644 X 0 nitfol
177 +100644 X 0 nitfol
178 EOF
180 test_expect_success \
181 '14 - unchanged in two heads.' \
182 'rm -f .git/index &&
183 echo nitfol nitfol >nitfol &&
184 git-update-cache --add nitfol &&
185 read_tree_twoway $treeH $treeM &&
186 git-ls-files --stage >14.out || exit
187 diff -u M.out 14.out >14diff.out
188 compare_change 14diff.out expected &&
189 check_cache_at nitfol clean'
191 test_expect_success \
192 '15 - unchanged in two heads.' \
193 'rm -f .git/index &&
194 echo nitfol nitfol >nitfol &&
195 git-update-cache --add nitfol &&
196 echo nitfol nitfol nitfol >nitfol &&
197 read_tree_twoway $treeH $treeM &&
198 git-ls-files --stage >15.out || exit
199 diff -u M.out 15.out >15diff.out
200 compare_change 15diff.out expected &&
201 check_cache_at nitfol dirty'
203 test_expect_success \
204 '16 - conflicting local change.' \
205 'rm -f .git/index &&
206 echo bozbar bozbar >bozbar &&
207 git-update-cache --add bozbar &&
208 if read_tree_twoway $treeH $treeM; then false; else :; fi'
210 test_expect_success \
211 '17 - conflicting local change.' \
212 'rm -f .git/index &&
213 echo bozbar bozbar >bozbar &&
214 git-update-cache --add bozbar &&
215 echo bozbar bozbar bozbar >bozbar &&
216 if read_tree_twoway $treeH $treeM; then false; else :; fi'
218 test_expect_success \
219 '18 - local change already having a good result.' \
220 'rm -f .git/index &&
221 echo gnusto >bozbar &&
222 git-update-cache --add bozbar &&
223 read_tree_twoway $treeH $treeM &&
224 git-ls-files --stage >18.out &&
225 diff -u M.out 18.out &&
226 check_cache_at bozbar clean'
228 test_expect_success \
229 '19 - local change already having a good result, further modified.' \
230 'rm -f .git/index &&
231 echo gnusto >bozbar &&
232 git-update-cache --add bozbar &&
233 echo gnusto gnusto >bozbar &&
234 read_tree_twoway $treeH $treeM &&
235 git-ls-files --stage >19.out &&
236 diff -u M.out 19.out &&
237 check_cache_at bozbar dirty'
239 test_expect_success \
240 '20 - no local change, use new tree.' \
241 'rm -f .git/index &&
242 echo bozbar >bozbar &&
243 git-update-cache --add bozbar &&
244 read_tree_twoway $treeH $treeM &&
245 git-ls-files --stage >20.out &&
246 diff -u M.out 20.out &&
247 check_cache_at bozbar dirty'
249 test_expect_success \
250 '21 - no local change, dirty cache.' \
251 'rm -f .git/index &&
252 echo bozbar >bozbar &&
253 git-update-cache --add bozbar &&
254 echo gnusto gnusto >bozbar &&
255 if read_tree_twoway $treeH $treeM; then false; else :; fi'
257 # Also make sure we did not break DF vs DF/DF case.
258 test_expect_success \
259 'DF vs DF/DF case setup.' \
260 'rm -f .git/index &&
261 echo DF >DF &&
262 git-update-cache --add DF &&
263 treeDF=`git-write-tree` &&
264 echo treeDF $treeDF &&
265 git-ls-tree $treeDF &&
267 rm -f DF &&
268 mkdir DF &&
269 echo DF/DF >DF/DF &&
270 git-update-cache --add --remove DF DF/DF &&
271 treeDFDF=`git-write-tree` &&
272 echo treeDFDF $treeDFDF &&
273 git-ls-tree $treeDFDF &&
274 git-ls-files --stage >DFDF.out'
276 test_expect_success \
277 'DF vs DF/DF case test.' \
278 'rm -f .git/index &&
279 rm -fr DF &&
280 echo DF >DF &&
281 git-update-cache --add DF &&
282 read_tree_twoway $treeDF $treeDFDF &&
283 git-ls-files --stage >DFDFcheck.out &&
284 diff -u DFDF.out DFDFcheck.out &&
285 check_cache_at DF/DF dirty &&
286 :'
288 test_done