Code

t6042: Add tests for content issues with modify/rename/directory conflicts
[git.git] / t / t6042-merge-rename-corner-cases.sh
1 #!/bin/sh
3 test_description="recursive merge corner cases w/ renames but not criss-crosses"
4 # t6036 has corner cases that involve both criss-cross merges and renames
6 . ./test-lib.sh
8 test_expect_success 'setup rename/delete + untracked file' '
9         echo "A pretty inscription" >ring &&
10         git add ring &&
11         test_tick &&
12         git commit -m beginning &&
14         git branch people &&
15         git checkout -b rename-the-ring &&
16         git mv ring one-ring-to-rule-them-all &&
17         test_tick &&
18         git commit -m fullname &&
20         git checkout people &&
21         git rm ring &&
22         echo gollum >owner &&
23         git add owner &&
24         test_tick &&
25         git commit -m track-people-instead-of-objects &&
26         echo "Myyy PRECIOUSSS" >ring
27 '
29 test_expect_failure "Does git preserve Gollum's precious artifact?" '
30         test_must_fail git merge -s recursive rename-the-ring &&
32         # Make sure git did not delete an untracked file
33         test -f ring
34 '
36 # Testcase setup for rename/modify/add-source:
37 #   Commit A: new file: a
38 #   Commit B: modify a slightly
39 #   Commit C: rename a->b, add completely different a
40 #
41 # We should be able to merge B & C cleanly
43 test_expect_success 'setup rename/modify/add-source conflict' '
44         git rm -rf . &&
45         git clean -fdqx &&
46         rm -rf .git &&
47         git init &&
49         printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
50         git add a &&
51         git commit -m A &&
52         git tag A &&
54         git checkout -b B A &&
55         echo 8 >>a &&
56         git add a &&
57         git commit -m B &&
59         git checkout -b C A &&
60         git mv a b &&
61         echo something completely different >a &&
62         git add a &&
63         git commit -m C
64 '
66 test_expect_failure 'rename/modify/add-source conflict resolvable' '
67         git checkout B^0 &&
69         git merge -s recursive C^0 &&
71         test $(git rev-parse B:a) = $(git rev-parse b) &&
72         test $(git rev-parse C:a) = $(git rev-parse a)
73 '
75 test_expect_success 'setup resolvable conflict missed if rename missed' '
76         git rm -rf . &&
77         git clean -fdqx &&
78         rm -rf .git &&
79         git init &&
81         printf "1\n2\n3\n4\n5\n" >a &&
82         echo foo >b &&
83         git add a b &&
84         git commit -m A &&
85         git tag A &&
87         git checkout -b B A &&
88         git mv a c &&
89         echo "Completely different content" >a &&
90         git add a &&
91         git commit -m B &&
93         git checkout -b C A &&
94         echo 6 >>a &&
95         git add a &&
96         git commit -m C
97 '
99 test_expect_failure 'conflict caused if rename not detected' '
100         git checkout -q C^0 &&
101         git merge -s recursive B^0 &&
103         test 3 -eq $(git ls-files -s | wc -l) &&
104         test 0 -eq $(git ls-files -u | wc -l) &&
105         test 0 -eq $(git ls-files -o | wc -l) &&
107         test 6 -eq $(wc -l < c) &&
108         test $(git rev-parse HEAD:a) = $(git rev-parse B:a) &&
109         test $(git rev-parse HEAD:b) = $(git rev-parse A:b)
112 test_expect_success 'setup conflict resolved wrong if rename missed' '
113         git reset --hard &&
114         git clean -f &&
116         git checkout -b D A &&
117         echo 7 >>a &&
118         git add a &&
119         git mv a c &&
120         echo "Completely different content" >a &&
121         git add a &&
122         git commit -m D &&
124         git checkout -b E A &&
125         git rm a &&
126         echo "Completely different content" >>a &&
127         git add a &&
128         git commit -m E
131 test_expect_failure 'missed conflict if rename not detected' '
132         git checkout -q E^0 &&
133         test_must_fail git merge -s recursive D^0
136 # Tests for undetected rename/add-source causing a file to erroneously be
137 # deleted (and for mishandled rename/rename(1to1) causing the same issue).
139 # This test uses a rename/rename(1to1)+add-source conflict (1to1 means the
140 # same file is renamed on both sides to the same thing; it should trigger
141 # the 1to2 logic, which it would do if the add-source didn't cause issues
142 # for git's rename detection):
143 #   Commit A: new file: a
144 #   Commit B: rename a->b
145 #   Commit C: rename a->b, add unrelated a
147 test_expect_success 'setup undetected rename/add-source causes data loss' '
148         git rm -rf . &&
149         git clean -fdqx &&
150         rm -rf .git &&
151         git init &&
153         printf "1\n2\n3\n4\n5\n" >a &&
154         git add a &&
155         git commit -m A &&
156         git tag A &&
158         git checkout -b B A &&
159         git mv a b &&
160         git commit -m B &&
162         git checkout -b C A &&
163         git mv a b &&
164         echo foobar >a &&
165         git add a &&
166         git commit -m C
169 test_expect_failure 'detect rename/add-source and preserve all data' '
170         git checkout B^0 &&
172         git merge -s recursive C^0 &&
174         test 2 -eq $(git ls-files -s | wc -l) &&
175         test 2 -eq $(git ls-files -u | wc -l) &&
176         test 0 -eq $(git ls-files -o | wc -l) &&
178         test -f a &&
179         test -f b &&
181         test $(git rev-parse HEAD:b) = $(git rev-parse A:a) &&
182         test $(git rev-parse HEAD:a) = $(git rev-parse C:a)
185 test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
186         git checkout C^0 &&
188         git merge -s recursive B^0 &&
190         test 2 -eq $(git ls-files -s | wc -l) &&
191         test 2 -eq $(git ls-files -u | wc -l) &&
192         test 0 -eq $(git ls-files -o | wc -l) &&
194         test -f a &&
195         test -f b &&
197         test $(git rev-parse HEAD:b) = $(git rev-parse A:a) &&
198         test $(git rev-parse HEAD:a) = $(git rev-parse C:a)
201 test_expect_success 'setup content merge + rename/directory conflict' '
202         git rm -rf . &&
203         git clean -fdqx &&
204         rm -rf .git &&
205         git init &&
207         printf "1\n2\n3\n4\n5\n6\n" >file &&
208         git add file &&
209         test_tick &&
210         git commit -m base &&
211         git tag base &&
213         git checkout -b right &&
214         echo 7 >>file &&
215         mkdir newfile &&
216         echo junk >newfile/realfile &&
217         git add file newfile/realfile &&
218         test_tick &&
219         git commit -m right &&
221         git checkout -b left-conflict base &&
222         echo 8 >>file &&
223         git add file &&
224         git mv file newfile &&
225         test_tick &&
226         git commit -m left &&
228         git checkout -b left-clean base &&
229         echo 0 >newfile &&
230         cat file >>newfile &&
231         git add newfile &&
232         git rm file &&
233         test_tick &&
234         git commit -m left
237 test_expect_failure 'rename/directory conflict + clean content merge' '
238         git reset --hard &&
239         git reset --hard &&
240         git clean -fdqx &&
242         git checkout left-clean^0 &&
244         test_must_fail git merge -s recursive right^0 &&
246         test 2 -eq $(git ls-files -s | wc -l) &&
247         test 1 -eq $(git ls-files -u | wc -l) &&
248         test 1 -eq $(git ls-files -o | wc -l) &&
250         echo 0 >expect &&
251         git cat-file -p base:file >>expect &&
252         echo 7 >>expect &&
253         test_cmp expect newfile~HEAD &&
255         test $(git rev-parse :2:newfile) = $(git hash-object expect) &&
257         test -f newfile/realfile &&
258         test -f newfile~HEAD
261 test_expect_failure 'rename/directory conflict + content merge conflict' '
262         git reset --hard &&
263         git reset --hard &&
264         git clean -fdqx &&
266         git checkout left-conflict^0 &&
268         test_must_fail git merge -s recursive right^0 &&
270         test 4 -eq $(git ls-files -s | wc -l) &&
271         test 3 -eq $(git ls-files -u | wc -l) &&
272         test 1 -eq $(git ls-files -o | wc -l) &&
274         git cat-file -p left-conflict:newfile >left &&
275         git cat-file -p base:file    >base &&
276         git cat-file -p right:file   >right &&
277         test_must_fail git merge-file \
278                 -L "HEAD:newfile" \
279                 -L "" \
280                 -L "right^0:file" \
281                 left base right &&
282         test_cmp left newfile~HEAD &&
284         test $(git rev-parse :1:newfile) = $(git rev-parse base:file) &&
285         test $(git rev-parse :2:newfile) = $(git rev-parse left-conflict:newfile) &&
286         test $(git rev-parse :3:newfile) = $(git rev-parse right:file) &&
288         test -f newfile/realfile &&
289         test -f newfile~HEAD
292 test_expect_success 'setup content merge + rename/directory conflict w/ disappearing dir' '
293         git reset --hard &&
294         git rm -rf . &&
295         git clean -fdqx &&
296         rm -rf .git &&
297         git init &&
299         mkdir sub &&
300         printf "1\n2\n3\n4\n5\n6\n" >sub/file &&
301         git add sub/file &&
302         test_tick &&
303         git commit -m base &&
304         git tag base &&
306         git checkout -b right &&
307         echo 7 >>sub/file &&
308         git add sub/file &&
309         test_tick &&
310         git commit -m right &&
312         git checkout -b left base &&
313         echo 0 >newfile &&
314         cat sub/file >>newfile &&
315         git rm sub/file &&
316         mv newfile sub &&
317         git add sub &&
318         test_tick &&
319         git commit -m left
322 test_expect_success 'disappearing dir in rename/directory conflict handled' '
323         git reset --hard &&
324         git clean -fdqx &&
326         git checkout left^0 &&
328         git merge -s recursive right^0 &&
330         test 1 -eq $(git ls-files -s | wc -l) &&
331         test 0 -eq $(git ls-files -u | wc -l) &&
332         test 0 -eq $(git ls-files -o | wc -l) &&
334         echo 0 >expect &&
335         git cat-file -p base:sub/file >>expect &&
336         echo 7 >>expect &&
337         test_cmp expect sub &&
339         test -f sub
342 test_done