Skip to content

Commit a76b208

Browse files
committed
Merge branch 'jl/status-ignore-submodules'
* 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
2 parents 978327f + 46a958b commit a76b208

File tree

9 files changed

+177
-16
lines changed

9 files changed

+177
-16
lines changed

Documentation/git-status.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ See linkgit:git-config[1] for configuration variable
5353
used to change the default for when the option is not
5454
specified.
5555

56+
--ignore-submodules[=<when>]::
57+
Ignore changes to submodules when looking for changes. <when> can be
58+
either "untracked", "dirty" or "all", which is the default. When
59+
"untracked" is used submodules are not considered dirty when they only
60+
contain untracked content (but they are still scanned for modified
61+
content). Using "dirty" ignores all changes to the work tree of submodules,
62+
only changes to the commits stored in the superproject are shown (this was
63+
the behavior before 1.7.0). Using "all" hides all changes to submodules
64+
(and suppresses the output of submodule summaries when the config option
65+
`status.submodulesummary` is set).
66+
5667
-z::
5768
Terminate entries with NUL, instead of LF. This implies
5869
the `--porcelain` output format if no other format is given.

builtin/commit.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static char *author_name, *author_email, *author_date;
7272
static int all, edit_flag, also, interactive, only, amend, signoff;
7373
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
7474
static int no_post_rewrite, allow_empty_message;
75-
static char *untracked_files_arg, *force_date;
75+
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
7676
/*
7777
* The default commit message cleanup mode will remove the lines
7878
* beginning with # (shell comments) and leading and trailing
@@ -1059,6 +1059,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
10591059
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
10601060
OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
10611061
"show ignored files"),
1062+
{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
1063+
"ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
1064+
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
10621065
OPT_END(),
10631066
};
10641067

@@ -1089,6 +1092,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
10891092

10901093
s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
10911094
s.in_merge = in_merge;
1095+
s.ignore_submodule_arg = ignore_submodule_arg;
10921096
wt_status_collect(&s);
10931097

10941098
if (s.relative_paths)
@@ -1107,6 +1111,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
11071111
break;
11081112
case STATUS_FORMAT_LONG:
11091113
s.verbose = verbose;
1114+
s.ignore_submodule_arg = ignore_submodule_arg;
11101115
wt_status_print(&s);
11111116
break;
11121117
}

diff.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3168,17 +3168,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
31683168
else if (!strcmp(arg, "--no-textconv"))
31693169
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
31703170
else if (!strcmp(arg, "--ignore-submodules"))
3171-
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
3172-
else if (!prefixcmp(arg, "--ignore-submodules=")) {
3173-
if (!strcmp(arg + 20, "all"))
3174-
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
3175-
else if (!strcmp(arg + 20, "untracked"))
3176-
DIFF_OPT_SET(options, IGNORE_UNTRACKED_IN_SUBMODULES);
3177-
else if (!strcmp(arg + 20, "dirty"))
3178-
DIFF_OPT_SET(options, IGNORE_DIRTY_SUBMODULES);
3179-
else
3180-
die("bad --ignore-submodules argument: %s", arg + 20);
3181-
} else if (!strcmp(arg, "--submodule"))
3171+
handle_ignore_submodules_arg(options, "all");
3172+
else if (!prefixcmp(arg, "--ignore-submodules="))
3173+
handle_ignore_submodules_arg(options, arg + 20);
3174+
else if (!strcmp(arg, "--submodule"))
31823175
DIFF_OPT_SET(options, SUBMODULE_LOG);
31833176
else if (!prefixcmp(arg, "--submodule=")) {
31843177
if (!strcmp(arg + 12, "log"))

git-submodule.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ cmd_summary() {
580580

581581
cd_to_toplevel
582582
# Get modified modules cared by user
583-
modules=$(git $diff_cmd $cached --raw $head -- "$@" |
583+
modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
584584
sane_egrep '^:([0-7]* )?160000' |
585585
while read mod_src mod_dst sha1_src sha1_dst status name
586586
do
@@ -594,7 +594,7 @@ cmd_summary() {
594594

595595
test -z "$modules" && return
596596

597-
git $diff_cmd $cached --raw $head -- $modules |
597+
git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
598598
sane_egrep '^:([0-7]* )?160000' |
599599
cut -c2- |
600600
while read mod_src mod_dst sha1_src sha1_dst status name
@@ -760,7 +760,7 @@ cmd_status()
760760
continue;
761761
fi
762762
set_name_rev "$path" "$sha1"
763-
if git diff-files --quiet -- "$path"
763+
if git diff-files --ignore-submodules=dirty --quiet -- "$path"
764764
then
765765
say " $sha1 $displaypath$revname"
766766
else

submodule.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ static int add_submodule_odb(const char *path)
4646
return ret;
4747
}
4848

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+
4962
void show_submodule_summary(FILE *f, const char *path,
5063
unsigned char one[20], unsigned char two[20],
5164
unsigned dirty_submodule,

submodule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef SUBMODULE_H
22
#define SUBMODULE_H
33

4+
struct diff_options;
5+
6+
void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
47
void show_submodule_summary(FILE *f, const char *path,
58
unsigned char one[20], unsigned char two[20],
69
unsigned dirty_submodule,

t/t7508-status.sh

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,4 +808,131 @@ test_expect_success POSIXPERM 'status succeeds in a read-only repository' '
808808
(exit $status)
809809
'
810810

811+
cat > expect << EOF
812+
# On branch master
813+
# Changed but not updated:
814+
# (use "git add <file>..." to update what will be committed)
815+
# (use "git checkout -- <file>..." to discard changes in working directory)
816+
#
817+
# modified: dir1/modified
818+
#
819+
# Untracked files:
820+
# (use "git add <file>..." to include in what will be committed)
821+
#
822+
# dir1/untracked
823+
# dir2/modified
824+
# dir2/untracked
825+
# expect
826+
# output
827+
# untracked
828+
no changes added to commit (use "git add" and/or "git commit -a")
829+
EOF
830+
831+
test_expect_success '--ignore-submodules=untracked suppresses submodules with untracked content' '
832+
echo modified > sm/untracked &&
833+
git status --ignore-submodules=untracked > output &&
834+
test_cmp expect output
835+
'
836+
837+
test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '
838+
git status --ignore-submodules=dirty > output &&
839+
test_cmp expect output
840+
'
841+
842+
test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '
843+
echo modified > sm/foo &&
844+
git status --ignore-submodules=dirty > output &&
845+
test_cmp expect output
846+
'
847+
848+
cat > expect << EOF
849+
# On branch master
850+
# Changed but not updated:
851+
# (use "git add <file>..." to update what will be committed)
852+
# (use "git checkout -- <file>..." to discard changes in working directory)
853+
# (commit or discard the untracked or modified content in submodules)
854+
#
855+
# modified: dir1/modified
856+
# modified: sm (modified content)
857+
#
858+
# Untracked files:
859+
# (use "git add <file>..." to include in what will be committed)
860+
#
861+
# dir1/untracked
862+
# dir2/modified
863+
# dir2/untracked
864+
# expect
865+
# output
866+
# untracked
867+
no changes added to commit (use "git add" and/or "git commit -a")
868+
EOF
869+
870+
test_expect_success "--ignore-submodules=untracked doesn't suppress submodules with modified content" '
871+
git status --ignore-submodules=untracked > output &&
872+
test_cmp expect output
873+
'
874+
875+
head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD)
876+
877+
cat > expect << EOF
878+
# On branch master
879+
# Changed but not updated:
880+
# (use "git add <file>..." to update what will be committed)
881+
# (use "git checkout -- <file>..." to discard changes in working directory)
882+
#
883+
# modified: dir1/modified
884+
# modified: sm (new commits)
885+
#
886+
# Submodules changed but not updated:
887+
#
888+
# * sm $head...$head2 (1):
889+
# > 2nd commit
890+
#
891+
# Untracked files:
892+
# (use "git add <file>..." to include in what will be committed)
893+
#
894+
# dir1/untracked
895+
# dir2/modified
896+
# dir2/untracked
897+
# expect
898+
# output
899+
# untracked
900+
no changes added to commit (use "git add" and/or "git commit -a")
901+
EOF
902+
903+
test_expect_success "--ignore-submodules=untracked doesn't suppress submodule summary" '
904+
git status --ignore-submodules=untracked > output &&
905+
test_cmp expect output
906+
'
907+
908+
test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" '
909+
git status --ignore-submodules=dirty > output &&
910+
test_cmp expect output
911+
'
912+
913+
cat > expect << EOF
914+
# On branch master
915+
# Changed but not updated:
916+
# (use "git add <file>..." to update what will be committed)
917+
# (use "git checkout -- <file>..." to discard changes in working directory)
918+
#
919+
# modified: dir1/modified
920+
#
921+
# Untracked files:
922+
# (use "git add <file>..." to include in what will be committed)
923+
#
924+
# dir1/untracked
925+
# dir2/modified
926+
# dir2/untracked
927+
# expect
928+
# output
929+
# untracked
930+
no changes added to commit (use "git add" and/or "git commit -a")
931+
EOF
932+
933+
test_expect_success "--ignore-submodules=all suppresses submodule summary" '
934+
git status --ignore-submodules=all > output &&
935+
test_cmp expect output
936+
'
937+
811938
test_done

wt-status.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "run-command.h"
1111
#include "remote.h"
1212
#include "refs.h"
13+
#include "submodule.h"
1314

1415
static char default_wt_status_colors[][COLOR_MAXLEN] = {
1516
GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
@@ -312,6 +313,8 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
312313
DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES);
313314
if (!s->show_untracked_files)
314315
DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
316+
if (s->ignore_submodule_arg)
317+
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
315318
rev.diffopt.format_callback = wt_status_collect_changed_cb;
316319
rev.diffopt.format_callback_data = s;
317320
rev.prune_data = s->pathspec;
@@ -328,6 +331,9 @@ static void wt_status_collect_changes_index(struct wt_status *s)
328331
opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
329332
setup_revisions(0, NULL, &rev, &opt);
330333

334+
if (s->ignore_submodule_arg)
335+
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
336+
331337
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
332338
rev.diffopt.format_callback = wt_status_collect_updated_cb;
333339
rev.diffopt.format_callback_data = s;
@@ -646,7 +652,9 @@ void wt_status_print(struct wt_status *s)
646652
wt_status_print_updated(s);
647653
wt_status_print_unmerged(s);
648654
wt_status_print_changed(s);
649-
if (s->submodule_summary) {
655+
if (s->submodule_summary &&
656+
(!s->ignore_submodule_arg ||
657+
strcmp(s->ignore_submodule_arg, "all"))) {
650658
wt_status_print_submodule_summary(s, 0); /* staged */
651659
wt_status_print_submodule_summary(s, 1); /* unstaged */
652660
}

wt-status.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct wt_status {
4545
int submodule_summary;
4646
int show_ignored_files;
4747
enum untracked_status_type show_untracked_files;
48+
const char *ignore_submodule_arg;
4849
char color_palette[WT_STATUS_REMOTE_BRANCH+1][COLOR_MAXLEN];
4950

5051
/* These are computed during processing of the individual sections */

0 commit comments

Comments
 (0)