]> git.ipfire.org Git - thirdparty/git.git/commitdiff
path: refactor `repo_submodule_path()` family of functions
authorPatrick Steinhardt <ps@pks.im>
Fri, 7 Feb 2025 11:03:30 +0000 (12:03 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 7 Feb 2025 17:59:22 +0000 (09:59 -0800)
As explained in an earlier commit, we're refactoring path-related
functions to provide a consistent interface for computing paths into the
commondir, gitdir and worktree. Refactor the "submodule" family of
functions accordingly.

Note that in contrast to the other `repo_*_path()` families, we have to
pass in the repository as a non-constant pointer. This is because we end
up calling `repo_read_gitmodules()` deep down in the callstack, which
may end up modifying the repository.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/submodule--helper.c
path.c
path.h
t/helper/test-ref-store.c
worktree.c

index 3a64f7e605e64e9704feebc3c4c46c60cdcbb7c1..c1a8029714bfe9415445edde4831f693211f4ff9 100644 (file)
@@ -1826,7 +1826,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,
 
        connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
 
-       p = git_pathdup_submodule(clone_data_path, "config");
+       p = repo_submodule_path(the_repository, clone_data_path, "config");
        if (!p)
                die(_("could not get submodule directory for '%s'"), clone_data_path);
 
diff --git a/path.c b/path.c
index a7fa42162e61e11407c143cfae23199e22121630..0d81e9fc328df4672abfb0874a6872feed2b46fa 100644 (file)
--- a/path.c
+++ b/path.c
@@ -560,14 +560,15 @@ const char *repo_worktree_path_replace(const struct repository *repo,
 }
 
 /* Returns 0 on success, negative on failure. */
-static int do_submodule_path(struct strbuf *buf, const char *path,
+static int do_submodule_path(struct repository *repo,
+                            struct strbuf *buf, const char *path,
                             const char *fmt, va_list args)
 {
        struct strbuf git_submodule_common_dir = STRBUF_INIT;
        struct strbuf git_submodule_dir = STRBUF_INIT;
        int ret;
 
-       ret = submodule_to_gitdir(the_repository, &git_submodule_dir, path);
+       ret = submodule_to_gitdir(repo, &git_submodule_dir, path);
        if (ret)
                goto cleanup;
 
@@ -586,13 +587,14 @@ cleanup:
        return ret;
 }
 
-char *git_pathdup_submodule(const char *path, const char *fmt, ...)
+char *repo_submodule_path(struct repository *repo,
+                         const char *path, const char *fmt, ...)
 {
        int err;
        va_list args;
        struct strbuf buf = STRBUF_INIT;
        va_start(args, fmt);
-       err = do_submodule_path(&buf, path, fmt, args);
+       err = do_submodule_path(repo, &buf, path, fmt, args);
        va_end(args);
        if (err) {
                strbuf_release(&buf);
@@ -601,16 +603,35 @@ char *git_pathdup_submodule(const char *path, const char *fmt, ...)
        return strbuf_detach(&buf, NULL);
 }
 
-int strbuf_git_path_submodule(struct strbuf *buf, const char *path,
-                             const char *fmt, ...)
+const char *repo_submodule_path_append(struct repository *repo,
+                                      struct strbuf *buf,
+                                      const char *path,
+                                      const char *fmt, ...)
 {
        int err;
        va_list args;
        va_start(args, fmt);
-       err = do_submodule_path(buf, path, fmt, args);
+       err = do_submodule_path(repo, buf, path, fmt, args);
        va_end(args);
+       if (err)
+               return NULL;
+       return buf->buf;
+}
 
-       return err;
+const char *repo_submodule_path_replace(struct repository *repo,
+                                       struct strbuf *buf,
+                                       const char *path,
+                                       const char *fmt, ...)
+{
+       int err;
+       va_list args;
+       strbuf_reset(buf);
+       va_start(args, fmt);
+       err = do_submodule_path(repo, buf, path, fmt, args);
+       va_end(args);
+       if (err)
+               return NULL;
+       return buf->buf;
 }
 
 void repo_common_pathv(const struct repository *repo,
diff --git a/path.h b/path.h
index d3f85f06762c67683345f7785f18f3e181076f39..4fe523626c505905d46c3eff68fe8aae7bb3f68a 100644 (file)
--- a/path.h
+++ b/path.h
@@ -93,20 +93,26 @@ const char *repo_worktree_path_replace(const struct repository *repo,
        __attribute__((format (printf, 3, 4)));
 
 /*
- * Return a path into a submodule's git directory located at `path`.  `path`
- * must only reference a submodule of the main repository (the_repository).
- */
-char *git_pathdup_submodule(const char *path, const char *fmt, ...)
-       __attribute__((format (printf, 2, 3)));
-
-/*
- * Construct a path into a submodule's git directory located at `path` and
- * append it to the provided buffer `sb`.  `path` must only reference a
- * submodule of the main repository (the_repository).
+ * The `repo_submodule_path` family of functions will construct a path into a
+ * submodule's git directory located at `path`. `path` must be a submodule path
+ * as found in the index and must be part of the given repository.
+ *
+ * Returns a `NULL` pointer in case the submodule cannot be found.
  */
-int strbuf_git_path_submodule(struct strbuf *sb, const char *path,
-                                    const char *fmt, ...)
+char *repo_submodule_path(struct repository *repo,
+                         const char *path,
+                         const char *fmt, ...)
        __attribute__((format (printf, 3, 4)));
+const char *repo_submodule_path_append(struct repository *repo,
+                                      struct strbuf *sb,
+                                      const char *path,
+                                      const char *fmt, ...)
+       __attribute__((format (printf, 4, 5)));
+const char *repo_submodule_path_replace(struct repository *repo,
+                                       struct strbuf *sb,
+                                       const char *path,
+                                       const char *fmt, ...)
+       __attribute__((format (printf, 4, 5)));
 
 void report_linked_checkout_garbage(struct repository *r);
 
index 1cc05f043ac204fcea0d3304e93e8e2bde5b6b70..e00fce592b10ed54eea6b1cfda3d7be85d109e93 100644 (file)
@@ -75,11 +75,10 @@ static const char **get_store(const char **argv, struct ref_store **refs)
                *refs = get_main_ref_store(the_repository);
        } else if (skip_prefix(argv[0], "submodule:", &gitdir)) {
                struct strbuf sb = STRBUF_INIT;
-               int ret;
 
-               ret = strbuf_git_path_submodule(&sb, gitdir, "objects/");
-               if (ret)
-                       die("strbuf_git_path_submodule failed: %d", ret);
+               if (!repo_submodule_path_append(the_repository,
+                                               &sb, gitdir, "objects/"))
+                       die("computing submodule path failed");
                add_to_alternates_memory(sb.buf);
                strbuf_release(&sb);
 
index f8d6e7127f4ab8b6504a7c3a2c82d5b117740d51..8f4fc10c44b51359b985984239090736d86ed2ee 100644 (file)
@@ -487,7 +487,8 @@ int submodule_uses_worktrees(const char *path)
        int ret = 0;
        struct repository_format format = REPOSITORY_FORMAT_INIT;
 
-       submodule_gitdir = git_pathdup_submodule(path, "%s", "");
+       submodule_gitdir = repo_submodule_path(the_repository,
+                                              path, "%s", "");
        if (!submodule_gitdir)
                return 0;