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