Merge branch 'sg/name-rev-wo-recursion'
[git] / t / t4038-diff-combined.sh
1 #!/bin/sh
2
3 test_description='combined diff'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/diff-lib.sh
7
8 setup_helper () {
9         one=$1 branch=$2 side=$3 &&
10
11         git branch $side $branch &&
12         for l in $one two three fyra
13         do
14                 echo $l
15         done >file &&
16         git add file &&
17         test_tick &&
18         git commit -m $branch &&
19         git checkout $side &&
20         for l in $one two three quatro
21         do
22                 echo $l
23         done >file &&
24         git add file &&
25         test_tick &&
26         git commit -m $side &&
27         test_must_fail git merge $branch &&
28         for l in $one three four
29         do
30                 echo $l
31         done >file &&
32         git add file &&
33         test_tick &&
34         git commit -m "merge $branch into $side"
35 }
36
37 verify_helper () {
38         it=$1 &&
39
40         # Ignore lines that were removed only from the other parent
41         sed -e '
42                 1,/^@@@/d
43                 /^ -/d
44                 s/^\(.\)./\1/
45         ' "$it" >"$it.actual.1" &&
46         sed -e '
47                 1,/^@@@/d
48                 /^- /d
49                 s/^.\(.\)/\1/
50         ' "$it" >"$it.actual.2" &&
51
52         git diff "$it^" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.1" &&
53         test_cmp "$it.expect.1" "$it.actual.1" &&
54
55         git diff "$it^2" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.2" &&
56         test_cmp "$it.expect.2" "$it.actual.2"
57 }
58
59 test_expect_success setup '
60         >file &&
61         git add file &&
62         test_tick &&
63         git commit -m initial &&
64
65         git branch withone &&
66         git branch sansone &&
67
68         git checkout withone &&
69         setup_helper one withone sidewithone &&
70
71         git checkout sansone &&
72         setup_helper "" sansone sidesansone
73 '
74
75 test_expect_success 'check combined output (1)' '
76         git show sidewithone -- >sidewithone &&
77         verify_helper sidewithone
78 '
79
80 test_expect_success 'check combined output (2)' '
81         git show sidesansone -- >sidesansone &&
82         verify_helper sidesansone
83 '
84
85 test_expect_success 'diagnose truncated file' '
86         >file &&
87         git add file &&
88         git commit --amend -C HEAD &&
89         git show >out &&
90         grep "diff --cc file" out
91 '
92
93 test_expect_success 'setup for --cc --raw' '
94         blob=$(echo file | git hash-object --stdin -w) &&
95         base_tree=$(echo "100644 blob $blob     file" | git mktree) &&
96         trees= &&
97         for i in $(test_seq 1 40)
98         do
99                 blob=$(echo file$i | git hash-object --stdin -w) &&
100                 trees="$trees$(echo "100644 blob $blob  file" | git mktree)$LF"
101         done
102 '
103
104 test_expect_success 'check --cc --raw with four trees' '
105         four_trees=$(echo "$trees" | sed -e 4q) &&
106         git diff --cc --raw $four_trees $base_tree >out &&
107         # Check for four leading colons in the output:
108         grep "^::::[^:]" out
109 '
110
111 test_expect_success 'check --cc --raw with forty trees' '
112         git diff --cc --raw $trees $base_tree >out &&
113         # Check for forty leading colons in the output:
114         grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
115 '
116
117 test_expect_success 'setup combined ignore spaces' '
118         git checkout master &&
119         >test &&
120         git add test &&
121         git commit -m initial &&
122
123         tr -d Q <<-\EOF >test &&
124         always coalesce
125         eol space coalesce Q
126         space  change coalesce
127         all spa ces coalesce
128         eol spaces Q
129         space  change
130         all spa ces
131         EOF
132         git commit -m "test space change" -a &&
133
134         git checkout -b side HEAD^ &&
135         tr -d Q <<-\EOF >test &&
136         always coalesce
137         eol space coalesce
138         space change coalesce
139         all spaces coalesce
140         eol spaces
141         space change
142         all spaces
143         EOF
144         git commit -m "test other space changes" -a &&
145
146         test_must_fail git merge master &&
147         tr -d Q <<-\EOF >test &&
148         eol spaces Q
149         space  change
150         all spa ces
151         EOF
152         git commit -m merged -a
153 '
154
155 test_expect_success 'check combined output (no ignore space)' '
156         git show >actual.tmp &&
157         sed -e "1,/^@@@/d" < actual.tmp >actual &&
158         tr -d Q <<-\EOF >expected &&
159         --always coalesce
160         - eol space coalesce
161         - space change coalesce
162         - all spaces coalesce
163         - eol spaces
164         - space change
165         - all spaces
166          -eol space coalesce Q
167          -space  change coalesce
168          -all spa ces coalesce
169         + eol spaces Q
170         + space  change
171         + all spa ces
172         EOF
173         compare_diff_patch expected actual
174 '
175
176 test_expect_success 'check combined output (ignore space at eol)' '
177         git show --ignore-space-at-eol >actual.tmp &&
178         sed -e "1,/^@@@/d" < actual.tmp >actual &&
179         tr -d Q <<-\EOF >expected &&
180         --always coalesce
181         --eol space coalesce
182         - space change coalesce
183         - all spaces coalesce
184          -space  change coalesce
185          -all spa ces coalesce
186           eol spaces Q
187         - space change
188         - all spaces
189         + space  change
190         + all spa ces
191         EOF
192         compare_diff_patch expected actual
193 '
194
195 test_expect_success 'check combined output (ignore space change)' '
196         git show -b >actual.tmp &&
197         sed -e "1,/^@@@/d" < actual.tmp >actual &&
198         tr -d Q <<-\EOF >expected &&
199         --always coalesce
200         --eol space coalesce
201         --space change coalesce
202         - all spaces coalesce
203          -all spa ces coalesce
204           eol spaces Q
205           space  change
206         - all spaces
207         + all spa ces
208         EOF
209         compare_diff_patch expected actual
210 '
211
212 test_expect_success 'check combined output (ignore all spaces)' '
213         git show -w >actual.tmp &&
214         sed -e "1,/^@@@/d" < actual.tmp >actual &&
215         tr -d Q <<-\EOF >expected &&
216         --always coalesce
217         --eol space coalesce
218         --space change coalesce
219         --all spaces coalesce
220           eol spaces Q
221           space  change
222           all spa ces
223         EOF
224         compare_diff_patch expected actual
225 '
226
227 test_expect_success 'combine diff coalesce simple' '
228         >test &&
229         git add test &&
230         git commit -m initial &&
231         test_seq 4 >test &&
232         git commit -a -m empty1 &&
233         git branch side1 &&
234         git checkout HEAD^ &&
235         test_seq 5 >test &&
236         git commit -a -m empty2 &&
237         test_must_fail git merge side1 &&
238         >test &&
239         git commit -a -m merge &&
240         git show >actual.tmp &&
241         sed -e "1,/^@@@/d" < actual.tmp >actual &&
242         tr -d Q <<-\EOF >expected &&
243         --1
244         --2
245         --3
246         --4
247         - 5
248         EOF
249         compare_diff_patch expected actual
250 '
251
252 test_expect_success 'combine diff coalesce tricky' '
253         >test &&
254         git add test &&
255         git commit -m initial --allow-empty &&
256         cat <<-\EOF >test &&
257         3
258         1
259         2
260         3
261         4
262         EOF
263         git commit -a -m empty1 &&
264         git branch -f side1 &&
265         git checkout HEAD^ &&
266         cat <<-\EOF >test &&
267         1
268         3
269         5
270         4
271         EOF
272         git commit -a -m empty2 &&
273         git branch -f side2 &&
274         test_must_fail git merge side1 &&
275         >test &&
276         git commit -a -m merge &&
277         git show >actual.tmp &&
278         sed -e "1,/^@@@/d" < actual.tmp >actual &&
279         tr -d Q <<-\EOF >expected &&
280          -3
281         --1
282          -2
283         --3
284         - 5
285         --4
286         EOF
287         compare_diff_patch expected actual &&
288         git checkout -f side1 &&
289         test_must_fail git merge side2 &&
290         >test &&
291         git commit -a -m merge &&
292         git show >actual.tmp &&
293         sed -e "1,/^@@@/d" < actual.tmp >actual &&
294         tr -d Q <<-\EOF >expected &&
295         - 3
296         --1
297         - 2
298         --3
299          -5
300         --4
301         EOF
302         compare_diff_patch expected actual
303 '
304
305 test_expect_failure 'combine diff coalesce three parents' '
306         >test &&
307         git add test &&
308         git commit -m initial --allow-empty &&
309         cat <<-\EOF >test &&
310         3
311         1
312         2
313         3
314         4
315         EOF
316         git commit -a -m empty1 &&
317         git checkout -B side1 &&
318         git checkout HEAD^ &&
319         cat <<-\EOF >test &&
320         1
321         3
322         7
323         5
324         4
325         EOF
326         git commit -a -m empty2 &&
327         git branch -f side2 &&
328         git checkout HEAD^ &&
329         cat <<-\EOF >test &&
330         3
331         1
332         6
333         5
334         4
335         EOF
336         git commit -a -m empty3 &&
337         >test &&
338         git add test &&
339         TREE=$(git write-tree) &&
340         COMMIT=$(git commit-tree -p HEAD -p side1 -p side2 -m merge $TREE) &&
341         git show $COMMIT >actual.tmp &&
342         sed -e "1,/^@@@/d" < actual.tmp >actual &&
343         tr -d Q <<-\EOF >expected &&
344         -- 3
345         ---1
346         -  6
347          - 2
348          --3
349           -7
350         - -5
351         ---4
352         EOF
353         compare_diff_patch expected actual
354 '
355
356 # Test for a bug reported at
357 # https://lore.kernel.org/git/20130515143508.GO25742@login.drsnuggles.stderr.nl/
358 # where a delete lines were missing from combined diff output when they
359 # occurred exactly before the context lines of a later change.
360 test_expect_success 'combine diff missing delete bug' '
361         git commit -m initial --allow-empty &&
362         cat <<-\EOF >test &&
363         1
364         2
365         3
366         4
367         EOF
368         git add test &&
369         git commit -a -m side1 &&
370         git checkout -B side1 &&
371         git checkout HEAD^ &&
372         cat <<-\EOF >test &&
373         0
374         1
375         2
376         3
377         4modified
378         EOF
379         git add test &&
380         git commit -m side2 &&
381         git branch -f side2 &&
382         test_must_fail git merge --no-commit side1 &&
383         cat <<-\EOF >test &&
384         1
385         2
386         3
387         4modified
388         EOF
389         git add test &&
390         git commit -a -m merge &&
391         git diff-tree -c -p HEAD >actual.tmp &&
392         sed -e "1,/^@@@/d" < actual.tmp >actual &&
393         tr -d Q <<-\EOF >expected &&
394         - 0
395           1
396           2
397           3
398          -4
399          +4modified
400         EOF
401         compare_diff_patch expected actual
402 '
403
404 test_expect_success 'combine diff gets tree sorting right' '
405         # create a directory and a file that sort differently in trees
406         # versus byte-wise (implied "/" sorts after ".")
407         git checkout -f master &&
408         mkdir foo &&
409         echo base >foo/one &&
410         echo base >foo/two &&
411         echo base >foo.ext &&
412         git add foo foo.ext &&
413         git commit -m base &&
414
415         # one side modifies a file in the directory, along with the root
416         # file...
417         echo master >foo/one &&
418         echo master >foo.ext &&
419         git commit -a -m master &&
420
421         # the other side modifies the other file in the directory
422         git checkout -b other HEAD^ &&
423         echo other >foo/two &&
424         git commit -a -m other &&
425
426         # And now we merge. The files in the subdirectory will resolve cleanly,
427         # meaning that a combined diff will not find them interesting. But it
428         # will find the tree itself interesting, because it had to be merged.
429         git checkout master &&
430         git merge other &&
431
432         printf "MM\tfoo\n" >expect &&
433         git diff-tree -c --name-status -t HEAD >actual.tmp &&
434         sed 1d <actual.tmp >actual &&
435         test_cmp expect actual
436 '
437
438 test_expect_success 'setup for --combined-all-paths' '
439         git branch side1c &&
440         git branch side2c &&
441         git checkout side1c &&
442         test_seq 1 10 >filename-side1c &&
443         side1cf=$(git hash-object filename-side1c) &&
444         git add filename-side1c &&
445         git commit -m with &&
446         git checkout side2c &&
447         test_seq 1 9 >filename-side2c &&
448         echo ten >>filename-side2c &&
449         side2cf=$(git hash-object filename-side2c) &&
450         git add filename-side2c &&
451         git commit -m iam &&
452         git checkout -b mergery side1c &&
453         git merge --no-commit side2c &&
454         git rm filename-side1c &&
455         echo eleven >>filename-side2c &&
456         git mv filename-side2c filename-merged &&
457         mergedf=$(git hash-object filename-merged) &&
458         git add filename-merged &&
459         git commit
460 '
461
462 test_expect_success '--combined-all-paths and --raw' '
463         cat <<-EOF >expect &&
464         ::100644 100644 100644 $side1cf $side2cf $mergedf RR    filename-side1c filename-side2c filename-merged
465         EOF
466         git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp &&
467         sed 1d <actual.tmp >actual &&
468         test_cmp expect actual
469 '
470
471 test_expect_success '--combined-all-paths and --cc' '
472         cat <<-\EOF >expect &&
473         --- a/filename-side1c
474         --- a/filename-side2c
475         +++ b/filename-merged
476         EOF
477         git diff-tree --cc -M --combined-all-paths HEAD >actual.tmp &&
478         grep ^[-+][-+][-+] <actual.tmp >actual &&
479         test_cmp expect actual
480 '
481
482 test_expect_success FUNNYNAMES 'setup for --combined-all-paths with funny names' '
483         git branch side1d &&
484         git branch side2d &&
485         git checkout side1d &&
486         test_seq 1 10 >"$(printf "file\twith\ttabs")" &&
487         git add file* &&
488         side1df=$(git hash-object *tabs) &&
489         git commit -m with &&
490         git checkout side2d &&
491         test_seq 1 9 >"$(printf "i\tam\ttabbed")" &&
492         echo ten >>"$(printf "i\tam\ttabbed")" &&
493         git add *tabbed &&
494         side2df=$(git hash-object *tabbed) &&
495         git commit -m iam &&
496         git checkout -b funny-names-mergery side1d &&
497         git merge --no-commit side2d &&
498         git rm *tabs &&
499         echo eleven >>"$(printf "i\tam\ttabbed")" &&
500         git mv "$(printf "i\tam\ttabbed")" "$(printf "fickle\tnaming")" &&
501         git add fickle* &&
502         headf=$(git hash-object fickle*) &&
503         git commit &&
504         head=$(git rev-parse HEAD)
505 '
506
507 test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names' '
508         cat <<-EOF >expect &&
509         ::100644 100644 100644 $side1df $side2df $headf RR      "file\twith\ttabs"      "i\tam\ttabbed" "fickle\tnaming"
510         EOF
511         git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp &&
512         sed 1d <actual.tmp >actual &&
513         test_cmp expect actual
514 '
515
516 test_expect_success FUNNYNAMES '--combined-all-paths and --raw -and -z and funny names' '
517         printf "$head\0::100644 100644 100644 $side1df $side2df $headf RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect &&
518         git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual &&
519         test_cmp expect actual
520 '
521
522 test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' '
523         cat <<-\EOF >expect &&
524         --- "a/file\twith\ttabs"
525         --- "a/i\tam\ttabbed"
526         +++ "b/fickle\tnaming"
527         EOF
528         git diff-tree --cc -M --combined-all-paths HEAD >actual.tmp &&
529         grep ^[-+][-+][-+] <actual.tmp >actual &&
530         test_cmp expect actual
531 '
532
533 test_done