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