]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'en/clean-cleanups'
authorJunio C Hamano <gitster@pobox.com>
Thu, 25 Jun 2020 19:27:45 +0000 (12:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 25 Jun 2020 19:27:45 +0000 (12:27 -0700)
Code clean-up of "git clean" resulted in a fix of recent
performance regression.

* en/clean-cleanups:
  clean: optimize and document cases where we recurse into subdirectories
  clean: consolidate handling of ignored parameters
  dir, clean: avoid disallowed behavior
  dir: fix a few confusing comments

1  2 
dir.c

diff --combined dir.c
index 9ecd349e27dae10d204b36c549540c5d370c62b2,a3ad9702d646649477a37ce94a1f3b6c22e27f21..1045cc9c6f58702aba6e9036a8bce91a431c108a
--- 1/dir.c
--- 2/dir.c
+++ b/dir.c
@@@ -193,6 -193,10 +193,10 @@@ int fill_directory(struct dir_struct *d
        const char *prefix;
        size_t prefix_len;
  
+       unsigned exclusive_flags = DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO;
+       if ((dir->flags & exclusive_flags) == exclusive_flags)
+               BUG("DIR_SHOW_IGNORED and DIR_SHOW_IGNORED_TOO are exclusive");
        /*
         * Calculate common prefix for the pathspec, and
         * use that to optimize the directory walk
@@@ -364,8 -368,7 +368,8 @@@ static int match_pathspec_item(const st
                return MATCHED_FNMATCH;
  
        /* Perform checks to see if "name" is a leading string of the pathspec */
 -      if (flags & DO_MATCH_LEADING_PATHSPEC) {
 +      if ( (flags & DO_MATCH_LEADING_PATHSPEC) &&
 +          !(flags & DO_MATCH_EXCLUDE)) {
                /* name is a literal prefix of the pathspec */
                int offset = name[namelen-1] == '/' ? 1 : 0;
                if ((namelen < matchlen) &&
  }
  
  /*
 + * do_match_pathspec() is meant to ONLY be called by
 + * match_pathspec_with_flags(); calling it directly risks pathspecs
 + * like ':!unwanted_path' being ignored.
 + *
   * Given a name and a list of pathspecs, returns the nature of the
   * closest (i.e. most specific) match of the name to any of the
   * pathspecs.
@@@ -491,12 -490,13 +495,12 @@@ static int do_match_pathspec(const stru
        return retval;
  }
  
 -int match_pathspec(const struct index_state *istate,
 -                 const struct pathspec *ps,
 -                 const char *name, int namelen,
 -                 int prefix, char *seen, int is_dir)
 +static int match_pathspec_with_flags(const struct index_state *istate,
 +                                   const struct pathspec *ps,
 +                                   const char *name, int namelen,
 +                                   int prefix, char *seen, unsigned flags)
  {
        int positive, negative;
 -      unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;
        positive = do_match_pathspec(istate, ps, name, namelen,
                                     prefix, seen, flags);
        if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)
        return negative ? 0 : positive;
  }
  
 +int match_pathspec(const struct index_state *istate,
 +                 const struct pathspec *ps,
 +                 const char *name, int namelen,
 +                 int prefix, char *seen, int is_dir)
 +{
 +      unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;
 +      return match_pathspec_with_flags(istate, ps, name, namelen,
 +                                       prefix, seen, flags);
 +}
 +
  /**
   * Check if a submodule is a superset of the pathspec
   */
@@@ -525,11 -515,11 +529,11 @@@ int submodule_path_match(const struct i
                         const char *submodule_name,
                         char *seen)
  {
 -      int matched = do_match_pathspec(istate, ps, submodule_name,
 -                                      strlen(submodule_name),
 -                                      0, seen,
 -                                      DO_MATCH_DIRECTORY |
 -                                      DO_MATCH_LEADING_PATHSPEC);
 +      int matched = match_pathspec_with_flags(istate, ps, submodule_name,
 +                                              strlen(submodule_name),
 +                                              0, seen,
 +                                              DO_MATCH_DIRECTORY |
 +                                              DO_MATCH_LEADING_PATHSPEC);
        return matched;
  }
  
@@@ -1771,11 -1761,9 +1775,11 @@@ static enum path_treatment treat_direct
         * for matching patterns.
         */
        if (pathspec && !excluded) {
 -              matches_how = do_match_pathspec(istate, pathspec, dirname, len,
 -                                              0 /* prefix */, NULL /* seen */,
 -                                              DO_MATCH_LEADING_PATHSPEC);
 +              matches_how = match_pathspec_with_flags(istate, pathspec,
 +                                                      dirname, len,
 +                                                      0 /* prefix */,
 +                                                      NULL /* seen */,
 +                                                      DO_MATCH_LEADING_PATHSPEC);
                if (!matches_how)
                        return path_none;
        }
         * to recurse into untracked/ignored directories if either of the
         * following bits is set:
         *   - DIR_SHOW_IGNORED_TOO (because then we need to determine if
-        *                           there are ignored directories below)
+        *                           there are ignored entries below)
         *   - DIR_HIDE_EMPTY_DIRECTORIES (because we have to determine if
         *                                 the directory is empty)
         */
                return path_excluded;
  
        /*
-        * If we have we don't want to know the all the paths under an
-        * untracked or ignored directory, we still need to go into the
-        * directory to determine if it is empty (because an empty directory
-        * should be path_none instead of path_excluded or path_untracked).
+        * Even if we don't want to know all the paths under an untracked or
+        * ignored directory, we may still need to go into the directory to
+        * determine if it is empty (because with DIR_HIDE_EMPTY_DIRECTORIES,
+        * an empty directory should be path_none instead of path_excluded or
+        * path_untracked).
         */
        check_only = ((dir->flags & DIR_HIDE_EMPTY_DIRECTORIES) &&
                      !(dir->flags & DIR_SHOW_IGNORED_TOO));
@@@ -2207,9 -2196,9 +2212,9 @@@ static enum path_treatment treat_path(s
                if (excluded)
                        return path_excluded;
                if (pathspec &&
 -                  !do_match_pathspec(istate, pathspec, path->buf, path->len,
 -                                     0 /* prefix */, NULL /* seen */,
 -                                     0 /* flags */))
 +                  !match_pathspec(istate, pathspec, path->buf, path->len,
 +                                  0 /* prefix */, NULL /* seen */,
 +                                  0 /* is_dir */))
                        return path_none;
                return path_untracked;
        }