From 92718b7438799f4654304e2fa3b5b7e5a9fda882 Mon Sep 17 00:00:00 2001 From: Michael Rappazzo Date: Thu, 8 Oct 2015 13:01:04 -0400 Subject: worktree: add details to the worktree struct In addition to the absolute path in the worktree struct, add the location of the git dir, the head ref (if not detached), the head revision sha1, whether or not head is detached, and whether or not the worktree is a bare repo. Signed-off-by: Michael Rappazzo Signed-off-by: Junio C Hamano --- worktree.c | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) (limited to 'worktree.c') diff --git a/worktree.c b/worktree.c index c2e6db0a2c..981f810e80 100644 --- a/worktree.c +++ b/worktree.c @@ -9,6 +9,8 @@ void free_worktrees(struct worktree **worktrees) for (i = 0; worktrees[i]; i++) { free(worktrees[i]->path); + free(worktrees[i]->git_dir); + free(worktrees[i]->head_ref); free(worktrees[i]); } free (worktrees); @@ -49,6 +51,21 @@ static int parse_ref(char *path_to_ref, struct strbuf *ref, int *is_detached) return 0; } +/** + * Add the head_sha1 and head_ref (if not detached) to the given worktree + */ +static void add_head_info(struct strbuf *head_ref, struct worktree *worktree) +{ + if (head_ref->len) { + if (worktree->is_detached) { + get_sha1_hex(head_ref->buf, worktree->head_sha1); + } else { + resolve_ref_unsafe(head_ref->buf, 0, worktree->head_sha1, NULL); + worktree->head_ref = strbuf_detach(head_ref, NULL); + } + } +} + /** * get the main worktree */ @@ -59,19 +76,29 @@ static struct worktree *get_main_worktree(void) struct strbuf worktree_path = STRBUF_INIT; struct strbuf gitdir = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; + int is_bare = 0; + int is_detached = 0; strbuf_addf(&gitdir, "%s", absolute_path(get_git_common_dir())); strbuf_addbuf(&worktree_path, &gitdir); - if (!strbuf_strip_suffix(&worktree_path, "/.git")) + is_bare = !strbuf_strip_suffix(&worktree_path, "/.git"); + if (is_bare) strbuf_strip_suffix(&worktree_path, "/."); strbuf_addf(&path, "%s/HEAD", get_git_common_dir()); - if (parse_ref(path.buf, &head_ref, NULL) >= 0) { - worktree = xmalloc(sizeof(struct worktree)); - worktree->path = strbuf_detach(&worktree_path, NULL); - worktree->git_dir = strbuf_detach(&gitdir, NULL); - } + if (parse_ref(path.buf, &head_ref, &is_detached) < 0) + goto done; + + worktree = xmalloc(sizeof(struct worktree)); + worktree->path = strbuf_detach(&worktree_path, NULL); + worktree->git_dir = strbuf_detach(&gitdir, NULL); + worktree->is_bare = is_bare; + worktree->head_ref = NULL; + worktree->is_detached = is_detached; + add_head_info(&head_ref, worktree); + +done: strbuf_release(&path); strbuf_release(&gitdir); strbuf_release(&worktree_path); @@ -86,6 +113,7 @@ static struct worktree *get_linked_worktree(const char *id) struct strbuf worktree_path = STRBUF_INIT; struct strbuf gitdir = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; + int is_detached = 0; if (!id) die("Missing linked worktree name"); @@ -107,11 +135,16 @@ static struct worktree *get_linked_worktree(const char *id) strbuf_reset(&path); strbuf_addf(&path, "%s/worktrees/%s/HEAD", get_git_common_dir(), id); - if (parse_ref(path.buf, &head_ref, NULL) >= 0) { - worktree = xmalloc(sizeof(struct worktree)); - worktree->path = strbuf_detach(&worktree_path, NULL); - worktree->git_dir = strbuf_detach(&gitdir, NULL); - } + if (parse_ref(path.buf, &head_ref, &is_detached) < 0) + goto done; + + worktree = xmalloc(sizeof(struct worktree)); + worktree->path = strbuf_detach(&worktree_path, NULL); + worktree->git_dir = strbuf_detach(&gitdir, NULL); + worktree->is_bare = 0; + worktree->head_ref = NULL; + worktree->is_detached = is_detached; + add_head_info(&head_ref, worktree); done: strbuf_release(&path); -- cgit v1.2.3