Merge branch 'jl/status-ignore-submodules'
authorJunio C Hamano <gitster@pobox.com>
Wed, 30 Jun 2010 18:55:39 +0000 (11:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Jun 2010 18:55:39 +0000 (11:55 -0700)
* jl/status-ignore-submodules:
Add the option "--ignore-submodules" to "git status"
git submodule: ignore dirty submodules for summary and status

Conflicts:
builtin/commit.c
t/t7508-status.sh
wt-status.c
wt-status.h

Documentation/git-status.txt
builtin/commit.c
diff.c
git-submodule.sh
submodule.c
submodule.h
t/t7508-status.sh
wt-status.c
wt-status.h
index fd0fe7cb56cf3ba163cef467f5fc9c35b0ea963b..2fd054c1040ce43949382e4744a0d7a814a8d9bd 100644 (file)
@@ -53,6 +53,17 @@ See linkgit:git-config[1] for configuration variable
 used to change the default for when the option is not
 specified.
 
+--ignore-submodules[=<when>]::
+       Ignore changes to submodules when looking for changes. <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 before 1.7.0). Using "all" hides all changes to submodules
+       (and suppresses the output of submodule summaries when the config option
+       `status.submodulesummary` is set).
+
 -z::
        Terminate entries with NUL, instead of LF.  This implies
        the `--porcelain` output format if no other format is given.
index c6b053a508facc2029df489d069e0667cfeb28fe..c101f006f6b5d7d185aa97081fb9717de92b09cd 100644 (file)
@@ -72,7 +72,7 @@ static char *author_name, *author_email, *author_date;
 static int all, edit_flag, also, interactive, only, amend, signoff;
 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
 static int no_post_rewrite, allow_empty_message;
-static char *untracked_files_arg, *force_date;
+static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
 /*
  * The default commit message cleanup mode will remove the lines
  * beginning with # (shell comments) and leading and trailing
@@ -1059,6 +1059,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
                OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
                            "show ignored files"),
+               { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
+                 "ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
+                 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
                OPT_END(),
        };
 
@@ -1089,6 +1092,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 
        s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
        s.in_merge = in_merge;
+       s.ignore_submodule_arg = ignore_submodule_arg;
        wt_status_collect(&s);
 
        if (s.relative_paths)
@@ -1107,6 +1111,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                break;
        case STATUS_FORMAT_LONG:
                s.verbose = verbose;
+               s.ignore_submodule_arg = ignore_submodule_arg;
                wt_status_print(&s);
                break;
        }
diff --git a/diff.c b/diff.c
index 9d70f9d731325287dd7e9f83e5e3b44ad1dfb8d9..3aa695df62d2f13beed4b4ac54e3ea568194ae02 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3168,17 +3168,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        else if (!strcmp(arg, "--no-textconv"))
                DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
        else if (!strcmp(arg, "--ignore-submodules"))
-               DIFF_OPT_SET(options, IGNORE_SUBMODULES);
-       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"))
+               handle_ignore_submodules_arg(options, "all");
+       else if (!prefixcmp(arg, "--ignore-submodules="))
+               handle_ignore_submodules_arg(options, arg + 20);
+       else if (!strcmp(arg, "--submodule"))
                DIFF_OPT_SET(options, SUBMODULE_LOG);
        else if (!prefixcmp(arg, "--submodule=")) {
                if (!strcmp(arg + 12, "log"))
index 8c562a72e6e95fce60b78c015623212b7fce1dab..d9950c2b7fadef0876867e11ef26283ca1cfaf1e 100755 (executable)
@@ -580,7 +580,7 @@ cmd_summary() {
 
        cd_to_toplevel
        # Get modified modules cared by user
-       modules=$(git $diff_cmd $cached --raw $head -- "$@" |
+       modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
                sane_egrep '^:([0-7]* )?160000' |
                while read mod_src mod_dst sha1_src sha1_dst status name
                do
@@ -594,7 +594,7 @@ cmd_summary() {
 
        test -z "$modules" && return
 
-       git $diff_cmd $cached --raw $head -- $modules |
+       git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
        sane_egrep '^:([0-7]* )?160000' |
        cut -c2- |
        while read mod_src mod_dst sha1_src sha1_dst status name
@@ -760,7 +760,7 @@ cmd_status()
                        continue;
                fi
                set_name_rev "$path" "$sha1"
-               if git diff-files --quiet -- "$path"
+               if git diff-files --ignore-submodules=dirty --quiet -- "$path"
                then
                        say " $sha1 $displaypath$revname"
                else
index 676d48fb33119f393befcaf8998ad38741366525..61cb6e21ddfc789ce59597c96204e7904cd9359e 100644 (file)
@@ -46,6 +46,19 @@ static int add_submodule_odb(const char *path)
        return ret;
 }
 
+void handle_ignore_submodules_arg(struct diff_options *diffopt,
+                                 const char *arg)
+{
+       if (!strcmp(arg, "all"))
+               DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
+       else if (!strcmp(arg, "untracked"))
+               DIFF_OPT_SET(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
+       else if (!strcmp(arg, "dirty"))
+               DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES);
+       else
+               die("bad --ignore-submodules argument: %s", arg);
+}
+
 void show_submodule_summary(FILE *f, const char *path,
                unsigned char one[20], unsigned char two[20],
                unsigned dirty_submodule,
index dbda270873171c41f20c0f07b70773ce67c6a303..6fd3bb40702e5fb905eb4ae519d487e3c9f40073 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef SUBMODULE_H
 #define SUBMODULE_H
 
+struct diff_options;
+
+void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
 void show_submodule_summary(FILE *f, const char *path,
                unsigned char one[20], unsigned char two[20],
                unsigned dirty_submodule,
index 9e081073fbed00da362137446d78a7be7f86350b..a72fe3ae640378350102a07124aee201fb1c637b 100755 (executable)
@@ -808,4 +808,131 @@ test_expect_success POSIXPERM 'status succeeds in a read-only repository' '
        (exit $status)
 '
 
+cat > expect << EOF
+# On branch master
+# Changed but not updated:
+#   (use "git add <file>..." to update what will be committed)
+#   (use "git checkout -- <file>..." to discard changes in working directory)
+#
+#      modified:   dir1/modified
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#      dir1/untracked
+#      dir2/modified
+#      dir2/untracked
+#      expect
+#      output
+#      untracked
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
+
+test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' '
+       echo modified > sm/untracked &&
+       git status --ignore-submodules=untracked > output &&
+       test_cmp expect output
+'
+
+test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '
+       git status --ignore-submodules=dirty > output &&
+       test_cmp expect output
+'
+
+test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '
+       echo modified > sm/foo &&
+       git status --ignore-submodules=dirty > output &&
+       test_cmp expect output
+'
+
+cat > expect << EOF
+# On branch master
+# Changed but not updated:
+#   (use "git add <file>..." to update what will be committed)
+#   (use "git checkout -- <file>..." to discard changes in working directory)
+#   (commit or discard the untracked or modified content in submodules)
+#
+#      modified:   dir1/modified
+#      modified:   sm (modified content)
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#      dir1/untracked
+#      dir2/modified
+#      dir2/untracked
+#      expect
+#      output
+#      untracked
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
+
+test_expect_success "--ignore-submodules=untracked doesn't suppress submodules with modified content" '
+       git status --ignore-submodules=untracked > output &&
+       test_cmp expect output
+'
+
+head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD)
+
+cat > expect << EOF
+# On branch master
+# Changed but not updated:
+#   (use "git add <file>..." to update what will be committed)
+#   (use "git checkout -- <file>..." to discard changes in working directory)
+#
+#      modified:   dir1/modified
+#      modified:   sm (new commits)
+#
+# Submodules changed but not updated:
+#
+# * sm $head...$head2 (1):
+#   > 2nd commit
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#      dir1/untracked
+#      dir2/modified
+#      dir2/untracked
+#      expect
+#      output
+#      untracked
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
+
+test_expect_success "--ignore-submodules=untracked doesn't suppress submodule summary" '
+       git status --ignore-submodules=untracked > output &&
+       test_cmp expect output
+'
+
+test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" '
+       git status --ignore-submodules=dirty > output &&
+       test_cmp expect output
+'
+
+cat > expect << EOF
+# On branch master
+# Changed but not updated:
+#   (use "git add <file>..." to update what will be committed)
+#   (use "git checkout -- <file>..." to discard changes in working directory)
+#
+#      modified:   dir1/modified
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#      dir1/untracked
+#      dir2/modified
+#      dir2/untracked
+#      expect
+#      output
+#      untracked
+no changes added to commit (use "git add" and/or "git commit -a")
+EOF
+
+test_expect_success "--ignore-submodules=all suppresses submodule summary" '
+       git status --ignore-submodules=all > output &&
+       test_cmp expect output
+'
+
 test_done
index 38754ad735e9e6b090eb23990d82926cd2d82396..2f9e33c8fa172b129fd956abc4f74a5bf5543ba7 100644 (file)
@@ -10,6 +10,7 @@
 #include "run-command.h"
 #include "remote.h"
 #include "refs.h"
+#include "submodule.h"
 
 static char default_wt_status_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
@@ -312,6 +313,8 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
        DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES);
        if (!s->show_untracked_files)
                DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
+       if (s->ignore_submodule_arg)
+               handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
        rev.diffopt.format_callback = wt_status_collect_changed_cb;
        rev.diffopt.format_callback_data = s;
        rev.prune_data = s->pathspec;
@@ -328,6 +331,9 @@ static void wt_status_collect_changes_index(struct wt_status *s)
        opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
        setup_revisions(0, NULL, &rev, &opt);
 
+       if (s->ignore_submodule_arg)
+               handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
+
        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = wt_status_collect_updated_cb;
        rev.diffopt.format_callback_data = s;
@@ -646,7 +652,9 @@ void wt_status_print(struct wt_status *s)
        wt_status_print_updated(s);
        wt_status_print_unmerged(s);
        wt_status_print_changed(s);
-       if (s->submodule_summary) {
+       if (s->submodule_summary &&
+           (!s->ignore_submodule_arg ||
+            strcmp(s->ignore_submodule_arg, "all"))) {
                wt_status_print_submodule_summary(s, 0);  /* staged */
                wt_status_print_submodule_summary(s, 1);  /* unstaged */
        }
index 4cd74c4b32f51dbe575b0a04a894a520df79e9bf..9df9c9fad2512d7c1d7d6456cdd645d641b5a089 100644 (file)
@@ -45,6 +45,7 @@ struct wt_status {
        int submodule_summary;
        int show_ignored_files;
        enum untracked_status_type show_untracked_files;
+       const char *ignore_submodule_arg;
        char color_palette[WT_STATUS_REMOTE_BRANCH+1][COLOR_MAXLEN];
 
        /* These are computed during processing of the individual sections */