Sync with maint
[git] / t / t4041-diff-submodule-option.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2009 Jens Lehmann, based on t7401 by Ping Yin
4 #
5
6 test_description='Support for verbose submodule differences in git diff
7
8 This test tries to verify the sanity of the --submodule option of git diff.
9 '
10
11 . ./test-lib.sh
12
13 add_file () {
14         (
15                 cd "$1" &&
16                 shift &&
17                 for name
18                 do
19                         echo "$name" >"$name" &&
20                         git add "$name" &&
21                         test_tick &&
22                         git commit -m "Add $name" || exit
23                 done >/dev/null &&
24                 git rev-parse --short --verify HEAD
25         )
26 }
27 commit_file () {
28         test_tick &&
29         git commit "$@" -m "Commit $*" >/dev/null
30 }
31
32 test_create_repo sm1 &&
33 add_file . foo >/dev/null
34
35 head1=$(add_file sm1 foo1 foo2)
36 fullhead1=$(cd sm1; git rev-parse --verify HEAD)
37
38 test_expect_success 'added submodule' '
39         git add sm1 &&
40         git diff-index -p --submodule=log HEAD >actual &&
41         cat >expected <<-EOF &&
42         Submodule sm1 0000000...$head1 (new submodule)
43         EOF
44         test_cmp expected actual
45 '
46
47 test_expect_success 'added submodule, set diff.submodule' '
48         git config diff.submodule log &&
49         git add sm1 &&
50         git diff --cached >actual &&
51         cat >expected <<-EOF &&
52         Submodule sm1 0000000...$head1 (new submodule)
53         EOF
54         git config --unset diff.submodule &&
55         test_cmp expected actual
56 '
57
58 test_expect_success '--submodule=short overrides diff.submodule' '
59         test_config diff.submodule log &&
60         git add sm1 &&
61         git diff --submodule=short --cached >actual &&
62         cat >expected <<-EOF &&
63         diff --git a/sm1 b/sm1
64         new file mode 160000
65         index 0000000..$head1
66         --- /dev/null
67         +++ b/sm1
68         @@ -0,0 +1 @@
69         +Subproject commit $fullhead1
70         EOF
71         test_cmp expected actual
72 '
73
74 test_expect_success 'diff.submodule does not affect plumbing' '
75         test_config diff.submodule log &&
76         git diff-index -p HEAD >actual &&
77         cat >expected <<-EOF &&
78         diff --git a/sm1 b/sm1
79         new file mode 160000
80         index 0000000..$head1
81         --- /dev/null
82         +++ b/sm1
83         @@ -0,0 +1 @@
84         +Subproject commit $fullhead1
85         EOF
86         test_cmp expected actual
87 '
88
89 commit_file sm1 &&
90 head2=$(add_file sm1 foo3)
91
92 test_expect_success 'modified submodule(forward)' '
93         git diff-index -p --submodule=log HEAD >actual &&
94         cat >expected <<-EOF &&
95         Submodule sm1 $head1..$head2:
96           > Add foo3
97         EOF
98         test_cmp expected actual
99 '
100
101 test_expect_success 'modified submodule(forward)' '
102         git diff --submodule=log >actual &&
103         cat >expected <<-EOF &&
104         Submodule sm1 $head1..$head2:
105           > Add foo3
106         EOF
107         test_cmp expected actual
108 '
109
110 test_expect_success 'modified submodule(forward) --submodule' '
111         git diff --submodule >actual &&
112         cat >expected <<-EOF &&
113         Submodule sm1 $head1..$head2:
114           > Add foo3
115         EOF
116         test_cmp expected actual
117 '
118
119 fullhead2=$(cd sm1; git rev-parse --verify HEAD)
120 test_expect_success 'modified submodule(forward) --submodule=short' '
121         git diff --submodule=short >actual &&
122         cat >expected <<-EOF &&
123         diff --git a/sm1 b/sm1
124         index $head1..$head2 160000
125         --- a/sm1
126         +++ b/sm1
127         @@ -1 +1 @@
128         -Subproject commit $fullhead1
129         +Subproject commit $fullhead2
130         EOF
131         test_cmp expected actual
132 '
133
134 commit_file sm1 &&
135 head3=$(
136         cd sm1 &&
137         git reset --hard HEAD~2 >/dev/null &&
138         git rev-parse --short --verify HEAD
139 )
140
141 test_expect_success 'modified submodule(backward)' '
142         git diff-index -p --submodule=log HEAD >actual &&
143         cat >expected <<-EOF &&
144         Submodule sm1 $head2..$head3 (rewind):
145           < Add foo3
146           < Add foo2
147         EOF
148         test_cmp expected actual
149 '
150
151 head4=$(add_file sm1 foo4 foo5)
152 test_expect_success 'modified submodule(backward and forward)' '
153         git diff-index -p --submodule=log HEAD >actual &&
154         cat >expected <<-EOF &&
155         Submodule sm1 $head2...$head4:
156           > Add foo5
157           > Add foo4
158           < Add foo3
159           < Add foo2
160         EOF
161         test_cmp expected actual
162 '
163
164 commit_file sm1 &&
165 mv sm1 sm1-bak &&
166 echo sm1 >sm1 &&
167 head5=$(git hash-object sm1 | cut -c1-7) &&
168 git add sm1 &&
169 rm -f sm1 &&
170 mv sm1-bak sm1
171
172 test_expect_success 'typechanged submodule(submodule->blob), --cached' '
173         git diff --submodule=log --cached >actual &&
174         cat >expected <<-EOF &&
175         Submodule sm1 $head4...0000000 (submodule deleted)
176         diff --git a/sm1 b/sm1
177         new file mode 100644
178         index 0000000..$head5
179         --- /dev/null
180         +++ b/sm1
181         @@ -0,0 +1 @@
182         +sm1
183         EOF
184         test_cmp expected actual
185 '
186
187 test_expect_success 'typechanged submodule(submodule->blob)' '
188         git diff --submodule=log >actual &&
189         cat >expected <<-EOF &&
190         diff --git a/sm1 b/sm1
191         deleted file mode 100644
192         index $head5..0000000
193         --- a/sm1
194         +++ /dev/null
195         @@ -1 +0,0 @@
196         -sm1
197         Submodule sm1 0000000...$head4 (new submodule)
198         EOF
199         test_cmp expected actual
200 '
201
202 rm -rf sm1 &&
203 git checkout-index sm1
204 test_expect_success 'typechanged submodule(submodule->blob)' '
205         git diff-index -p --submodule=log HEAD >actual &&
206         cat >expected <<-EOF &&
207         Submodule sm1 $head4...0000000 (submodule deleted)
208         diff --git a/sm1 b/sm1
209         new file mode 100644
210         index 0000000..$head5
211         --- /dev/null
212         +++ b/sm1
213         @@ -0,0 +1 @@
214         +sm1
215         EOF
216         test_cmp expected actual
217 '
218
219 rm -f sm1 &&
220 test_create_repo sm1 &&
221 head6=$(add_file sm1 foo6 foo7)
222 fullhead6=$(cd sm1; git rev-parse --verify HEAD)
223 test_expect_success 'nonexistent commit' '
224         git diff-index -p --submodule=log HEAD >actual &&
225         cat >expected <<-EOF &&
226         Submodule sm1 $head4...$head6 (commits not present)
227         EOF
228         test_cmp expected actual
229 '
230
231 commit_file
232 test_expect_success 'typechanged submodule(blob->submodule)' '
233         git diff-index -p --submodule=log HEAD >actual &&
234         cat >expected <<-EOF &&
235         diff --git a/sm1 b/sm1
236         deleted file mode 100644
237         index $head5..0000000
238         --- a/sm1
239         +++ /dev/null
240         @@ -1 +0,0 @@
241         -sm1
242         Submodule sm1 0000000...$head6 (new submodule)
243         EOF
244         test_cmp expected actual
245 '
246
247 commit_file sm1 &&
248 test_expect_success 'submodule is up to date' '
249         git diff-index -p --submodule=log HEAD >actual &&
250         cat >expected <<-EOF &&
251         EOF
252         test_cmp expected actual
253 '
254
255 test_expect_success 'submodule contains untracked content' '
256         echo new > sm1/new-file &&
257         git diff-index -p --submodule=log HEAD >actual &&
258         cat >expected <<-EOF &&
259         Submodule sm1 contains untracked content
260         EOF
261         test_cmp expected actual
262 '
263
264 test_expect_success 'submodule contains untracked content (untracked ignored)' '
265         git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
266         ! test -s actual
267 '
268
269 test_expect_success 'submodule contains untracked content (dirty ignored)' '
270         git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
271         ! test -s actual
272 '
273
274 test_expect_success 'submodule contains untracked content (all ignored)' '
275         git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
276         ! test -s actual
277 '
278
279 test_expect_success 'submodule contains untracked and modifed content' '
280         echo new > sm1/foo6 &&
281         git diff-index -p --submodule=log HEAD >actual &&
282         cat >expected <<-EOF &&
283         Submodule sm1 contains untracked content
284         Submodule sm1 contains modified content
285         EOF
286         test_cmp expected actual
287 '
288
289 test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' '
290         echo new > sm1/foo6 &&
291         git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
292         cat >expected <<-EOF &&
293         Submodule sm1 contains modified content
294         EOF
295         test_cmp expected actual
296 '
297
298 test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' '
299         echo new > sm1/foo6 &&
300         git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
301         ! test -s actual
302 '
303
304 test_expect_success 'submodule contains untracked and modifed content (all ignored)' '
305         echo new > sm1/foo6 &&
306         git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
307         ! test -s actual
308 '
309
310 test_expect_success 'submodule contains modifed content' '
311         rm -f sm1/new-file &&
312         git diff-index -p --submodule=log HEAD >actual &&
313         cat >expected <<-EOF &&
314         Submodule sm1 contains modified content
315         EOF
316         test_cmp expected actual
317 '
318
319 (cd sm1; git commit -mchange foo6 >/dev/null) &&
320 head8=$(cd sm1; git rev-parse --short --verify HEAD) &&
321 test_expect_success 'submodule is modified' '
322         git diff-index -p --submodule=log HEAD >actual &&
323         cat >expected <<-EOF &&
324         Submodule sm1 $head6..$head8:
325           > change
326         EOF
327         test_cmp expected actual
328 '
329
330 test_expect_success 'modified submodule contains untracked content' '
331         echo new > sm1/new-file &&
332         git diff-index -p --submodule=log HEAD >actual &&
333         cat >expected <<-EOF &&
334         Submodule sm1 contains untracked content
335         Submodule sm1 $head6..$head8:
336           > change
337         EOF
338         test_cmp expected actual
339 '
340
341 test_expect_success 'modified submodule contains untracked content (untracked ignored)' '
342         git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
343         cat >expected <<-EOF &&
344         Submodule sm1 $head6..$head8:
345           > change
346         EOF
347         test_cmp expected actual
348 '
349
350 test_expect_success 'modified submodule contains untracked content (dirty ignored)' '
351         git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
352         cat >expected <<-EOF &&
353         Submodule sm1 $head6..$head8:
354           > change
355         EOF
356         test_cmp expected actual
357 '
358
359 test_expect_success 'modified submodule contains untracked content (all ignored)' '
360         git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
361         ! test -s actual
362 '
363
364 test_expect_success 'modified submodule contains untracked and modifed content' '
365         echo modification >> sm1/foo6 &&
366         git diff-index -p --submodule=log HEAD >actual &&
367         cat >expected <<-EOF &&
368         Submodule sm1 contains untracked content
369         Submodule sm1 contains modified content
370         Submodule sm1 $head6..$head8:
371           > change
372         EOF
373         test_cmp expected actual
374 '
375
376 test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' '
377         echo modification >> sm1/foo6 &&
378         git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
379         cat >expected <<-EOF &&
380         Submodule sm1 contains modified content
381         Submodule sm1 $head6..$head8:
382           > change
383         EOF
384         test_cmp expected actual
385 '
386
387 test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' '
388         echo modification >> sm1/foo6 &&
389         git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
390         cat >expected <<-EOF &&
391         Submodule sm1 $head6..$head8:
392           > change
393         EOF
394         test_cmp expected actual
395 '
396
397 test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' '
398         echo modification >> sm1/foo6 &&
399         git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
400         ! test -s actual
401 '
402
403 test_expect_success 'modified submodule contains modifed content' '
404         rm -f sm1/new-file &&
405         git diff-index -p --submodule=log HEAD >actual &&
406         cat >expected <<-EOF &&
407         Submodule sm1 contains modified content
408         Submodule sm1 $head6..$head8:
409           > change
410         EOF
411         test_cmp expected actual
412 '
413
414 rm -rf sm1
415 test_expect_success 'deleted submodule' '
416         git diff-index -p --submodule=log HEAD >actual &&
417         cat >expected <<-EOF &&
418         Submodule sm1 $head6...0000000 (submodule deleted)
419         EOF
420         test_cmp expected actual
421 '
422
423 test_create_repo sm2 &&
424 head7=$(add_file sm2 foo8 foo9) &&
425 git add sm2
426
427 test_expect_success 'multiple submodules' '
428         git diff-index -p --submodule=log HEAD >actual &&
429         cat >expected <<-EOF &&
430         Submodule sm1 $head6...0000000 (submodule deleted)
431         Submodule sm2 0000000...$head7 (new submodule)
432         EOF
433         test_cmp expected actual
434 '
435
436 test_expect_success 'path filter' '
437         git diff-index -p --submodule=log HEAD sm2 >actual &&
438         cat >expected <<-EOF &&
439         Submodule sm2 0000000...$head7 (new submodule)
440         EOF
441         test_cmp expected actual
442 '
443
444 commit_file sm2
445 test_expect_success 'given commit' '
446         git diff-index -p --submodule=log HEAD^ >actual &&
447         cat >expected <<-EOF &&
448         Submodule sm1 $head6...0000000 (submodule deleted)
449         Submodule sm2 0000000...$head7 (new submodule)
450         EOF
451         test_cmp expected actual
452 '
453
454 test_expect_success 'given commit --submodule' '
455         git diff-index -p --submodule HEAD^ >actual &&
456         cat >expected <<-EOF &&
457         Submodule sm1 $head6...0000000 (submodule deleted)
458         Submodule sm2 0000000...$head7 (new submodule)
459         EOF
460         test_cmp expected actual
461 '
462
463 fullhead7=$(cd sm2; git rev-parse --verify HEAD)
464
465 test_expect_success 'given commit --submodule=short' '
466         git diff-index -p --submodule=short HEAD^ >actual &&
467         cat >expected <<-EOF &&
468         diff --git a/sm1 b/sm1
469         deleted file mode 160000
470         index $head6..0000000
471         --- a/sm1
472         +++ /dev/null
473         @@ -1 +0,0 @@
474         -Subproject commit $fullhead6
475         diff --git a/sm2 b/sm2
476         new file mode 160000
477         index 0000000..$head7
478         --- /dev/null
479         +++ b/sm2
480         @@ -0,0 +1 @@
481         +Subproject commit $fullhead7
482         EOF
483         test_cmp expected actual
484 '
485
486 test_expect_success 'setup .git file for sm2' '
487         (cd sm2 &&
488          REAL="$(pwd)/../.real" &&
489          mv .git "$REAL"
490          echo "gitdir: $REAL" >.git)
491 '
492
493 test_expect_success 'diff --submodule with .git file' '
494         git diff --submodule HEAD^ >actual &&
495         cat >expected <<-EOF &&
496         Submodule sm1 $head6...0000000 (submodule deleted)
497         Submodule sm2 0000000...$head7 (new submodule)
498         EOF
499         test_cmp expected actual
500 '
501
502 test_expect_success 'diff --submodule with objects referenced by alternates' '
503         mkdir sub_alt &&
504         (cd sub_alt &&
505                 git init &&
506                 echo a >a &&
507                 git add a &&
508                 git commit -m a
509         ) &&
510         mkdir super &&
511         (cd super &&
512                 git clone -s ../sub_alt sub &&
513                 git init &&
514                 git add sub &&
515                 git commit -m "sub a"
516         ) &&
517         (cd sub_alt &&
518                 sha1_before=$(git rev-parse --short HEAD)
519                 echo b >b &&
520                 git add b &&
521                 git commit -m b
522                 sha1_after=$(git rev-parse --short HEAD)
523                 echo "Submodule sub $sha1_before..$sha1_after:
524   > b" >../expected
525         ) &&
526         (cd super &&
527                 (cd sub &&
528                         git fetch &&
529                         git checkout origin/master
530                 ) &&
531                 git diff --submodule > ../actual
532         )
533         test_cmp expected actual
534 '
535
536 test_done