path: refactor `repo_submodule_path()` family of functions

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>

Patrick Steinhardt committed Feb 7, 2025 at 12:03 UTC f5c714e2a7d6239548b94c37ae906484e94b5bc7
5 files changed +53 -26
builtin/submodule--helper.c
+1 -1
@@ -1826,7 +1826,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,
1826
1827 connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
1828
1829 - p = git_pathdup_submodule(clone_data_path, "config");
1829 + p = repo_submodule_path(the_repository, clone_data_path, "config");
1830 if (!p)
1831 die(_("could not get submodule directory for '%s'"), clone_data_path);
1832
path.c
+29 -8
@@ -560,14 +560,15 @@ const char *repo_worktree_path_replace(const struct repository *repo,
560 }
561
562 /* Returns 0 on success, negative on failure. */
563 -static int do_submodule_path(struct strbuf *buf, const char *path,
563 +static int do_submodule_path(struct repository *repo,
564 + struct strbuf *buf, const char *path,
565 const char *fmt, va_list args)
566 {
567 struct strbuf git_submodule_common_dir = STRBUF_INIT;
568 struct strbuf git_submodule_dir = STRBUF_INIT;
569 int ret;
570
570 - ret = submodule_to_gitdir(the_repository, &git_submodule_dir, path);
571 + ret = submodule_to_gitdir(repo, &git_submodule_dir, path);
572 if (ret)
573 goto cleanup;
574
@@ -586,13 +587,14 @@ cleanup:
587 return ret;
588 }
589
589 -char *git_pathdup_submodule(const char *path, const char *fmt, ...)
590 +char *repo_submodule_path(struct repository *repo,
591 + const char *path, const char *fmt, ...)
592 {
593 int err;
594 va_list args;
595 struct strbuf buf = STRBUF_INIT;
596 va_start(args, fmt);
595 - err = do_submodule_path(&buf, path, fmt, args);
597 + err = do_submodule_path(repo, &buf, path, fmt, args);
598 va_end(args);
599 if (err) {
600 strbuf_release(&buf);
@@ -601,16 +603,35 @@ char *git_pathdup_submodule(const char *path, const char *fmt, ...)
603 return strbuf_detach(&buf, NULL);
604 }
605
604 -int strbuf_git_path_submodule(struct strbuf *buf, const char *path,
605 - const char *fmt, ...)
606 +const char *repo_submodule_path_append(struct repository *repo,
607 + struct strbuf *buf,
608 + const char *path,
609 + const char *fmt, ...)
610 {
611 int err;
612 va_list args;
613 va_start(args, fmt);
610 - err = do_submodule_path(buf, path, fmt, args);
614 + err = do_submodule_path(repo, buf, path, fmt, args);
615 va_end(args);
616 + if (err)
617 + return NULL;
618 + return buf->buf;
619 +}
620
613 - return err;
621 +const char *repo_submodule_path_replace(struct repository *repo,
622 + struct strbuf *buf,
623 + const char *path,
624 + const char *fmt, ...)
625 +{
626 + int err;
627 + va_list args;
628 + strbuf_reset(buf);
629 + va_start(args, fmt);
630 + err = do_submodule_path(repo, buf, path, fmt, args);
631 + va_end(args);
632 + if (err)
633 + return NULL;
634 + return buf->buf;
635 }
636
637 void repo_common_pathv(const struct repository *repo,
path.h
+18 -12
@@ -93,20 +93,26 @@ const char *repo_worktree_path_replace(const struct repository *repo,
93 __attribute__((format (printf, 3, 4)));
94
95 /*
96 - * Return a path into a submodule's git directory located at `path`. `path`
97 - * must only reference a submodule of the main repository (the_repository).
98 - */
99 -char *git_pathdup_submodule(const char *path, const char *fmt, ...)
100 - __attribute__((format (printf, 2, 3)));
101 -
102 -/*
103 - * Construct a path into a submodule's git directory located at `path` and
104 - * append it to the provided buffer `sb`. `path` must only reference a
105 - * submodule of the main repository (the_repository).
96 + * The `repo_submodule_path` family of functions will construct a path into a
97 + * submodule's git directory located at `path`. `path` must be a submodule path
98 + * as found in the index and must be part of the given repository.
99 + *
100 + * Returns a `NULL` pointer in case the submodule cannot be found.
101 */
107 -int strbuf_git_path_submodule(struct strbuf *sb, const char *path,
108 - const char *fmt, ...)
102 +char *repo_submodule_path(struct repository *repo,
103 + const char *path,
104 + const char *fmt, ...)
105 __attribute__((format (printf, 3, 4)));
106 +const char *repo_submodule_path_append(struct repository *repo,
107 + struct strbuf *sb,
108 + const char *path,
109 + const char *fmt, ...)
110 + __attribute__((format (printf, 4, 5)));
111 +const char *repo_submodule_path_replace(struct repository *repo,
112 + struct strbuf *sb,
113 + const char *path,
114 + const char *fmt, ...)
115 + __attribute__((format (printf, 4, 5)));
116
117 void report_linked_checkout_garbage(struct repository *r);
118
t/helper/test-ref-store.c
+3 -4
@@ -75,11 +75,10 @@ static const char **get_store(const char **argv, struct ref_store **refs)
75 *refs = get_main_ref_store(the_repository);
76 } else if (skip_prefix(argv[0], "submodule:", &gitdir)) {
77 struct strbuf sb = STRBUF_INIT;
78 - int ret;
78
80 - ret = strbuf_git_path_submodule(&sb, gitdir, "objects/");
81 - if (ret)
82 - die("strbuf_git_path_submodule failed: %d", ret);
79 + if (!repo_submodule_path_append(the_repository,
80 + &sb, gitdir, "objects/"))
81 + die("computing submodule path failed");
82 add_to_alternates_memory(sb.buf);
83 strbuf_release(&sb);
84
worktree.c
+2 -1
@@ -487,7 +487,8 @@ int submodule_uses_worktrees(const char *path)
487 int ret = 0;
488 struct repository_format format = REPOSITORY_FORMAT_INIT;
489
490 - submodule_gitdir = git_pathdup_submodule(path, "%s", "");
490 + submodule_gitdir = repo_submodule_path(the_repository,
491 + path, "%s", "");
492 if (!submodule_gitdir)
493 return 0;
494