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