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