On Fri, Jul 31, 2015 at 6:11 PM, David Turner <dturner@xxxxxxxxxxxxxxxx> wrote: > Add a new function, find_shared_symref, which contains the heart of > die_if_checked_out, but works for all symrefs. Refactor Slightly more explanatory: ..., but works for any symref, not just HEAD. Refactor More below. > die_if_checked_out to use the same infrastructure as > find_shared_symref. > > Soon, we will use find_shared_symref to protect notes merges in > worktrees. > > Signed-off-by: David Turner <dturner@xxxxxxxxxxxxxxxx> > --- > diff --git a/branch.c b/branch.c > index c85be07..9b5e3b3 100644 > --- a/branch.c > +++ b/branch.c > @@ -349,31 +350,47 @@ static void check_linked_checkout(const char *branch, const char *id) > strbuf_addstr(&gitdir, get_git_common_dir()); > skip_prefix(branch, "refs/heads/", &branch); > strbuf_strip_suffix(&gitdir, ".git"); > - die(_("'%s' is already checked out at '%s'"), branch, gitdir.buf); > + return strbuf_detach(&gitdir, NULL); By returning here, you're now leaking 'path' and 'sb' (see the 'done' label below). > done: > strbuf_release(&path); > strbuf_release(&sb); > strbuf_release(&gitdir); > + > + return NULL; > } > > -void die_if_checked_out(const char *branch) > +char *find_shared_symref(const char *symref, const char *target) > { > struct strbuf path = STRBUF_INIT; > DIR *dir; > struct dirent *d; > + char *existing; > > - check_linked_checkout(branch, NULL); > + if ((existing = find_linked_symref(symref, target, NULL))) > + return existing; > > strbuf_addf(&path, "%s/worktrees", get_git_common_dir()); > dir = opendir(path.buf); > strbuf_release(&path); > if (!dir) > - return; > + return NULL; > > while ((d = readdir(dir)) != NULL) { > if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) > continue; > - check_linked_checkout(branch, d->d_name); > + if ((existing = find_linked_symref(symref, target, d->d_name))) > + return existing; By returning here, you're leaking the open 'dir'. > } > closedir(dir); > + > + return NULL; > +} > + > +void die_if_checked_out(const char *branch) > +{ > + char *existing; > + > + existing = find_shared_symref("HEAD", branch); > + if (existing) > + die(_("'%s' is already checked out at '%s'"), branch, existing); > } > diff --git a/branch.h b/branch.h > index 58aa45f..0f466c7 100644 > --- a/branch.h > +++ b/branch.h > @@ -59,4 +59,12 @@ extern int read_branch_desc(struct strbuf *, const char *branch_name); > */ > extern void die_if_checked_out(const char *branch); > > +/* > + * Check if a per-worktree symref points to a ref in the main worktree > + * or any linked worktree, and return the path to the exising worktree > + * if it is. Returns NULL if there is no existing ref. The caller is > + * responsible for freeing the returned path. > + */ > +extern char *find_shared_symref(const char *symref, const char *branch); I think you meant s/branch/target/. > #endif > -- > 2.0.4.315.gad8727a-twtrsrc -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html