]> git.ipfire.org Git - thirdparty/git.git/blobdiff - dir.c
add, rm, mv: fix bug that prevents the update of non-sparse dirs
[thirdparty/git.git] / dir.c
diff --git a/dir.c b/dir.c
index 174d336c30e0397423623c770f56a74066c5cce3..7bbf22a3e7da4d81074be49dd3d822e7a1009a77 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1504,8 +1504,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 +1517,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,