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