@matheusbsbs / matheus-bagliano / commits / 46a958b3da
Fork 0

Add the option "--ignore-submodules" to "git status"

In some use cases it is not desirable that "git status" 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 (this was the behavior before 1.7.0). 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 when using the "dirty" parameter. And if you want to ignore any changes to submodules, you can now do that by using this option without parameters or with "all" (when the config option status.submodulesummary is set, using "all" will also suppress the output of the submodule summary). A new function handle_ignore_submodules_arg() is introduced to parse this option new to "git status" in a single location, as "git diff" already knew it. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jens Lehmann committed Jun 25, 2010 at 16:56 UTC 46a958b3daa1da336683ec82d7f321d0f51b39c8
8 files changed +174 -13
Documentation/git-status.txt
+11
@@ -49,6 +49,17 @@ See linkgit:git-config[1] for configuration variable
49 used to change the default for when the option is not
50 specified.
51
52 +--ignore-submodules[=<when>]::
53 + Ignore changes to submodules when looking for changes. <when> can be
54 + either "untracked", "dirty" or "all", which is the default. When
55 + "untracked" is used submodules are not considered dirty when they only
56 + contain untracked content (but they are still scanned for modified
57 + content). Using "dirty" ignores all changes to the work tree of submodules,
58 + only changes to the commits stored in the superproject are shown (this was
59 + the behavior before 1.7.0). Using "all" hides all changes to submodules
60 + (and suppresses the output of submodule summaries when the config option
61 + `status.submodulesummary` is set).
62 +
63 -z::
64 Terminate entries with NUL, instead of LF. This implies
65 the `--porcelain` output format if no other format is given.
builtin/commit.c
+6 -1
@@ -67,7 +67,7 @@ static char *author_name, *author_email, *author_date;
67 static int all, edit_flag, also, interactive, only, amend, signoff;
68 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
69 static int no_post_rewrite;
70 -static char *untracked_files_arg, *force_date;
70 +static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
71 /*
72 * The default commit message cleanup mode will remove the lines
73 * beginning with # (shell comments) and leading and trailing
@@ -1031,6 +1031,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1031 "mode",
1032 "show untracked files, optional modes: all, normal, no. (Default: all)",
1033 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1034 + { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
1035 + "ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
1036 + PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1037 OPT_END(),
1038 };
1039
@@ -1052,6 +1055,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1055 refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
1056 s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
1057 s.in_merge = in_merge;
1058 + s.ignore_submodule_arg = ignore_submodule_arg;
1059 wt_status_collect(&s);
1060
1061 if (s.relative_paths)
@@ -1070,6 +1074,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1074 break;
1075 case STATUS_FORMAT_LONG:
1076 s.verbose = verbose;
1077 + s.ignore_submodule_arg = ignore_submodule_arg;
1078 wt_status_print(&s);
1079 break;
1080 }
diff.c
+4 -11
@@ -2866,17 +2866,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
2866 else if (!strcmp(arg, "--no-textconv"))
2867 DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
2868 else if (!strcmp(arg, "--ignore-submodules"))
2869 - DIFF_OPT_SET(options, IGNORE_SUBMODULES);
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"))
2869 + handle_ignore_submodules_arg(options, "all");
2870 + else if (!prefixcmp(arg, "--ignore-submodules="))
2871 + handle_ignore_submodules_arg(options, arg + 20);
2872 + else if (!strcmp(arg, "--submodule"))
2873 DIFF_OPT_SET(options, SUBMODULE_LOG);
2874 else if (!prefixcmp(arg, "--submodule=")) {
2875 if (!strcmp(arg + 12, "log"))
submodule.c
+13
@@ -46,6 +46,19 @@ done:
46 return ret;
47 }
48
49 +void handle_ignore_submodules_arg(struct diff_options *diffopt,
50 + const char *arg)
51 +{
52 + if (!strcmp(arg, "all"))
53 + DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
54 + else if (!strcmp(arg, "untracked"))
55 + DIFF_OPT_SET(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
56 + else if (!strcmp(arg, "dirty"))
57 + DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES);
58 + else
59 + die("bad --ignore-submodules argument: %s", arg);
60 +}
61 +
62 void show_submodule_summary(FILE *f, const char *path,
63 unsigned char one[20], unsigned char two[20],
64 unsigned dirty_submodule,
submodule.h
+3
@@ -1,6 +1,9 @@
1 #ifndef SUBMODULE_H
2 #define SUBMODULE_H
3
4 +struct diff_options;
5 +
6 +void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
7 void show_submodule_summary(FILE *f, const char *path,
8 unsigned char one[20], unsigned char two[20],
9 unsigned dirty_submodule,
t/t7508-status.sh
+127
@@ -693,4 +693,131 @@ test_expect_success 'commit --dry-run submodule summary (--amend)' '
693 test_cmp expect output
694 '
695
696 +cat > expect << EOF
697 +# On branch master
698 +# Changed but not updated:
699 +# (use "git add <file>..." to update what will be committed)
700 +# (use "git checkout -- <file>..." to discard changes in working directory)
701 +#
702 +# modified: dir1/modified
703 +#
704 +# Untracked files:
705 +# (use "git add <file>..." to include in what will be committed)
706 +#
707 +# dir1/untracked
708 +# dir2/modified
709 +# dir2/untracked
710 +# expect
711 +# output
712 +# untracked
713 +no changes added to commit (use "git add" and/or "git commit -a")
714 +EOF
715 +
716 +test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' '
717 + echo modified > sm/untracked &&
718 + git status --ignore-submodules=untracked > output &&
719 + test_cmp expect output
720 +'
721 +
722 +test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '
723 + git status --ignore-submodules=dirty > output &&
724 + test_cmp expect output
725 +'
726 +
727 +test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '
728 + echo modified > sm/foo &&
729 + git status --ignore-submodules=dirty > output &&
730 + test_cmp expect output
731 +'
732 +
733 +cat > expect << EOF
734 +# On branch master
735 +# Changed but not updated:
736 +# (use "git add <file>..." to update what will be committed)
737 +# (use "git checkout -- <file>..." to discard changes in working directory)
738 +# (commit or discard the untracked or modified content in submodules)
739 +#
740 +# modified: dir1/modified
741 +# modified: sm (modified content)
742 +#
743 +# Untracked files:
744 +# (use "git add <file>..." to include in what will be committed)
745 +#
746 +# dir1/untracked
747 +# dir2/modified
748 +# dir2/untracked
749 +# expect
750 +# output
751 +# untracked
752 +no changes added to commit (use "git add" and/or "git commit -a")
753 +EOF
754 +
755 +test_expect_success "--ignore-submodules=untracked doesn't suppress submodules with modified content" '
756 + git status --ignore-submodules=untracked > output &&
757 + test_cmp expect output
758 +'
759 +
760 +head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD)
761 +
762 +cat > expect << EOF
763 +# On branch master
764 +# Changed but not updated:
765 +# (use "git add <file>..." to update what will be committed)
766 +# (use "git checkout -- <file>..." to discard changes in working directory)
767 +#
768 +# modified: dir1/modified
769 +# modified: sm (new commits)
770 +#
771 +# Submodules changed but not updated:
772 +#
773 +# * sm $head...$head2 (1):
774 +# > 2nd commit
775 +#
776 +# Untracked files:
777 +# (use "git add <file>..." to include in what will be committed)
778 +#
779 +# dir1/untracked
780 +# dir2/modified
781 +# dir2/untracked
782 +# expect
783 +# output
784 +# untracked
785 +no changes added to commit (use "git add" and/or "git commit -a")
786 +EOF
787 +
788 +test_expect_success "--ignore-submodules=untracked doesn't suppress submodule summary" '
789 + git status --ignore-submodules=untracked > output &&
790 + test_cmp expect output
791 +'
792 +
793 +test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" '
794 + git status --ignore-submodules=dirty > output &&
795 + test_cmp expect output
796 +'
797 +
798 +cat > expect << EOF
799 +# On branch master
800 +# Changed but not updated:
801 +# (use "git add <file>..." to update what will be committed)
802 +# (use "git checkout -- <file>..." to discard changes in working directory)
803 +#
804 +# modified: dir1/modified
805 +#
806 +# Untracked files:
807 +# (use "git add <file>..." to include in what will be committed)
808 +#
809 +# dir1/untracked
810 +# dir2/modified
811 +# dir2/untracked
812 +# expect
813 +# output
814 +# untracked
815 +no changes added to commit (use "git add" and/or "git commit -a")
816 +EOF
817 +
818 +test_expect_success "--ignore-submodules=all suppresses submodule summary" '
819 + git status --ignore-submodules=all > output &&
820 + test_cmp expect output
821 +'
822 +
823 test_done
wt-status.c
+9 -1
@@ -9,6 +9,7 @@
9 #include "quote.h"
10 #include "run-command.h"
11 #include "remote.h"
12 +#include "submodule.h"
13
14 static char default_wt_status_colors[][COLOR_MAXLEN] = {
15 GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
@@ -306,6 +307,8 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
307 DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES);
308 if (!s->show_untracked_files)
309 DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
310 + if (s->ignore_submodule_arg)
311 + handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
312 rev.diffopt.format_callback = wt_status_collect_changed_cb;
313 rev.diffopt.format_callback_data = s;
314 rev.prune_data = s->pathspec;
@@ -322,6 +325,9 @@ static void wt_status_collect_changes_index(struct wt_status *s)
325 opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
326 setup_revisions(0, NULL, &rev, &opt);
327
328 + if (s->ignore_submodule_arg)
329 + handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
330 +
331 rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
332 rev.diffopt.format_callback = wt_status_collect_updated_cb;
333 rev.diffopt.format_callback_data = s;
@@ -618,7 +624,9 @@ void wt_status_print(struct wt_status *s)
624 wt_status_print_updated(s);
625 wt_status_print_unmerged(s);
626 wt_status_print_changed(s);
621 - if (s->submodule_summary) {
627 + if (s->submodule_summary &&
628 + (!s->ignore_submodule_arg ||
629 + strcmp(s->ignore_submodule_arg, "all"))) {
630 wt_status_print_submodule_summary(s, 0); /* staged */
631 wt_status_print_submodule_summary(s, 1); /* unstaged */
632 }
wt-status.h
+1
@@ -42,6 +42,7 @@ struct wt_status {
42 int relative_paths;
43 int submodule_summary;
44 enum untracked_status_type show_untracked_files;
45 + const char *ignore_submodule_arg;
46 char color_palette[WT_STATUS_UNMERGED+1][COLOR_MAXLEN];
47
48 /* These are computed during processing of the individual sections */