Add optional parameters to the diff option "--ignore-submodules"
authorJens Lehmann <Jens.Lehmann@web.de>
Tue, 8 Jun 2010 16:31:51 +0000 (18:31 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 11 Jun 2010 20:33:17 +0000 (13:33 -0700)
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 <Jens.Lehmann@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/diff-options.txt
diff-lib.c
diff.c
diff.h
t/t4027-diff-submodule.sh
t/t4041-diff-submodule-option.sh
index c9c6c2b1cb61caa6db5e029d6bce1c76a6c075a7..2dd91e930bae16808108eb677246aa1163abbc82 100644 (file)
@@ -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/".
index c9f6e05badf7b752188dcb5fa28a9bef53521dee..8b8978ae6d1b4d947952b7fe9ec9cea013aaa8c3 100644 (file)
@@ -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 e40c1271da3f2ea433b55f770408e8d3a0f8a521..804acf0b21c5bc0f7b702c62e159a4296277538b 100644 (file)
--- 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 6a71013dc63fc0912fd4f3d27f70ae909917f1f6..53db218b300842beb06626b19eef70c880082f29 100644 (file)
--- 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)
index 83c19147717f2a5e6c634918c74b93e54376d725..559b41eccde63e8bae10806a22df63a82bf127ce 100755 (executable)
@@ -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)' '
index 019acb926d6765bf24e1dfe4bea2a9dba28ca797..f44b9064ea48b6a6f2ac93f791416e1763607a76 100755 (executable)
@@ -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 &&