Skip to content
Permalink
Browse files

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 <johannes.schindelin@gmx.de>
  • Loading branch information...
gitster authored and dscho committed Oct 30, 2017
2 parents 46cdf7f + 1961a68 commit ed3d106bc93775b62b3860176d7501e079a089b9
Showing with 360 additions and 18 deletions.
  1. +20 −1 Documentation/git-status.txt
  2. +23 −4 Documentation/technical/api-directory-listing.txt
  3. +25 −6 builtin/commit.c
  4. +42 −2 dir.c
  5. +2 −1 dir.h
  6. +233 −0 t/t7521-ignored-mode.sh
  7. +8 −3 wt-status.c
  8. +7 −1 wt-status.h
@@ -97,8 +97,27 @@ configuration variable documented in linkgit:git-config[1].
(and suppresses the output of submodule summaries when the config option
`status.submoduleSummary` is set).

--ignored::
--ignored[=<mode>]::
Show ignored files as well.
+
The mode parameter is used to specify the handling of ignored files.
It is optional: it defaults to 'traditional'.
+
The possible options are:
+
- 'traditional' - Shows ignored files and directories, unless
--untracked-files=all is specifed, in which case
individual files in ignored directories are
displayed.
- 'no' - Show no ignored files.
- 'matching' - Shows ignored files and directories matching an
ignore pattern.
+
When 'matching' mode is specified, paths that explicity match an
ignored pattern are shown. If a directory matches an ignore pattern,
then it is shown, but not paths contained in the ignored directory. If
a directory does not match an ignore pattern, but all contents are
ignored, then the directory is not shown, but all contents are shown.

-z::
Terminate entries with NUL, instead of LF. This implies
@@ -22,23 +22,42 @@ The notable options are:

`flags`::

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

`DIR_SHOW_IGNORED`:::

Return just ignored files in `entries[]`, not untracked files.
Return just ignored files in `entries[]`, not untracked
files. This flag is mutually exclusive with
`DIR_SHOW_IGNORED_TOO`.

`DIR_SHOW_IGNORED_TOO`:::

Similar to `DIR_SHOW_IGNORED`, but return ignored files in `ignored[]`
in addition to untracked files in `entries[]`.
Similar to `DIR_SHOW_IGNORED`, but return ignored files in
`ignored[]` in addition to untracked files in
`entries[]`. This flag is mutually exclusive with
`DIR_SHOW_IGNORED`.

`DIR_KEEP_UNTRACKED_CONTENTS`:::

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

`DIR_SHOW_IGNORED_TOO_MODE_MATCHING`:::

Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if
this is set, returns ignored files and directories that match
an exclude pattern. If a directory matches an exclude pattern,
then the directory is returned and the contained paths are
not. A directory that does not match an exclude pattern will
not be returned even if all of its contents are ignored. In
this case, the contents are returned as individual entries.
+
If this is set, files and directories that explicity match an ignore
pattern are reported. Implicity ignored directories (directories that
do not match an ignore pattern, but whose contents are all ignored)
are not reported, instead all of the contents are reported.

`DIR_COLLECT_IGNORED`:::

Special mode for git-add. Return ignored files in `ignored[]` and
@@ -118,7 +118,7 @@ static int edit_flag = -1; /* unspecified */
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
static int config_commit_verbose = -1; /* unspecified */
static int no_post_rewrite, allow_empty_message;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
static char *sign_commit;

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

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

static void handle_ignored_arg(struct wt_status *s)
{
if (!ignored_arg)
; /* default already initialized */
else if (!strcmp(ignored_arg, "traditional"))
s->show_ignored_mode = SHOW_TRADITIONAL_IGNORED;
else if (!strcmp(ignored_arg, "no"))
s->show_ignored_mode = SHOW_NO_IGNORED;
else if (!strcmp(ignored_arg, "matching"))
s->show_ignored_mode = SHOW_MATCHING_IGNORED;
else
die(_("Invalid ignored mode '%s'"), ignored_arg);
}

static void handle_untracked_files_arg(struct wt_status *s)
{
@@ -1364,8 +1377,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
N_("mode"),
N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
OPT_BOOL(0, "ignored", &show_ignored_in_status,
N_("show ignored files")),
{ OPTION_STRING, 0, "ignored", &ignored_arg,
N_("mode"),
N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"),
PARSE_OPT_OPTARG, NULL, (intptr_t)"traditional" },
{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
@@ -1397,8 +1412,12 @@ int cmd_status(int argc, const char **argv, const char *prefix)
no_lock_index = 1;

handle_untracked_files_arg(&s);
if (show_ignored_in_status)
s.show_ignored_files = 1;
handle_ignored_arg(&s);

if (s.show_ignored_mode == SHOW_MATCHING_IGNORED &&
s.show_untracked_files == SHOW_NO_UNTRACKED_FILES)
die(_("Unsupported combination of ignored and untracked-files arguments"));

parse_pathspec(&s.pathspec, 0,
PATHSPEC_PREFER_FULL,
prefix, argv);
44 dir.c
@@ -1389,6 +1389,30 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
case index_nonexistent:
if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
break;
if (exclude &&
(dir->flags & DIR_SHOW_IGNORED_TOO) &&
(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING)) {

/*
* This is an excluded directory and we are
* showing ignored paths that match an exclude
* pattern. (e.g. show directory as ignored
* only if it matches an exclude pattern).
* This path will either be 'path_excluded`
* (if we are showing empty directories or if
* the directory is not empty), or will be
* 'path_none' (empty directory, and we are
* not showing empty directories).
*/
if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
return path_excluded;

if (read_directory_recursive(dir, istate, dirname, len,
untracked, 1, 1, pathspec) == path_excluded)
return path_excluded;

return path_none;
}
if (!(dir->flags & DIR_NO_GITLINKS)) {
unsigned char sha1[20];
if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
@@ -1561,6 +1585,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
{
int exclude;
int has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case);
enum path_treatment path_treatment;

if (dtype == DT_UNKNOWN)
dtype = get_dtype(de, istate, path->buf, path->len);
@@ -1607,8 +1632,23 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
return path_none;
case DT_DIR:
strbuf_addch(path, '/');
return treat_directory(dir, istate, untracked, path->buf, path->len,
baselen, exclude, pathspec);
path_treatment = treat_directory(dir, istate, untracked,
path->buf, path->len,
baselen, exclude, pathspec);
/*
* If 1) we only want to return directories that
* match an exclude pattern and 2) this directory does
* not match an exclude pattern but all of its
* contents are excluded, then indicate that we should
* recurse into this directory (instead of marking the
* directory itself as an ignored path).
*/
if (!exclude &&
path_treatment == path_excluded &&
(dir->flags & DIR_SHOW_IGNORED_TOO) &&
(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING))
return path_recurse;
return path_treatment;
case DT_REG:
case DT_LNK:
return exclude ? path_excluded : path_untracked;
3 dir.h
@@ -152,7 +152,8 @@ struct dir_struct {
DIR_COLLECT_IGNORED = 1<<4,
DIR_SHOW_IGNORED_TOO = 1<<5,
DIR_COLLECT_KILLED_ONLY = 1<<6,
DIR_KEEP_UNTRACKED_CONTENTS = 1<<7
DIR_KEEP_UNTRACKED_CONTENTS = 1<<7,
DIR_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8
} flags;
struct dir_entry **entries;
struct dir_entry **ignored;

0 comments on commit ed3d106

Please sign in to comment.
You can’t perform that action at this time.