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