]> git.ipfire.org Git - thirdparty/git.git/blobdiff - dir.c
test-ref-store: remove force-create argument for create-reflog
[thirdparty/git.git] / dir.c
diff --git a/dir.c b/dir.c
index a4306ab8747e4faecb2219d68930f4be0714521b..5aa6fbad0b76ad3ad026a8775761f9c7ea1776e8 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1294,7 +1294,7 @@ int match_pathname(const char *pathname, int pathlen,
                 * then our prefix match is all we need; we
                 * do not need to call fnmatch at all.
                 */
-               if (!patternlen && (!namelen || (flags & PATTERN_FLAG_MUSTBEDIR)))
+               if (!patternlen && !namelen)
                        return 1;
        }
 
@@ -1303,44 +1303,6 @@ int match_pathname(const char *pathname, int pathlen,
                                 WM_PATHNAME) == 0;
 }
 
-static int path_matches_dir_pattern(const char *pathname,
-                                   int pathlen,
-                                   struct strbuf **path_parent,
-                                   int *dtype,
-                                   struct path_pattern *pattern,
-                                   struct index_state *istate)
-{
-       if (!*path_parent) {
-               char *slash;
-               CALLOC_ARRAY(*path_parent, 1);
-               strbuf_add(*path_parent, pathname, pathlen);
-               slash = find_last_dir_sep((*path_parent)->buf);
-
-               if (slash)
-                       strbuf_setlen(*path_parent, slash - (*path_parent)->buf);
-               else
-                       strbuf_setlen(*path_parent, 0);
-       }
-
-       /*
-        * If the parent directory matches the pattern, then we do not
-        * need to check for dtype.
-        */
-       if ((*path_parent)->len &&
-           match_pathname((*path_parent)->buf, (*path_parent)->len,
-                          pattern->base,
-                          pattern->baselen ? pattern->baselen - 1 : 0,
-                          pattern->pattern, pattern->nowildcardlen,
-                          pattern->patternlen, pattern->flags))
-               return 1;
-
-       *dtype = resolve_dtype(*dtype, istate, pathname, pathlen);
-       if (*dtype != DT_DIR)
-               return 0;
-
-       return 1;
-}
-
 /*
  * Scan the given exclude list in reverse to see whether pathname
  * should be ignored.  The first match (i.e. the last on the list), if
@@ -1356,7 +1318,6 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
 {
        struct path_pattern *res = NULL; /* undecided */
        int i;
-       struct strbuf *path_parent = NULL;
 
        if (!pl->nr)
                return NULL;    /* undefined */
@@ -1366,10 +1327,11 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
                const char *exclude = pattern->pattern;
                int prefix = pattern->nowildcardlen;
 
-               if (pattern->flags & PATTERN_FLAG_MUSTBEDIR &&
-                   !path_matches_dir_pattern(pathname, pathlen, &path_parent,
-                                             dtype, pattern, istate))
-                       continue;
+               if (pattern->flags & PATTERN_FLAG_MUSTBEDIR) {
+                       *dtype = resolve_dtype(*dtype, istate, pathname, pathlen);
+                       if (*dtype != DT_DIR)
+                               continue;
+               }
 
                if (pattern->flags & PATTERN_FLAG_NODIR) {
                        if (match_basename(basename,
@@ -1393,12 +1355,6 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
                        break;
                }
        }
-
-       if (path_parent) {
-               strbuf_release(path_parent);
-               free(path_parent);
-       }
-
        return res;
 }
 
@@ -1504,8 +1460,9 @@ static int path_in_sparse_checkout_1(const char *path,
                                     struct index_state *istate,
                                     int require_cone_mode)
 {
-       const char *base;
        int dtype = DT_REG;
+       enum pattern_match_result match = UNDECIDED;
+       const char *end, *slash;
 
        /*
         * We default to accepting a path if there are no patterns or
@@ -1516,11 +1473,27 @@ static int path_in_sparse_checkout_1(const char *path,
             !istate->sparse_checkout_patterns->use_cone_patterns))
                return 1;
 
-       base = strrchr(path, '/');
-       return path_matches_pattern_list(path, strlen(path), base ? base + 1 : path,
-                                        &dtype,
-                                        istate->sparse_checkout_patterns,
-                                        istate) > 0;
+       /*
+        * If UNDECIDED, use the match from the parent dir (recursively), or
+        * fall back to NOT_MATCHED at the topmost level. Note that cone mode
+        * never returns UNDECIDED, so we will execute only one iteration in
+        * this case.
+        */
+       for (end = path + strlen(path);
+            end > path && match == UNDECIDED;
+            end = slash) {
+
+               for (slash = end - 1; slash > path && *slash != '/'; slash--)
+                       ; /* do nothing */
+
+               match = path_matches_pattern_list(path, end - path,
+                               slash > path ? slash + 1 : path, &dtype,
+                               istate->sparse_checkout_patterns, istate);
+
+               /* We are going to match the parent dir now */
+               dtype = DT_DIR;
+       }
+       return match > 0;
 }
 
 int path_in_sparse_checkout(const char *path,