Skip to content

Commit d0c7d2a

Browse files
committed
Merge branch 'jm/status-ignored-files-list'
This is an early version of the latest iteration of what used to be 08f088c (Merge branch 'show-ignored-directory', 2017-10-23), i.e. support for the then-experimental, now-dropped `--show-ignored-directory` option. The set of paths output from "git status --ignored" was tied closely with its "--untracked=<mode>" option, but now it can be controlled more flexibly. Most notably, a directory that is ignored because it is listed to be ignored in the ignore/exclude mechanism can be handled differently from a directory that ends up to be ignored only because all files in it are ignored. * jm/status-ignored-files-list: status: test ignored modes status: document options to show matching ignored files status: report matching ignored and normal untracked status: add option to show ignored files differently Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 9abc2c0 + a20a86d commit d0c7d2a

File tree

8 files changed

+360
-18
lines changed

8 files changed

+360
-18
lines changed

Documentation/git-status.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,27 @@ configuration variable documented in linkgit:git-config[1].
9797
(and suppresses the output of submodule summaries when the config option
9898
`status.submoduleSummary` is set).
9999

100-
--ignored::
100+
--ignored[=<mode>]::
101101
Show ignored files as well.
102+
+
103+
The mode parameter is used to specify the handling of ignored files.
104+
It is optional: it defaults to 'traditional'.
105+
+
106+
The possible options are:
107+
+
108+
- 'traditional' - Shows ignored files and directories, unless
109+
--untracked-files=all is specifed, in which case
110+
individual files in ignored directories are
111+
displayed.
112+
- 'no' - Show no ignored files.
113+
- 'matching' - Shows ignored files and directories matching an
114+
ignore pattern.
115+
+
116+
When 'matching' mode is specified, paths that explicity match an
117+
ignored pattern are shown. If a directory matches an ignore pattern,
118+
then it is shown, but not paths contained in the ignored directory. If
119+
a directory does not match an ignore pattern, but all contents are
120+
ignored, then the directory is not shown, but all contents are shown.
102121

103122
-z::
104123
Terminate entries with NUL, instead of LF. This implies

Documentation/technical/api-directory-listing.txt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,42 @@ The notable options are:
2222

2323
`flags`::
2424

25-
A bit-field of options (the `*IGNORED*` flags are mutually exclusive):
25+
A bit-field of options:
2626

2727
`DIR_SHOW_IGNORED`:::
2828

29-
Return just ignored files in `entries[]`, not untracked files.
29+
Return just ignored files in `entries[]`, not untracked
30+
files. This flag is mutually exclusive with
31+
`DIR_SHOW_IGNORED_TOO`.
3032

3133
`DIR_SHOW_IGNORED_TOO`:::
3234

33-
Similar to `DIR_SHOW_IGNORED`, but return ignored files in `ignored[]`
34-
in addition to untracked files in `entries[]`.
35+
Similar to `DIR_SHOW_IGNORED`, but return ignored files in
36+
`ignored[]` in addition to untracked files in
37+
`entries[]`. This flag is mutually exclusive with
38+
`DIR_SHOW_IGNORED`.
3539

3640
`DIR_KEEP_UNTRACKED_CONTENTS`:::
3741

3842
Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is set, the
3943
untracked contents of untracked directories are also returned in
4044
`entries[]`.
4145

46+
`DIR_SHOW_IGNORED_TOO_MODE_MATCHING`:::
47+
48+
Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if
49+
this is set, returns ignored files and directories that match
50+
an exclude pattern. If a directory matches an exclude pattern,
51+
then the directory is returned and the contained paths are
52+
not. A directory that does not match an exclude pattern will
53+
not be returned even if all of its contents are ignored. In
54+
this case, the contents are returned as individual entries.
55+
+
56+
If this is set, files and directories that explicity match an ignore
57+
pattern are reported. Implicity ignored directories (directories that
58+
do not match an ignore pattern, but whose contents are all ignored)
59+
are not reported, instead all of the contents are reported.
60+
4261
`DIR_COLLECT_IGNORED`:::
4362

4463
Special mode for git-add. Return ignored files in `ignored[]` and

builtin/commit.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static int edit_flag = -1; /* unspecified */
118118
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
119119
static int config_commit_verbose = -1; /* unspecified */
120120
static int no_post_rewrite, allow_empty_message;
121-
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
121+
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
122122
static char *sign_commit;
123123

124124
/*
@@ -139,7 +139,7 @@ static const char *cleanup_arg;
139139
static enum commit_whence whence;
140140
static int sequencer_in_use;
141141
static int use_editor = 1, include_status = 1;
142-
static int show_ignored_in_status, have_option_m;
142+
static int have_option_m;
143143
static struct strbuf message = STRBUF_INIT;
144144

145145
static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
@@ -1075,6 +1075,19 @@ static const char *find_author_by_nickname(const char *name)
10751075
die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name);
10761076
}
10771077

1078+
static void handle_ignored_arg(struct wt_status *s)
1079+
{
1080+
if (!ignored_arg)
1081+
; /* default already initialized */
1082+
else if (!strcmp(ignored_arg, "traditional"))
1083+
s->show_ignored_mode = SHOW_TRADITIONAL_IGNORED;
1084+
else if (!strcmp(ignored_arg, "no"))
1085+
s->show_ignored_mode = SHOW_NO_IGNORED;
1086+
else if (!strcmp(ignored_arg, "matching"))
1087+
s->show_ignored_mode = SHOW_MATCHING_IGNORED;
1088+
else
1089+
die(_("Invalid ignored mode '%s'"), ignored_arg);
1090+
}
10781091

10791092
static void handle_untracked_files_arg(struct wt_status *s)
10801093
{
@@ -1364,8 +1377,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
13641377
N_("mode"),
13651378
N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
13661379
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1367-
OPT_BOOL(0, "ignored", &show_ignored_in_status,
1368-
N_("show ignored files")),
1380+
{ OPTION_STRING, 0, "ignored", &ignored_arg,
1381+
N_("mode"),
1382+
N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
1383+
PARSE_OPT_OPTARG, NULL, (intptr_t)"traditional" },
13691384
{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
13701385
N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
13711386
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
@@ -1393,8 +1408,12 @@ int cmd_status(int argc, const char **argv, const char *prefix)
13931408
}
13941409

13951410
handle_untracked_files_arg(&s);
1396-
if (show_ignored_in_status)
1397-
s.show_ignored_files = 1;
1411+
handle_ignored_arg(&s);
1412+
1413+
if (s.show_ignored_mode == SHOW_MATCHING_IGNORED &&
1414+
s.show_untracked_files == SHOW_NO_UNTRACKED_FILES)
1415+
die(_("Unsupported combination of ignored and untracked-files arguments"));
1416+
13981417
parse_pathspec(&s.pathspec, 0,
13991418
PATHSPEC_PREFER_FULL,
14001419
prefix, argv);

dir.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,30 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
13891389
case index_nonexistent:
13901390
if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
13911391
break;
1392+
if (exclude &&
1393+
(dir->flags & DIR_SHOW_IGNORED_TOO) &&
1394+
(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING)) {
1395+
1396+
/*
1397+
* This is an excluded directory and we are
1398+
* showing ignored paths that match an exclude
1399+
* pattern. (e.g. show directory as ignored
1400+
* only if it matches an exclude pattern).
1401+
* This path will either be 'path_excluded`
1402+
* (if we are showing empty directories or if
1403+
* the directory is not empty), or will be
1404+
* 'path_none' (empty directory, and we are
1405+
* not showing empty directories).
1406+
*/
1407+
if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
1408+
return path_excluded;
1409+
1410+
if (read_directory_recursive(dir, istate, dirname, len,
1411+
untracked, 1, 1, pathspec) == path_excluded)
1412+
return path_excluded;
1413+
1414+
return path_none;
1415+
}
13921416
if (!(dir->flags & DIR_NO_GITLINKS)) {
13931417
unsigned char sha1[20];
13941418
if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
@@ -1561,6 +1585,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
15611585
{
15621586
int exclude;
15631587
int has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case);
1588+
enum path_treatment path_treatment;
15641589

15651590
if (dtype == DT_UNKNOWN)
15661591
dtype = get_dtype(de, istate, path->buf, path->len);
@@ -1607,8 +1632,23 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
16071632
return path_none;
16081633
case DT_DIR:
16091634
strbuf_addch(path, '/');
1610-
return treat_directory(dir, istate, untracked, path->buf, path->len,
1611-
baselen, exclude, pathspec);
1635+
path_treatment = treat_directory(dir, istate, untracked,
1636+
path->buf, path->len,
1637+
baselen, exclude, pathspec);
1638+
/*
1639+
* If 1) we only want to return directories that
1640+
* match an exclude pattern and 2) this directory does
1641+
* not match an exclude pattern but all of its
1642+
* contents are excluded, then indicate that we should
1643+
* recurse into this directory (instead of marking the
1644+
* directory itself as an ignored path).
1645+
*/
1646+
if (!exclude &&
1647+
path_treatment == path_excluded &&
1648+
(dir->flags & DIR_SHOW_IGNORED_TOO) &&
1649+
(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING))
1650+
return path_recurse;
1651+
return path_treatment;
16121652
case DT_REG:
16131653
case DT_LNK:
16141654
return exclude ? path_excluded : path_untracked;

dir.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ struct dir_struct {
152152
DIR_COLLECT_IGNORED = 1<<4,
153153
DIR_SHOW_IGNORED_TOO = 1<<5,
154154
DIR_COLLECT_KILLED_ONLY = 1<<6,
155-
DIR_KEEP_UNTRACKED_CONTENTS = 1<<7
155+
DIR_KEEP_UNTRACKED_CONTENTS = 1<<7,
156+
DIR_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8
156157
} flags;
157158
struct dir_entry **entries;
158159
struct dir_entry **ignored;

0 commit comments

Comments
 (0)