]> git.ipfire.org Git - thirdparty/git.git/commitdiff
sparse-checkout: create helper methods
authorDerrick Stolee <dstolee@microsoft.com>
Wed, 8 Sep 2021 01:42:30 +0000 (01:42 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 Sep 2021 05:41:10 +0000 (22:41 -0700)
As we integrate the sparse index into more builtins, we occasionally
need to check the sparse-checkout patterns to see if a path is within
the sparse-checkout cone. Create some helper methods that help
initialize the patterns and check for pattern matching to make this
easier.

The existing callers of commands like get_sparse_checkout_patterns() use
a custom 'struct pattern_list' that is not necessarily the one in the
'struct index_state', so there are not many previous uses that could
adopt these helpers. There are just two in builtin/add.c and
sparse-index.c that can use path_in_sparse_checkout().

We add a path_in_cone_mode_sparse_checkout() as well that will only
return false if the path is outside of the sparse-checkout definition
_and_ the sparse-checkout patterns are in cone mode.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/add.c
dir.c
dir.h
sparse-index.c

index 17528e8f922693e2ec99aa66f3d761a3b83fcf35..88a6c0c69fb43bc9235d7c79e75624344f5abed2 100644 (file)
@@ -190,8 +190,6 @@ static int refresh(int verbose, const struct pathspec *pathspec)
        struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
        int flags = REFRESH_IGNORE_SKIP_WORKTREE |
                    (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
-       struct pattern_list pl = { 0 };
-       int sparse_checkout_enabled = !get_sparse_checkout_patterns(&pl);
 
        seen = xcalloc(pathspec->nr, 1);
        refresh_index(&the_index, flags, pathspec, seen,
@@ -199,12 +197,9 @@ static int refresh(int verbose, const struct pathspec *pathspec)
        for (i = 0; i < pathspec->nr; i++) {
                if (!seen[i]) {
                        const char *path = pathspec->items[i].original;
-                       int dtype = DT_REG;
 
                        if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) ||
-                           (sparse_checkout_enabled &&
-                            !path_matches_pattern_list(path, strlen(path), NULL,
-                                                       &dtype, &pl, &the_index))) {
+                           !path_in_sparse_checkout(path, &the_index)) {
                                string_list_append(&only_match_skip_worktree,
                                                   pathspec->items[i].original);
                        } else {
diff --git a/dir.c b/dir.c
index 03c4d212672bc4b68bc45a514fe16180f57ee1f4..86afa2eae001ef654abe331eb7ae54d209a09d63 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1439,6 +1439,58 @@ done:
        return result;
 }
 
+int init_sparse_checkout_patterns(struct index_state *istate)
+{
+       if (!core_apply_sparse_checkout)
+               return 1;
+       if (istate->sparse_checkout_patterns)
+               return 0;
+
+       CALLOC_ARRAY(istate->sparse_checkout_patterns, 1);
+
+       if (get_sparse_checkout_patterns(istate->sparse_checkout_patterns) < 0) {
+               FREE_AND_NULL(istate->sparse_checkout_patterns);
+               return -1;
+       }
+
+       return 0;
+}
+
+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;
+
+       /*
+        * We default to accepting a path if there are no patterns or
+        * they are of the wrong type.
+        */
+       if (init_sparse_checkout_patterns(istate) ||
+           (require_cone_mode &&
+            !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;
+}
+
+int path_in_sparse_checkout(const char *path,
+                           struct index_state *istate)
+{
+       return path_in_sparse_checkout_1(path, istate, 0);
+}
+
+int path_in_cone_mode_sparse_checkout(const char *path,
+                                    struct index_state *istate)
+{
+       return path_in_sparse_checkout_1(path, istate, 1);
+}
+
 static struct path_pattern *last_matching_pattern_from_lists(
                struct dir_struct *dir, struct index_state *istate,
                const char *pathname, int pathlen,
diff --git a/dir.h b/dir.h
index b3e1a54a97145d6be7385d044968a080e2f17ae8..6823312521e8135d2b89bdae3f5c2e37a2212761 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -394,6 +394,14 @@ enum pattern_match_result path_matches_pattern_list(const char *pathname,
                                const char *basename, int *dtype,
                                struct pattern_list *pl,
                                struct index_state *istate);
+
+int init_sparse_checkout_patterns(struct index_state *state);
+
+int path_in_sparse_checkout(const char *path,
+                           struct index_state *istate);
+int path_in_cone_mode_sparse_checkout(const char *path,
+                                     struct index_state *istate);
+
 struct dir_entry *dir_add_ignored(struct dir_struct *dir,
                                  struct index_state *istate,
                                  const char *pathname, int len);
index 880c5f723385054c760b7ca5acbf44727c03894c..23f7c3bd3619887f4654bb57018e0df7bc2dc64f 100644 (file)
@@ -33,19 +33,14 @@ static int convert_to_sparse_rec(struct index_state *istate,
 {
        int i, can_convert = 1;
        int start_converted = num_converted;
-       enum pattern_match_result match;
-       int dtype = DT_UNKNOWN;
        struct strbuf child_path = STRBUF_INIT;
-       struct pattern_list *pl = istate->sparse_checkout_patterns;
 
        /*
         * Is the current path outside of the sparse cone?
         * Then check if the region can be replaced by a sparse
         * directory entry (everything is sparse and merged).
         */
-       match = path_matches_pattern_list(ct_path, ct_pathlen,
-                                         NULL, &dtype, pl, istate);
-       if (match != NOT_MATCHED)
+       if (path_in_sparse_checkout(ct_path, istate))
                can_convert = 0;
 
        for (i = start; can_convert && i < end; i++) {
@@ -152,11 +147,8 @@ int convert_to_sparse(struct index_state *istate)
        if (!istate->repo->settings.sparse_index)
                return 0;
 
-       if (!istate->sparse_checkout_patterns) {
-               istate->sparse_checkout_patterns = xcalloc(1, sizeof(struct pattern_list));
-               if (get_sparse_checkout_patterns(istate->sparse_checkout_patterns) < 0)
-                       return 0;
-       }
+       if (init_sparse_checkout_patterns(istate))
+               return 0;
 
        /*
         * We need cone-mode patterns to use sparse-index. If a user edits