]> git.ipfire.org Git - thirdparty/git.git/blob - t/t6403-merge-file.sh
The third batch
[thirdparty/git.git] / t / t6403-merge-file.sh
1 #!/bin/sh
2
3 test_description='RCS merge replacement: merge-file'
4
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_expect_success 'setup' '
9 cat >orig.txt <<-\EOF &&
10 Dominus regit me,
11 et nihil mihi deerit.
12 In loco pascuae ibi me collocavit,
13 super aquam refectionis educavit me;
14 animam meam convertit,
15 deduxit me super semitas jusitiae,
16 propter nomen suum.
17 EOF
18
19 cat >new1.txt <<-\EOF &&
20 Dominus regit me,
21 et nihil mihi deerit.
22 In loco pascuae ibi me collocavit,
23 super aquam refectionis educavit me;
24 animam meam convertit,
25 deduxit me super semitas jusitiae,
26 propter nomen suum.
27 Nam et si ambulavero in medio umbrae mortis,
28 non timebo mala, quoniam tu mecum es:
29 virga tua et baculus tuus ipsa me consolata sunt.
30 EOF
31
32 cat >new2.txt <<-\EOF &&
33 Dominus regit me, et nihil mihi deerit.
34 In loco pascuae ibi me collocavit,
35 super aquam refectionis educavit me;
36 animam meam convertit,
37 deduxit me super semitas jusitiae,
38 propter nomen suum.
39 EOF
40
41 cat >new3.txt <<-\EOF &&
42 DOMINUS regit me,
43 et nihil mihi deerit.
44 In loco pascuae ibi me collocavit,
45 super aquam refectionis educavit me;
46 animam meam convertit,
47 deduxit me super semitas jusitiae,
48 propter nomen suum.
49 EOF
50
51 cat >new4.txt <<-\EOF &&
52 Dominus regit me, et nihil mihi deerit.
53 In loco pascuae ibi me collocavit,
54 super aquam refectionis educavit me;
55 animam meam convertit,
56 deduxit me super semitas jusitiae,
57 EOF
58
59 printf "propter nomen suum." >>new4.txt &&
60
61 cat >base.c <<-\EOF &&
62 int f(int x, int y)
63 {
64 if (x == 0)
65 {
66 return y;
67 }
68 return x;
69 }
70
71 int g(size_t u)
72 {
73 while (u < 30)
74 {
75 u++;
76 }
77 return u;
78 }
79 EOF
80
81 cat >ours.c <<-\EOF &&
82 int g(size_t u)
83 {
84 while (u < 30)
85 {
86 u++;
87 }
88 return u;
89 }
90
91 int h(int x, int y, int z)
92 {
93 if (z == 0)
94 {
95 return x;
96 }
97 return y;
98 }
99 EOF
100
101 cat >theirs.c <<-\EOF
102 int f(int x, int y)
103 {
104 if (x == 0)
105 {
106 return y;
107 }
108 return x;
109 }
110
111 int g(size_t u)
112 {
113 while (u > 34)
114 {
115 u--;
116 }
117 return u;
118 }
119 EOF
120 '
121
122 test_expect_success 'merge with no changes' '
123 cp orig.txt test.txt &&
124 git merge-file test.txt orig.txt orig.txt &&
125 test_cmp test.txt orig.txt
126 '
127
128 test_expect_success 'merge with no changes with --object-id' '
129 git add orig.txt &&
130 git merge-file -p --object-id :orig.txt :orig.txt :orig.txt >actual &&
131 test_cmp actual orig.txt
132 '
133
134 test_expect_success "merge without conflict" '
135 cp new1.txt test.txt &&
136 git merge-file test.txt orig.txt new2.txt
137 '
138
139 test_expect_success 'merge without conflict with --object-id' '
140 git add orig.txt new2.txt &&
141 git merge-file --object-id :orig.txt :orig.txt :new2.txt >actual &&
142 git rev-parse :new2.txt >expected &&
143 test_cmp actual expected
144 '
145
146 test_expect_success 'can accept object ID with --object-id' '
147 git merge-file --object-id $(test_oid empty_blob) $(test_oid empty_blob) :new2.txt >actual &&
148 git rev-parse :new2.txt >expected &&
149 test_cmp actual expected
150 '
151
152 test_expect_success 'works in subdirectory' '
153 mkdir dir &&
154 cp new1.txt dir/a.txt &&
155 cp orig.txt dir/o.txt &&
156 cp new2.txt dir/b.txt &&
157 ( cd dir && git merge-file a.txt o.txt b.txt ) &&
158 test_path_is_missing a.txt
159 '
160
161 test_expect_success "merge without conflict (--quiet)" '
162 cp new1.txt test.txt &&
163 git merge-file --quiet test.txt orig.txt new2.txt
164 '
165
166 test_expect_failure "merge without conflict (missing LF at EOF)" '
167 cp new1.txt test2.txt &&
168 git merge-file test2.txt orig.txt new4.txt
169 '
170
171 test_expect_failure "merge result added missing LF" '
172 test_cmp test.txt test2.txt
173 '
174
175 test_expect_success "merge without conflict (missing LF at EOF, away from change in the other file)" '
176 cp new4.txt test3.txt &&
177 git merge-file --quiet test3.txt new2.txt new3.txt
178 '
179
180 test_expect_success "merge does not add LF away of change" '
181 cat >expect.txt <<-\EOF &&
182 DOMINUS regit me,
183 et nihil mihi deerit.
184 In loco pascuae ibi me collocavit,
185 super aquam refectionis educavit me;
186 animam meam convertit,
187 deduxit me super semitas jusitiae,
188 EOF
189 printf "propter nomen suum." >>expect.txt &&
190
191 test_cmp expect.txt test3.txt
192 '
193
194 test_expect_success "merge with conflicts" '
195 cp test.txt backup.txt &&
196 test_must_fail git merge-file test.txt orig.txt new3.txt
197 '
198
199 test_expect_success "expected conflict markers" '
200 cat >expect.txt <<-\EOF &&
201 <<<<<<< test.txt
202 Dominus regit me, et nihil mihi deerit.
203 =======
204 DOMINUS regit me,
205 et nihil mihi deerit.
206 >>>>>>> new3.txt
207 In loco pascuae ibi me collocavit,
208 super aquam refectionis educavit me;
209 animam meam convertit,
210 deduxit me super semitas jusitiae,
211 propter nomen suum.
212 Nam et si ambulavero in medio umbrae mortis,
213 non timebo mala, quoniam tu mecum es:
214 virga tua et baculus tuus ipsa me consolata sunt.
215 EOF
216
217 test_cmp expect.txt test.txt
218 '
219
220 test_expect_success "merge with conflicts with --object-id" '
221 git add backup.txt orig.txt new3.txt &&
222 test_must_fail git merge-file -p --object-id :backup.txt :orig.txt :new3.txt >actual &&
223 sed -e "s/<< test.txt/<< :backup.txt/" \
224 -e "s/>> new3.txt/>> :new3.txt/" \
225 expect.txt >expect &&
226 test_cmp expect actual &&
227 test_must_fail git merge-file --object-id :backup.txt :orig.txt :new3.txt >oid &&
228 git cat-file blob "$(cat oid)" >actual &&
229 test_cmp expect actual
230 '
231
232 test_expect_success "merge with conflicts with --object-id with labels" '
233 git add backup.txt orig.txt new3.txt &&
234 test_must_fail git merge-file -p --object-id \
235 -L test.txt -L orig.txt -L new3.txt \
236 :backup.txt :orig.txt :new3.txt >actual &&
237 test_cmp expect.txt actual &&
238 test_must_fail git merge-file --object-id \
239 -L test.txt -L orig.txt -L new3.txt \
240 :backup.txt :orig.txt :new3.txt >oid &&
241 git cat-file blob "$(cat oid)" >actual &&
242 test_cmp expect.txt actual
243 '
244
245 test_expect_success "merge conflicting with --ours" '
246 cp backup.txt test.txt &&
247
248 cat >expect.txt <<-\EOF &&
249 Dominus regit me, et nihil mihi deerit.
250 In loco pascuae ibi me collocavit,
251 super aquam refectionis educavit me;
252 animam meam convertit,
253 deduxit me super semitas jusitiae,
254 propter nomen suum.
255 Nam et si ambulavero in medio umbrae mortis,
256 non timebo mala, quoniam tu mecum es:
257 virga tua et baculus tuus ipsa me consolata sunt.
258 EOF
259
260 git merge-file --ours test.txt orig.txt new3.txt &&
261 test_cmp expect.txt test.txt
262 '
263
264 test_expect_success "merge conflicting with --theirs" '
265 cp backup.txt test.txt &&
266
267 cat >expect.txt <<-\EOF &&
268 DOMINUS regit me,
269 et nihil mihi deerit.
270 In loco pascuae ibi me collocavit,
271 super aquam refectionis educavit me;
272 animam meam convertit,
273 deduxit me super semitas jusitiae,
274 propter nomen suum.
275 Nam et si ambulavero in medio umbrae mortis,
276 non timebo mala, quoniam tu mecum es:
277 virga tua et baculus tuus ipsa me consolata sunt.
278 EOF
279
280 git merge-file --theirs test.txt orig.txt new3.txt &&
281 test_cmp expect.txt test.txt
282 '
283
284 test_expect_success "merge conflicting with --union" '
285 cp backup.txt test.txt &&
286
287 cat >expect.txt <<-\EOF &&
288 Dominus regit me, et nihil mihi deerit.
289 DOMINUS regit me,
290 et nihil mihi deerit.
291 In loco pascuae ibi me collocavit,
292 super aquam refectionis educavit me;
293 animam meam convertit,
294 deduxit me super semitas jusitiae,
295 propter nomen suum.
296 Nam et si ambulavero in medio umbrae mortis,
297 non timebo mala, quoniam tu mecum es:
298 virga tua et baculus tuus ipsa me consolata sunt.
299 EOF
300
301 git merge-file --union test.txt orig.txt new3.txt &&
302 test_cmp expect.txt test.txt
303 '
304
305 test_expect_success "merge with conflicts, using -L" '
306 cp backup.txt test.txt &&
307
308 test_must_fail git merge-file -L 1 -L 2 test.txt orig.txt new3.txt
309 '
310
311 test_expect_success "expected conflict markers, with -L" '
312 cat >expect.txt <<-\EOF &&
313 <<<<<<< 1
314 Dominus regit me, et nihil mihi deerit.
315 =======
316 DOMINUS regit me,
317 et nihil mihi deerit.
318 >>>>>>> new3.txt
319 In loco pascuae ibi me collocavit,
320 super aquam refectionis educavit me;
321 animam meam convertit,
322 deduxit me super semitas jusitiae,
323 propter nomen suum.
324 Nam et si ambulavero in medio umbrae mortis,
325 non timebo mala, quoniam tu mecum es:
326 virga tua et baculus tuus ipsa me consolata sunt.
327 EOF
328
329 test_cmp expect.txt test.txt
330 '
331
332 test_expect_success "conflict in removed tail" '
333 sed "s/ tu / TU /" <new1.txt >new5.txt &&
334 test_must_fail git merge-file -p orig.txt new1.txt new5.txt >out
335 '
336
337 test_expect_success "expected conflict markers" '
338 cat >expect <<-\EOF &&
339 Dominus regit me,
340 et nihil mihi deerit.
341 In loco pascuae ibi me collocavit,
342 super aquam refectionis educavit me;
343 animam meam convertit,
344 deduxit me super semitas jusitiae,
345 propter nomen suum.
346 <<<<<<< orig.txt
347 =======
348 Nam et si ambulavero in medio umbrae mortis,
349 non timebo mala, quoniam TU mecum es:
350 virga tua et baculus tuus ipsa me consolata sunt.
351 >>>>>>> new5.txt
352 EOF
353
354 test_cmp expect out
355 '
356
357 test_expect_success 'binary files cannot be merged' '
358 test_must_fail git merge-file -p \
359 orig.txt "$TEST_DIRECTORY"/test-binary-1.png new1.txt 2> merge.err &&
360 grep "Cannot merge binary files" merge.err
361 '
362
363 test_expect_success 'binary files cannot be merged with --object-id' '
364 cp "$TEST_DIRECTORY"/test-binary-1.png . &&
365 git add orig.txt new1.txt test-binary-1.png &&
366 test_must_fail git merge-file --object-id \
367 :orig.txt :test-binary-1.png :new1.txt 2> merge.err &&
368 grep "Cannot merge binary files" merge.err
369 '
370
371 test_expect_success 'MERGE_ZEALOUS simplifies non-conflicts' '
372 sed -e "s/deerit.\$/deerit;/" -e "s/me;\$/me./" <new5.txt >new6.txt &&
373 sed -e "s/deerit.\$/deerit,/" -e "s/me;\$/me,/" <new5.txt >new7.txt &&
374
375 test_must_fail git merge-file -p new6.txt new5.txt new7.txt > output &&
376 test 1 = $(grep ======= <output | wc -l)
377 '
378
379 test_expect_success 'ZEALOUS_ALNUM' '
380 sed -e "s/deerit./&%%%%/" -e "s/locavit,/locavit;/" <new6.txt | tr % "\012" >new8.txt &&
381 sed -e "s/deerit./&%%%%/" -e "s/locavit,/locavit --/" <new7.txt | tr % "\012" >new9.txt &&
382
383 test_must_fail git merge-file -p \
384 new8.txt new5.txt new9.txt >merge.out &&
385 test 1 = $(grep ======= <merge.out | wc -l)
386 '
387
388 test_expect_success '"diff3 -m" style output (1)' '
389 cat >expect <<-\EOF &&
390 Dominus regit me,
391 <<<<<<< new8.txt
392 et nihil mihi deerit;
393
394
395
396
397 In loco pascuae ibi me collocavit;
398 super aquam refectionis educavit me.
399 ||||||| new5.txt
400 et nihil mihi deerit.
401 In loco pascuae ibi me collocavit,
402 super aquam refectionis educavit me;
403 =======
404 et nihil mihi deerit,
405
406
407
408
409 In loco pascuae ibi me collocavit --
410 super aquam refectionis educavit me,
411 >>>>>>> new9.txt
412 animam meam convertit,
413 deduxit me super semitas jusitiae,
414 propter nomen suum.
415 Nam et si ambulavero in medio umbrae mortis,
416 non timebo mala, quoniam TU mecum es:
417 virga tua et baculus tuus ipsa me consolata sunt.
418 EOF
419
420 test_must_fail git merge-file -p --diff3 \
421 new8.txt new5.txt new9.txt >actual &&
422 test_cmp expect actual
423 '
424
425 test_expect_success '"diff3 -m" style output (2)' '
426 git config merge.conflictstyle diff3 &&
427 test_must_fail git merge-file -p \
428 new8.txt new5.txt new9.txt >actual &&
429 test_cmp expect actual
430 '
431
432 test_expect_success 'marker size' '
433 cat >expect <<-\EOF &&
434 Dominus regit me,
435 <<<<<<<<<< new8.txt
436 et nihil mihi deerit;
437
438
439
440
441 In loco pascuae ibi me collocavit;
442 super aquam refectionis educavit me.
443 |||||||||| new5.txt
444 et nihil mihi deerit.
445 In loco pascuae ibi me collocavit,
446 super aquam refectionis educavit me;
447 ==========
448 et nihil mihi deerit,
449
450
451
452
453 In loco pascuae ibi me collocavit --
454 super aquam refectionis educavit me,
455 >>>>>>>>>> new9.txt
456 animam meam convertit,
457 deduxit me super semitas jusitiae,
458 propter nomen suum.
459 Nam et si ambulavero in medio umbrae mortis,
460 non timebo mala, quoniam TU mecum es:
461 virga tua et baculus tuus ipsa me consolata sunt.
462 EOF
463
464 test_must_fail git merge-file -p --marker-size=10 \
465 new8.txt new5.txt new9.txt >actual &&
466 test_cmp expect actual
467 '
468
469 test_expect_success 'conflict at EOF without LF resolved by --ours' '
470 printf "line1\nline2\nline3" >nolf-orig.txt &&
471 printf "line1\nline2\nline3x" >nolf-diff1.txt &&
472 printf "line1\nline2\nline3y" >nolf-diff2.txt &&
473
474 git merge-file -p --ours nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
475 printf "line1\nline2\nline3x" >expect.txt &&
476 test_cmp expect.txt output.txt
477 '
478
479 test_expect_success 'conflict at EOF without LF resolved by --theirs' '
480 git merge-file -p --theirs nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
481 printf "line1\nline2\nline3y" >expect.txt &&
482 test_cmp expect.txt output.txt
483 '
484
485 test_expect_success 'conflict at EOF without LF resolved by --union' '
486 git merge-file -p --union nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
487 printf "line1\nline2\nline3x\nline3y" >expect.txt &&
488 test_cmp expect.txt output.txt
489 '
490
491 test_expect_success 'conflict sections match existing line endings' '
492 printf "1\\r\\n2\\r\\n3" >crlf-orig.txt &&
493 printf "1\\r\\n2\\r\\n4" >crlf-diff1.txt &&
494 printf "1\\r\\n2\\r\\n5" >crlf-diff2.txt &&
495 test_must_fail git -c core.eol=crlf merge-file -p \
496 crlf-diff1.txt crlf-orig.txt crlf-diff2.txt >crlf.txt &&
497 test $(tr "\015" Q <crlf.txt | grep "^[<=>].*Q$" | wc -l) = 3 &&
498 test $(tr "\015" Q <crlf.txt | grep "[345]Q$" | wc -l) = 3 &&
499 test_must_fail git -c core.eol=crlf merge-file -p \
500 nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >nolf.txt &&
501 test $(tr "\015" Q <nolf.txt | grep "^[<=>].*Q$" | wc -l) = 0
502 '
503
504 test_expect_success '--object-id fails without repository' '
505 empty="$(test_oid empty_blob)" &&
506 nongit test_must_fail git merge-file --object-id $empty $empty $empty 2>err &&
507 grep "not a git repository" err
508 '
509
510 test_expect_success 'merging C files with "myers" diff algorithm creates some spurious conflicts' '
511 cat >expect.c <<-\EOF &&
512 int g(size_t u)
513 {
514 while (u < 30)
515 {
516 u++;
517 }
518 return u;
519 }
520
521 int h(int x, int y, int z)
522 {
523 <<<<<<< ours.c
524 if (z == 0)
525 ||||||| base.c
526 while (u < 30)
527 =======
528 while (u > 34)
529 >>>>>>> theirs.c
530 {
531 <<<<<<< ours.c
532 return x;
533 ||||||| base.c
534 u++;
535 =======
536 u--;
537 >>>>>>> theirs.c
538 }
539 return y;
540 }
541 EOF
542
543 test_must_fail git merge-file -p --diff3 --diff-algorithm myers ours.c base.c theirs.c >myers_output.c &&
544 test_cmp expect.c myers_output.c
545 '
546
547 test_expect_success 'merging C files with "histogram" diff algorithm avoids some spurious conflicts' '
548 cat >expect.c <<-\EOF &&
549 int g(size_t u)
550 {
551 while (u > 34)
552 {
553 u--;
554 }
555 return u;
556 }
557
558 int h(int x, int y, int z)
559 {
560 if (z == 0)
561 {
562 return x;
563 }
564 return y;
565 }
566 EOF
567
568 git merge-file -p --diff3 --diff-algorithm histogram ours.c base.c theirs.c >histogram_output.c &&
569 test_cmp expect.c histogram_output.c
570 '
571
572 test_done