The eleventh batch
[git/gitster.git] / t / t4108-apply-threeway.sh
blobc6302163d848a7add7e1f8f1d3d060bce515f738
1 #!/bin/sh
3 test_description='git apply --3way'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 TEST_PASSES_SANITIZE_LEAK=true
9 . ./test-lib.sh
11 print_sanitized_conflicted_diff () {
12 git diff HEAD >diff.raw &&
13 sed -e '
14 /^index /d
15 s/^\(+[<>|][<>|][<>|][<>|]*\) .*/\1/
16 ' diff.raw
19 test_expect_success setup '
20 test_tick &&
21 test_write_lines 1 2 3 4 5 6 7 >one &&
22 cat one >two &&
23 git add one two &&
24 git commit -m initial &&
26 git branch side &&
28 test_tick &&
29 test_write_lines 1 two 3 4 5 six 7 >one &&
30 test_write_lines 1 two 3 4 5 6 7 >two &&
31 git commit -a -m main &&
33 git checkout side &&
34 test_write_lines 1 2 3 4 five 6 7 >one &&
35 test_write_lines 1 2 3 4 five 6 7 >two &&
36 git commit -a -m side &&
38 git checkout main
41 test_expect_success 'apply without --3way' '
42 git diff side^ side >P.diff &&
44 # should fail to apply
45 git reset --hard &&
46 git checkout main^0 &&
47 test_must_fail git apply --index P.diff &&
48 # should leave things intact
49 git diff-files --exit-code &&
50 git diff-index --exit-code --cached HEAD
53 test_apply_with_3way () {
54 # Merging side should be similar to applying this patch
55 git diff ...side >P.diff &&
57 # The corresponding conflicted merge
58 git reset --hard &&
59 git checkout main^0 &&
60 test_must_fail git merge --no-commit side &&
61 git ls-files -s >expect.ls &&
62 print_sanitized_conflicted_diff >expect.diff &&
64 # should fail to apply
65 git reset --hard &&
66 git checkout main^0 &&
67 test_must_fail git apply --index --3way P.diff &&
68 git ls-files -s >actual.ls &&
69 print_sanitized_conflicted_diff >actual.diff &&
71 # The result should resemble the corresponding merge
72 test_cmp expect.ls actual.ls &&
73 test_cmp expect.diff actual.diff
76 test_expect_success 'apply with --3way' '
77 test_apply_with_3way
80 test_expect_success 'apply with --3way with merge.conflictStyle = diff3' '
81 test_config merge.conflictStyle diff3 &&
82 test_apply_with_3way
85 test_apply_with_3way_favoritism () {
86 apply_arg=$1
87 merge_arg=$2
89 # Merging side should be similar to applying this patch
90 git diff ...side >P.diff &&
92 # The corresponding conflicted merge
93 git reset --hard &&
94 git checkout main^0 &&
95 git merge --no-commit $merge_arg side &&
96 git ls-files -s >expect.ls &&
97 print_sanitized_conflicted_diff >expect.diff &&
99 # should apply successfully
100 git reset --hard &&
101 git checkout main^0 &&
102 git apply --index --3way $apply_arg P.diff &&
103 git ls-files -s >actual.ls &&
104 print_sanitized_conflicted_diff >actual.diff &&
106 # The result should resemble the corresponding merge
107 test_cmp expect.ls actual.ls &&
108 test_cmp expect.diff actual.diff
111 test_expect_success 'apply with --3way --ours' '
112 test_apply_with_3way_favoritism --ours -Xours
115 test_expect_success 'apply with --3way --theirs' '
116 test_apply_with_3way_favoritism --theirs -Xtheirs
119 test_expect_success 'apply with --3way --union' '
120 echo "* merge=union" >.gitattributes &&
121 test_apply_with_3way_favoritism --union &&
122 rm .gitattributes
125 test_expect_success 'apply with --3way with rerere enabled' '
126 test_config rerere.enabled true &&
128 # Merging side should be similar to applying this patch
129 git diff ...side >P.diff &&
131 # The corresponding conflicted merge
132 git reset --hard &&
133 git checkout main^0 &&
134 test_must_fail git merge --no-commit side &&
136 # Manually resolve and record the resolution
137 test_write_lines 1 two 3 4 five six 7 >one &&
138 git rerere &&
139 cat one >expect &&
141 # should fail to apply
142 git reset --hard &&
143 git checkout main^0 &&
144 test_must_fail git apply --index --3way P.diff &&
146 # but rerere should have replayed the recorded resolution
147 test_cmp expect one
150 test_expect_success 'apply -3 with add/add conflict setup' '
151 git reset --hard &&
153 git checkout -b adder &&
154 test_write_lines 1 2 3 4 5 6 7 >three &&
155 test_write_lines 1 2 3 4 5 6 7 >four &&
156 git add three four &&
157 git commit -m "add three and four" &&
159 git checkout -b another adder^ &&
160 test_write_lines 1 2 3 4 5 6 7 >three &&
161 test_write_lines 1 2 3 four 5 6 7 >four &&
162 git add three four &&
163 git commit -m "add three and four" &&
165 # Merging another should be similar to applying this patch
166 git diff adder...another >P.diff &&
168 git checkout adder^0 &&
169 test_must_fail git merge --no-commit another &&
170 git ls-files -s >expect.ls &&
171 print_sanitized_conflicted_diff >expect.diff
174 test_expect_success 'apply -3 with add/add conflict' '
175 # should fail to apply ...
176 git reset --hard &&
177 git checkout adder^0 &&
178 test_must_fail git apply --index --3way P.diff &&
179 # ... and leave conflicts in the index and in the working tree
180 git ls-files -s >actual.ls &&
181 print_sanitized_conflicted_diff >actual.diff &&
183 # The result should resemble the corresponding merge
184 test_cmp expect.ls actual.ls &&
185 test_cmp expect.diff actual.diff
188 test_expect_success 'apply -3 with add/add conflict (dirty working tree)' '
189 # should fail to apply ...
190 git reset --hard &&
191 git checkout adder^0 &&
192 echo >>four &&
193 cat four >four.save &&
194 cat three >three.save &&
195 git ls-files -s >expect.ls &&
196 test_must_fail git apply --index --3way P.diff &&
197 # ... and should not touch anything
198 git ls-files -s >actual.ls &&
199 test_cmp expect.ls actual.ls &&
200 test_cmp four.save four &&
201 test_cmp three.save three
204 test_expect_success 'apply -3 with ambiguous repeating file' '
205 git reset --hard &&
206 test_write_lines 1 2 1 2 1 2 1 2 1 2 1 >one_two_repeat &&
207 git add one_two_repeat &&
208 git commit -m "init one" &&
209 test_write_lines 1 2 1 2 1 2 1 2 one 2 1 >one_two_repeat &&
210 git commit -a -m "change one" &&
212 git diff HEAD~ >Repeat.diff &&
213 git reset --hard HEAD~ &&
215 test_write_lines 1 2 1 2 1 2 one 2 1 2 one >one_two_repeat &&
216 git commit -a -m "change surrounding one" &&
218 git apply --index --3way Repeat.diff &&
219 test_write_lines 1 2 1 2 1 2 one 2 one 2 one >expect &&
221 test_cmp expect one_two_repeat
224 test_expect_success 'apply with --3way --cached clean apply' '
225 # Merging side should be similar to applying this patch
226 git diff ...side >P.diff &&
228 # The corresponding cleanly applied merge
229 git reset --hard &&
230 git checkout main~ &&
231 git merge --no-commit side &&
232 git ls-files -s >expect.ls &&
234 # should succeed
235 git reset --hard &&
236 git checkout main~ &&
237 git apply --cached --3way P.diff &&
238 git ls-files -s >actual.ls &&
239 print_sanitized_conflicted_diff >actual.diff &&
241 # The cache should resemble the corresponding merge
242 # (both files at stage #0)
243 test_cmp expect.ls actual.ls &&
244 # However the working directory should not change
245 >expect.diff &&
246 test_cmp expect.diff actual.diff
249 test_expect_success 'apply with --3way --cached and conflicts' '
250 # Merging side should be similar to applying this patch
251 git diff ...side >P.diff &&
253 # The corresponding conflicted merge
254 git reset --hard &&
255 git checkout main^0 &&
256 test_must_fail git merge --no-commit side &&
257 git ls-files -s >expect.ls &&
259 # should fail to apply
260 git reset --hard &&
261 git checkout main^0 &&
262 test_must_fail git apply --cached --3way P.diff &&
263 git ls-files -s >actual.ls &&
264 print_sanitized_conflicted_diff >actual.diff &&
266 # The cache should resemble the corresponding merge
267 # (one file at stage #0, one file at stages #1 #2 #3)
268 test_cmp expect.ls actual.ls &&
269 # However the working directory should not change
270 >expect.diff &&
271 test_cmp expect.diff actual.diff
274 test_expect_success 'apply binary file patch' '
275 git reset --hard main &&
276 cp "$TEST_DIRECTORY/test-binary-1.png" bin.png &&
277 git add bin.png &&
278 git commit -m "add binary file" &&
280 cp "$TEST_DIRECTORY/test-binary-2.png" bin.png &&
282 git diff --binary >bin.diff &&
283 git reset --hard &&
285 # Apply must succeed.
286 git apply bin.diff
289 test_expect_success 'apply binary file patch with 3way' '
290 git reset --hard main &&
291 cp "$TEST_DIRECTORY/test-binary-1.png" bin.png &&
292 git add bin.png &&
293 git commit -m "add binary file" &&
295 cp "$TEST_DIRECTORY/test-binary-2.png" bin.png &&
297 git diff --binary >bin.diff &&
298 git reset --hard &&
300 # Apply must succeed.
301 git apply --3way --index bin.diff
304 test_expect_success 'apply full-index patch with 3way' '
305 git reset --hard main &&
306 cp "$TEST_DIRECTORY/test-binary-1.png" bin.png &&
307 git add bin.png &&
308 git commit -m "add binary file" &&
310 cp "$TEST_DIRECTORY/test-binary-2.png" bin.png &&
312 git diff --full-index >bin.diff &&
313 git reset --hard &&
315 # Apply must succeed.
316 git apply --3way --index bin.diff
319 test_expect_success 'apply delete then new patch with 3way' '
320 git reset --hard main &&
321 test_write_lines 2 > delnew &&
322 git add delnew &&
323 git diff --cached >> new.patch &&
324 git reset --hard &&
325 test_write_lines 1 > delnew &&
326 git add delnew &&
327 git commit -m "delnew" &&
328 rm delnew &&
329 git diff >> delete-then-new.patch &&
330 cat new.patch >> delete-then-new.patch &&
332 git checkout -- . &&
333 # Apply must succeed.
334 git apply --3way delete-then-new.patch
337 test_done