summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/diff-options.txt10
-rw-r--r--diff-lib.c1
-rw-r--r--diff.c11
-rw-r--r--diff.h1
-rwxr-xr-xt/t4027-diff-submodule.sh20
-rwxr-xr-xt/t4041-diff-submodule-option.sh81
6 files changed, 118 insertions, 6 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index c9c6c2b1cb..2dd91e930b 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -288,8 +288,14 @@ endif::git-format-patch[]
--no-ext-diff::
Disallow external diff drivers.
---ignore-submodules::
- Ignore changes to submodules in the diff generation.
+--ignore-submodules[=<when>]::
+ Ignore changes to submodules in the diff generation. <when> can be
+ either "untracked", "dirty" or "all", which is the default. When
+ "untracked" is used submodules are not considered dirty when they only
+ contain untracked content (but they are still scanned for modified
+ content). Using "dirty" ignores all changes to the work tree of submodules,
+ only changes to the commits stored in the superproject are shown (this was
+ the behavior until 1.7.0). Using "all" hides all changes to submodules.
--src-prefix=<prefix>::
Show the given source prefix instead of "a/".
diff --git a/diff-lib.c b/diff-lib.c
index c9f6e05bad..8b8978ae6d 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -70,6 +70,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt,
int changed = ce_match_stat(ce, st, ce_option);
if (S_ISGITLINK(ce->ce_mode)
&& !DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES)
+ && !DIFF_OPT_TST(diffopt, IGNORE_DIRTY_SUBMODULES)
&& (!changed || DIFF_OPT_TST(diffopt, DIRTY_SUBMODULES))) {
*dirty_submodule = is_submodule_modified(ce->name, DIFF_OPT_TST(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES));
}
diff --git a/diff.c b/diff.c
index e40c1271da..804acf0b21 100644
--- a/diff.c
+++ b/diff.c
@@ -2867,7 +2867,16 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
else if (!strcmp(arg, "--ignore-submodules"))
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
- else if (!strcmp(arg, "--submodule"))
+ else if (!prefixcmp(arg, "--ignore-submodules=")) {
+ if (!strcmp(arg + 20, "all"))
+ DIFF_OPT_SET(options, IGNORE_SUBMODULES);
+ else if (!strcmp(arg + 20, "untracked"))
+ DIFF_OPT_SET(options, IGNORE_UNTRACKED_IN_SUBMODULES);
+ else if (!strcmp(arg + 20, "dirty"))
+ DIFF_OPT_SET(options, IGNORE_DIRTY_SUBMODULES);
+ else
+ die("bad --ignore-submodules argument: %s", arg + 20);
+ } else if (!strcmp(arg, "--submodule"))
DIFF_OPT_SET(options, SUBMODULE_LOG);
else if (!prefixcmp(arg, "--submodule=")) {
if (!strcmp(arg + 12, "log"))
diff --git a/diff.h b/diff.h
index 6a71013dc6..53db218b30 100644
--- a/diff.h
+++ b/diff.h
@@ -71,6 +71,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_SUBMODULE_LOG (1 << 23)
#define DIFF_OPT_DIRTY_SUBMODULES (1 << 24)
#define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25)
+#define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh
index 83c1914771..559b41eccd 100755
--- a/t/t4027-diff-submodule.sh
+++ b/t/t4027-diff-submodule.sh
@@ -103,9 +103,17 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'
git diff HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subprev $subprev-dirty &&
- test_cmp expect.body actual.body
+ test_cmp expect.body actual.body &&
+ git diff --ignore-submodules HEAD >actual2 &&
+ echo -n "" | test_cmp - actual2 &&
+ git diff --ignore-submodules=untracked HEAD >actual3 &&
+ sed -e "1,/^@@/d" actual3 >actual3.body &&
+ expect_from_to >expect.body $subprev $subprev-dirty &&
+ test_cmp expect.body actual3.body &&
+ git diff --ignore-submodules=dirty HEAD >actual4 &&
+ echo -n "" | test_cmp - actual4
'
-
+test_done
test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' '
(
cd sub &&
@@ -129,7 +137,13 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)'
git diff HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subprev $subprev-dirty &&
- test_cmp expect.body actual.body
+ test_cmp expect.body actual.body &&
+ git diff --ignore-submodules=all HEAD >actual2 &&
+ echo -n "" | test_cmp - actual2 &&
+ git diff --ignore-submodules=untracked HEAD >actual3 &&
+ echo -n "" | test_cmp - actual3 &&
+ git diff --ignore-submodules=dirty HEAD >actual4 &&
+ echo -n "" | test_cmp - actual4
'
test_expect_success 'git diff (empty submodule dir)' '
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index 019acb926d..f44b9064ea 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -205,6 +205,21 @@ Submodule sm1 contains untracked content
EOF
"
+test_expect_success 'submodule contains untracked content (untracked ignored)' "
+ git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
+test_expect_success 'submodule contains untracked content (dirty ignored)' "
+ git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
+test_expect_success 'submodule contains untracked content (all ignored)' "
+ git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
test_expect_success 'submodule contains untracked and modifed content' "
echo new > sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
@@ -214,6 +229,26 @@ Submodule sm1 contains modified content
EOF
"
+test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' "
+ echo new > sm1/foo6 &&
+ git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 contains modified content
+EOF
+"
+
+test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' "
+ echo new > sm1/foo6 &&
+ git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
+test_expect_success 'submodule contains untracked and modifed content (all ignored)' "
+ echo new > sm1/foo6 &&
+ git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
test_expect_success 'submodule contains modifed content' "
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
@@ -242,6 +277,27 @@ Submodule sm1 $head6..$head8:
EOF
"
+test_expect_success 'modified submodule contains untracked content (untracked ignored)' "
+ git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6..$head8:
+ > change
+EOF
+"
+
+test_expect_success 'modified submodule contains untracked content (dirty ignored)' "
+ git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6..$head8:
+ > change
+EOF
+"
+
+test_expect_success 'modified submodule contains untracked content (all ignored)' "
+ git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
test_expect_success 'modified submodule contains untracked and modifed content' "
echo modification >> sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
@@ -253,6 +309,31 @@ Submodule sm1 $head6..$head8:
EOF
"
+test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' "
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 contains modified content
+Submodule sm1 $head6..$head8:
+ > change
+EOF
+"
+
+test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' "
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6..$head8:
+ > change
+EOF
+"
+
+test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' "
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
+ echo -n '' | diff actual -
+"
+
test_expect_success 'modified submodule contains modifed content' "
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&