worktree.c: make find_shared_symref() return struct worktree *
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Fri, 22 Apr 2016 13:01:27 +0000 (20:01 +0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 22 Apr 2016 21:09:37 +0000 (14:09 -0700)
This gives the caller more information and they can answer things like,
"is it the main worktree" or "is it the current worktree". The latter
question is needed for the "checkout a rebase branch" case later.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
branch.c
builtin/branch.c
builtin/notes.c
worktree.c
worktree.h
index 0674a993283f13b2c6aae04bed8cbb23ab7a50d2..1f1fbf528c638fc3a0dc9ae1b0f711870cd39af6 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -336,13 +336,14 @@ void remove_branch_state(void)
 
 void die_if_checked_out(const char *branch)
 {
-       char *existing;
+       const struct worktree *wt;
 
-       existing = find_shared_symref("HEAD", branch);
-       if (existing) {
-               skip_prefix(branch, "refs/heads/", &branch);
-               die(_("'%s' is already checked out at '%s'"), branch, existing);
-       }
+       wt = find_shared_symref("HEAD", branch);
+       if (!wt)
+               return;
+       skip_prefix(branch, "refs/heads/", &branch);
+       die(_("'%s' is already checked out at '%s'"),
+           branch, wt->path);
 }
 
 int replace_each_worktree_head_symref(const char *oldref, const char *newref)
index 0adba629d2ae35a4db74fb9d1450b54bb11e51e3..bcde87d8e72d53f94f6d0e9caec6737dc2774f1a 100644 (file)
@@ -220,12 +220,12 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
                name = mkpathdup(fmt, bname.buf);
 
                if (kinds == FILTER_REFS_BRANCHES) {
-                       char *worktree = find_shared_symref("HEAD", name);
-                       if (worktree) {
+                       const struct worktree *wt =
+                               find_shared_symref("HEAD", name);
+                       if (wt) {
                                error(_("Cannot delete branch '%s' "
                                        "checked out at '%s'"),
-                                     bname.buf, worktree);
-                               free(worktree);
+                                     bname.buf, wt->path);
                                ret = 1;
                                continue;
                        }
index 6fd058de9272631a3d5135ccbbd79bf1b4ff135c..c65b59ad9a340e9b68e4d09ea8912499227fce66 100644 (file)
@@ -847,15 +847,15 @@ static int merge(int argc, const char **argv, const char *prefix)
                update_ref(msg.buf, default_notes_ref(), result_sha1, NULL,
                           0, UPDATE_REFS_DIE_ON_ERR);
        else { /* Merge has unresolved conflicts */
-               char *existing;
+               const struct worktree *wt;
                /* Update .git/NOTES_MERGE_PARTIAL with partial merge result */
                update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL,
                           0, UPDATE_REFS_DIE_ON_ERR);
                /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
-               existing = find_shared_symref("NOTES_MERGE_REF", default_notes_ref());
-               if (existing)
+               wt = find_shared_symref("NOTES_MERGE_REF", default_notes_ref());
+               if (wt)
                        die(_("A notes merge into %s is already in-progress at %s"),
-                           default_notes_ref(), existing);
+                           default_notes_ref(), wt->path);
                if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL))
                        die("Failed to store link to current notes ref (%s)",
                            default_notes_ref());
index 5ae54f009151939879d4891e2fa95f59110fb6ff..360ba417e828d92d7473f6dff8b49bb61a42440a 100644 (file)
@@ -191,14 +191,19 @@ const char *get_worktree_git_dir(const struct worktree *wt)
                return git_common_path("worktrees/%s", wt->id);
 }
 
-char *find_shared_symref(const char *symref, const char *target)
+const struct worktree *find_shared_symref(const char *symref,
+                                         const char *target)
 {
-       char *existing = NULL;
+       const struct worktree *existing = NULL;
        struct strbuf path = STRBUF_INIT;
        struct strbuf sb = STRBUF_INIT;
-       struct worktree **worktrees = get_worktrees();
+       static struct worktree **worktrees;
        int i = 0;
 
+       if (worktrees)
+               free_worktrees(worktrees);
+       worktrees = get_worktrees();
+
        for (i = 0; worktrees[i]; i++) {
                strbuf_reset(&path);
                strbuf_reset(&sb);
@@ -211,14 +216,13 @@ char *find_shared_symref(const char *symref, const char *target)
                }
 
                if (!strcmp(sb.buf, target)) {
-                       existing = xstrdup(worktrees[i]->path);
+                       existing = worktrees[i];
                        break;
                }
        }
 
        strbuf_release(&path);
        strbuf_release(&sb);
-       free_worktrees(worktrees);
 
        return existing;
 }
index 3198c8da2a614ed705a0ee25a7c5a9a7c217eaff..ca50e73b58cf77ec035b1bf1546c755f493a2ed3 100644 (file)
@@ -35,10 +35,10 @@ extern void free_worktrees(struct worktree **);
 
 /*
  * 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.
+ * or any linked worktree, and return the worktree that holds the ref,
+ * or NULL otherwise. The result may be destroyed by the next call.
  */
-extern char *find_shared_symref(const char *symref, const char *target);
+extern const struct worktree *find_shared_symref(const char *symref,
+                                                const char *target);
 
 #endif