diff options
Diffstat (limited to 'path.c')
-rw-r--r-- | path.c | 98 |
1 files changed, 84 insertions, 14 deletions
@@ -5,6 +5,8 @@ #include "strbuf.h" #include "string-list.h" #include "dir.h" +#include "worktree.h" +#include "submodule-config.h" static int get_st_mode_bits(const char *path, int *mode) { @@ -134,7 +136,7 @@ static struct common_dir common_list[] = { * definite * definition * - * The trie would look look like: + * The trie would look like: * root: len = 0, children a and d non-NULL, value = NULL. * a: len = 2, contents = bc, value = (data for "abc") * d: len = 2, contents = ef, children i non-NULL, value = (data for "def") @@ -379,14 +381,17 @@ static void adjust_git_path(struct strbuf *buf, int git_dir_len) get_index_file(), strlen(get_index_file())); else if (git_db_env && dir_prefix(base, "objects")) replace_dir(buf, git_dir_len + 7, get_object_directory()); + else if (git_hooks_path && dir_prefix(base, "hooks")) + replace_dir(buf, git_dir_len + 5, git_hooks_path); else if (git_common_dir_env) update_common_dir(buf, git_dir_len, NULL); } -static void do_git_path(struct strbuf *buf, const char *fmt, va_list args) +static void do_git_path(const struct worktree *wt, struct strbuf *buf, + const char *fmt, va_list args) { int gitdir_len; - strbuf_addstr(buf, get_git_dir()); + strbuf_addstr(buf, get_worktree_git_dir(wt)); if (buf->len && !is_dir_sep(buf->buf[buf->len - 1])) strbuf_addch(buf, '/'); gitdir_len = buf->len; @@ -400,7 +405,7 @@ char *git_path_buf(struct strbuf *buf, const char *fmt, ...) va_list args; strbuf_reset(buf); va_start(args, fmt); - do_git_path(buf, fmt, args); + do_git_path(NULL, buf, fmt, args); va_end(args); return buf->buf; } @@ -409,7 +414,7 @@ void strbuf_git_path(struct strbuf *sb, const char *fmt, ...) { va_list args; va_start(args, fmt); - do_git_path(sb, fmt, args); + do_git_path(NULL, sb, fmt, args); va_end(args); } @@ -418,7 +423,7 @@ const char *git_path(const char *fmt, ...) struct strbuf *pathname = get_pathname(); va_list args; va_start(args, fmt); - do_git_path(pathname, fmt, args); + do_git_path(NULL, pathname, fmt, args); va_end(args); return pathname->buf; } @@ -428,7 +433,7 @@ char *git_pathdup(const char *fmt, ...) struct strbuf path = STRBUF_INIT; va_list args; va_start(args, fmt); - do_git_path(&path, fmt, args); + do_git_path(NULL, &path, fmt, args); va_end(args); return strbuf_detach(&path, NULL); } @@ -454,12 +459,26 @@ const char *mkpath(const char *fmt, ...) return cleanup_path(pathname->buf); } -static void do_submodule_path(struct strbuf *buf, const char *path, - const char *fmt, va_list args) +const char *worktree_git_path(const struct worktree *wt, const char *fmt, ...) +{ + struct strbuf *pathname = get_pathname(); + va_list args; + va_start(args, fmt); + do_git_path(wt, pathname, fmt, args); + va_end(args); + return pathname->buf; +} + +/* Returns 0 on success, negative on failure. */ +#define SUBMODULE_PATH_ERR_NOT_CONFIGURED -1 +static int do_submodule_path(struct strbuf *buf, const char *path, + const char *fmt, va_list args) { const char *git_dir; struct strbuf git_submodule_common_dir = STRBUF_INIT; struct strbuf git_submodule_dir = STRBUF_INIT; + const struct submodule *sub; + int err = 0; strbuf_addstr(buf, path); strbuf_complete(buf, '/'); @@ -470,8 +489,19 @@ static void do_submodule_path(struct strbuf *buf, const char *path, strbuf_reset(buf); strbuf_addstr(buf, git_dir); } + if (!is_git_directory(buf->buf)) { + gitmodules_config(); + sub = submodule_from_path(null_sha1, path); + if (!sub) { + err = SUBMODULE_PATH_ERR_NOT_CONFIGURED; + goto cleanup; + } + strbuf_reset(buf); + strbuf_git_path(buf, "%s/%s", "modules", sub->name); + } + strbuf_addch(buf, '/'); - strbuf_addstr(&git_submodule_dir, buf->buf); + strbuf_addbuf(&git_submodule_dir, buf); strbuf_vaddf(buf, fmt, args); @@ -480,26 +510,66 @@ static void do_submodule_path(struct strbuf *buf, const char *path, strbuf_cleanup_path(buf); +cleanup: strbuf_release(&git_submodule_dir); strbuf_release(&git_submodule_common_dir); + + return err; } char *git_pathdup_submodule(const char *path, const char *fmt, ...) { + int err; va_list args; struct strbuf buf = STRBUF_INIT; va_start(args, fmt); - do_submodule_path(&buf, path, fmt, args); + err = do_submodule_path(&buf, path, fmt, args); va_end(args); + if (err) { + strbuf_release(&buf); + return NULL; + } return strbuf_detach(&buf, NULL); } -void strbuf_git_path_submodule(struct strbuf *buf, const char *path, - const char *fmt, ...) +int strbuf_git_path_submodule(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); + va_end(args); + + return err; +} + +static void do_git_common_path(struct strbuf *buf, + const char *fmt, + va_list args) +{ + strbuf_addstr(buf, get_git_common_dir()); + if (buf->len && !is_dir_sep(buf->buf[buf->len - 1])) + strbuf_addch(buf, '/'); + strbuf_vaddf(buf, fmt, args); + strbuf_cleanup_path(buf); +} + +const char *git_common_path(const char *fmt, ...) +{ + struct strbuf *pathname = get_pathname(); + va_list args; + va_start(args, fmt); + do_git_common_path(pathname, fmt, args); + va_end(args); + return pathname->buf; +} + +void strbuf_git_common_path(struct strbuf *sb, const char *fmt, ...) { va_list args; va_start(args, fmt); - do_submodule_path(buf, path, fmt, args); + do_git_common_path(sb, fmt, args); va_end(args); } |