Skip to content

Commit dd44d41

Browse files
jlehmanngitster
authored andcommitted
Add optional parameters to the diff option "--ignore-submodules"
In some use cases it is not desirable that the diff family considers submodules that only contain untracked content as dirty. This may happen e.g. when the submodule is not under the developers control and not all build generated files have been added to .gitignore by the upstream developers. Using the "untracked" parameter for the "--ignore-submodules" option disables checking for untracked content and lets git diff report them as changed only when they have new commits or modified content. Sometimes it is not wanted to have submodules show up as changed when they just contain changes to their work tree. An example for that are scripts which just want to check for submodule commits while ignoring any changes to the work tree. Also users having large submodules known not to change might want to use this option, as the - sometimes substantial - time it takes to scan the submodule work tree(s) is saved. Signed-off-by: Jens Lehmann <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cf6aef8 commit dd44d41

File tree

6 files changed

+118
-6
lines changed

6 files changed

+118
-6
lines changed

Documentation/diff-options.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,14 @@ endif::git-format-patch[]
288288
--no-ext-diff::
289289
Disallow external diff drivers.
290290

291-
--ignore-submodules::
292-
Ignore changes to submodules in the diff generation.
291+
--ignore-submodules[=<when>]::
292+
Ignore changes to submodules in the diff generation. <when> can be
293+
either "untracked", "dirty" or "all", which is the default. When
294+
"untracked" is used submodules are not considered dirty when they only
295+
contain untracked content (but they are still scanned for modified
296+
content). Using "dirty" ignores all changes to the work tree of submodules,
297+
only changes to the commits stored in the superproject are shown (this was
298+
the behavior until 1.7.0). Using "all" hides all changes to submodules.
293299

294300
--src-prefix=<prefix>::
295301
Show the given source prefix instead of "a/".

diff-lib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt,
7070
int changed = ce_match_stat(ce, st, ce_option);
7171
if (S_ISGITLINK(ce->ce_mode)
7272
&& !DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES)
73+
&& !DIFF_OPT_TST(diffopt, IGNORE_DIRTY_SUBMODULES)
7374
&& (!changed || DIFF_OPT_TST(diffopt, DIRTY_SUBMODULES))) {
7475
*dirty_submodule = is_submodule_modified(ce->name, DIFF_OPT_TST(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES));
7576
}

diff.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2867,7 +2867,16 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
28672867
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
28682868
else if (!strcmp(arg, "--ignore-submodules"))
28692869
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
2870-
else if (!strcmp(arg, "--submodule"))
2870+
else if (!prefixcmp(arg, "--ignore-submodules=")) {
2871+
if (!strcmp(arg + 20, "all"))
2872+
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
2873+
else if (!strcmp(arg + 20, "untracked"))
2874+
DIFF_OPT_SET(options, IGNORE_UNTRACKED_IN_SUBMODULES);
2875+
else if (!strcmp(arg + 20, "dirty"))
2876+
DIFF_OPT_SET(options, IGNORE_DIRTY_SUBMODULES);
2877+
else
2878+
die("bad --ignore-submodules argument: %s", arg + 20);
2879+
} else if (!strcmp(arg, "--submodule"))
28712880
DIFF_OPT_SET(options, SUBMODULE_LOG);
28722881
else if (!prefixcmp(arg, "--submodule=")) {
28732882
if (!strcmp(arg + 12, "log"))

diff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
7171
#define DIFF_OPT_SUBMODULE_LOG (1 << 23)
7272
#define DIFF_OPT_DIRTY_SUBMODULES (1 << 24)
7373
#define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25)
74+
#define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)
7475

7576
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
7677
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)

t/t4027-diff-submodule.sh

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,17 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'
103103
git diff HEAD >actual &&
104104
sed -e "1,/^@@/d" actual >actual.body &&
105105
expect_from_to >expect.body $subprev $subprev-dirty &&
106-
test_cmp expect.body actual.body
106+
test_cmp expect.body actual.body &&
107+
git diff --ignore-submodules HEAD >actual2 &&
108+
echo -n "" | test_cmp - actual2 &&
109+
git diff --ignore-submodules=untracked HEAD >actual3 &&
110+
sed -e "1,/^@@/d" actual3 >actual3.body &&
111+
expect_from_to >expect.body $subprev $subprev-dirty &&
112+
test_cmp expect.body actual3.body &&
113+
git diff --ignore-submodules=dirty HEAD >actual4 &&
114+
echo -n "" | test_cmp - actual4
107115
'
108-
116+
test_done
109117
test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' '
110118
(
111119
cd sub &&
@@ -129,7 +137,13 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)'
129137
git diff HEAD >actual &&
130138
sed -e "1,/^@@/d" actual >actual.body &&
131139
expect_from_to >expect.body $subprev $subprev-dirty &&
132-
test_cmp expect.body actual.body
140+
test_cmp expect.body actual.body &&
141+
git diff --ignore-submodules=all HEAD >actual2 &&
142+
echo -n "" | test_cmp - actual2 &&
143+
git diff --ignore-submodules=untracked HEAD >actual3 &&
144+
echo -n "" | test_cmp - actual3 &&
145+
git diff --ignore-submodules=dirty HEAD >actual4 &&
146+
echo -n "" | test_cmp - actual4
133147
'
134148

135149
test_expect_success 'git diff (empty submodule dir)' '

t/t4041-diff-submodule-option.sh

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,21 @@ Submodule sm1 contains untracked content
205205
EOF
206206
"
207207

208+
test_expect_success 'submodule contains untracked content (untracked ignored)' "
209+
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
210+
echo -n '' | diff actual -
211+
"
212+
213+
test_expect_success 'submodule contains untracked content (dirty ignored)' "
214+
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
215+
echo -n '' | diff actual -
216+
"
217+
218+
test_expect_success 'submodule contains untracked content (all ignored)' "
219+
git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
220+
echo -n '' | diff actual -
221+
"
222+
208223
test_expect_success 'submodule contains untracked and modifed content' "
209224
echo new > sm1/foo6 &&
210225
git diff-index -p --submodule=log HEAD >actual &&
@@ -214,6 +229,26 @@ Submodule sm1 contains modified content
214229
EOF
215230
"
216231

232+
test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' "
233+
echo new > sm1/foo6 &&
234+
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
235+
diff actual - <<-EOF
236+
Submodule sm1 contains modified content
237+
EOF
238+
"
239+
240+
test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' "
241+
echo new > sm1/foo6 &&
242+
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
243+
echo -n '' | diff actual -
244+
"
245+
246+
test_expect_success 'submodule contains untracked and modifed content (all ignored)' "
247+
echo new > sm1/foo6 &&
248+
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
249+
echo -n '' | diff actual -
250+
"
251+
217252
test_expect_success 'submodule contains modifed content' "
218253
rm -f sm1/new-file &&
219254
git diff-index -p --submodule=log HEAD >actual &&
@@ -242,6 +277,27 @@ Submodule sm1 $head6..$head8:
242277
EOF
243278
"
244279

280+
test_expect_success 'modified submodule contains untracked content (untracked ignored)' "
281+
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
282+
diff actual - <<-EOF
283+
Submodule sm1 $head6..$head8:
284+
> change
285+
EOF
286+
"
287+
288+
test_expect_success 'modified submodule contains untracked content (dirty ignored)' "
289+
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
290+
diff actual - <<-EOF
291+
Submodule sm1 $head6..$head8:
292+
> change
293+
EOF
294+
"
295+
296+
test_expect_success 'modified submodule contains untracked content (all ignored)' "
297+
git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
298+
echo -n '' | diff actual -
299+
"
300+
245301
test_expect_success 'modified submodule contains untracked and modifed content' "
246302
echo modification >> sm1/foo6 &&
247303
git diff-index -p --submodule=log HEAD >actual &&
@@ -253,6 +309,31 @@ Submodule sm1 $head6..$head8:
253309
EOF
254310
"
255311

312+
test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' "
313+
echo modification >> sm1/foo6 &&
314+
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
315+
diff actual - <<-EOF
316+
Submodule sm1 contains modified content
317+
Submodule sm1 $head6..$head8:
318+
> change
319+
EOF
320+
"
321+
322+
test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' "
323+
echo modification >> sm1/foo6 &&
324+
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
325+
diff actual - <<-EOF
326+
Submodule sm1 $head6..$head8:
327+
> change
328+
EOF
329+
"
330+
331+
test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' "
332+
echo modification >> sm1/foo6 &&
333+
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
334+
echo -n '' | diff actual -
335+
"
336+
256337
test_expect_success 'modified submodule contains modifed content' "
257338
rm -f sm1/new-file &&
258339
git diff-index -p --submodule=log HEAD >actual &&

0 commit comments

Comments
 (0)