worktree.c: make find_shared_symref() return struct worktree *

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>

Nguyễn Thái Ngọc Duy committed Apr 22, 2016 at 20:01 UTC d3b9ac07eb44974bb619d71fc6c81c9f2036b96c
5 files changed +28 -23
branch.c
+7 -6
@@ -336,13 +336,14 @@ void remove_branch_state(void)
336
337 void die_if_checked_out(const char *branch)
338 {
339 - char *existing;
339 + const struct worktree *wt;
340
341 - existing = find_shared_symref("HEAD", branch);
342 - if (existing) {
343 - skip_prefix(branch, "refs/heads/", &branch);
344 - die(_("'%s' is already checked out at '%s'"), branch, existing);
345 - }
341 + wt = find_shared_symref("HEAD", branch);
342 + if (!wt)
343 + return;
344 + skip_prefix(branch, "refs/heads/", &branch);
345 + die(_("'%s' is already checked out at '%s'"),
346 + branch, wt->path);
347 }
348
349 int replace_each_worktree_head_symref(const char *oldref, const char *newref)
builtin/branch.c
+4 -4
@@ -220,12 +220,12 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
220 name = mkpathdup(fmt, bname.buf);
221
222 if (kinds == FILTER_REFS_BRANCHES) {
223 - char *worktree = find_shared_symref("HEAD", name);
224 - if (worktree) {
223 + const struct worktree *wt =
224 + find_shared_symref("HEAD", name);
225 + if (wt) {
226 error(_("Cannot delete branch '%s' "
227 "checked out at '%s'"),
227 - bname.buf, worktree);
228 - free(worktree);
228 + bname.buf, wt->path);
229 ret = 1;
230 continue;
231 }
builtin/notes.c
+4 -4
@@ -847,15 +847,15 @@ static int merge(int argc, const char **argv, const char *prefix)
847 update_ref(msg.buf, default_notes_ref(), result_sha1, NULL,
848 0, UPDATE_REFS_DIE_ON_ERR);
849 else { /* Merge has unresolved conflicts */
850 - char *existing;
850 + const struct worktree *wt;
851 /* Update .git/NOTES_MERGE_PARTIAL with partial merge result */
852 update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL,
853 0, UPDATE_REFS_DIE_ON_ERR);
854 /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
855 - existing = find_shared_symref("NOTES_MERGE_REF", default_notes_ref());
856 - if (existing)
855 + wt = find_shared_symref("NOTES_MERGE_REF", default_notes_ref());
856 + if (wt)
857 die(_("A notes merge into %s is already in-progress at %s"),
858 - default_notes_ref(), existing);
858 + default_notes_ref(), wt->path);
859 if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL))
860 die("Failed to store link to current notes ref (%s)",
861 default_notes_ref());
worktree.c
+9 -5
@@ -191,14 +191,19 @@ const char *get_worktree_git_dir(const struct worktree *wt)
191 return git_common_path("worktrees/%s", wt->id);
192 }
193
194 -char *find_shared_symref(const char *symref, const char *target)
194 +const struct worktree *find_shared_symref(const char *symref,
195 + const char *target)
196 {
196 - char *existing = NULL;
197 + const struct worktree *existing = NULL;
198 struct strbuf path = STRBUF_INIT;
199 struct strbuf sb = STRBUF_INIT;
199 - struct worktree **worktrees = get_worktrees();
200 + static struct worktree **worktrees;
201 int i = 0;
202
203 + if (worktrees)
204 + free_worktrees(worktrees);
205 + worktrees = get_worktrees();
206 +
207 for (i = 0; worktrees[i]; i++) {
208 strbuf_reset(&path);
209 strbuf_reset(&sb);
@@ -211,14 +216,13 @@ char *find_shared_symref(const char *symref, const char *target)
216 }
217
218 if (!strcmp(sb.buf, target)) {
214 - existing = xstrdup(worktrees[i]->path);
219 + existing = worktrees[i];
220 break;
221 }
222 }
223
224 strbuf_release(&path);
225 strbuf_release(&sb);
221 - free_worktrees(worktrees);
226
227 return existing;
228 }
worktree.h
+4 -4
@@ -35,10 +35,10 @@ extern void free_worktrees(struct worktree **);
35
36 /*
37 * Check if a per-worktree symref points to a ref in the main worktree
38 - * or any linked worktree, and return the path to the exising worktree
39 - * if it is. Returns NULL if there is no existing ref. The caller is
40 - * responsible for freeing the returned path.
38 + * or any linked worktree, and return the worktree that holds the ref,
39 + * or NULL otherwise. The result may be destroyed by the next call.
40 */
42 -extern char *find_shared_symref(const char *symref, const char *target);
41 +extern const struct worktree *find_shared_symref(const char *symref,
42 + const char *target);
43
44 #endif