summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2016-04-22 13:01:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-04-22 21:09:37 (GMT)
commitd3b9ac07eb44974bb619d71fc6c81c9f2036b96c (patch)
treeff18f60eb58addac7e2a2008d4d9f1aa43ad3b30
parent69dfe3b9420eb2a7f479a0a4cad663111af2b1f9 (diff)
downloadgit-d3b9ac07eb44974bb619d71fc6c81c9f2036b96c.zip
git-d3b9ac07eb44974bb619d71fc6c81c9f2036b96c.tar.gz
git-d3b9ac07eb44974bb619d71fc6c81c9f2036b96c.tar.bz2
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>
-rw-r--r--branch.c13
-rw-r--r--builtin/branch.c8
-rw-r--r--builtin/notes.c8
-rw-r--r--worktree.c14
-rw-r--r--worktree.h8
5 files changed, 28 insertions, 23 deletions
diff --git a/branch.c b/branch.c
index 0674a99..1f1fbf5 100644
--- 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)
diff --git a/builtin/branch.c b/builtin/branch.c
index 0adba62..bcde87d 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -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;
}
diff --git a/builtin/notes.c b/builtin/notes.c
index 6fd058d..c65b59a 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -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());
diff --git a/worktree.c b/worktree.c
index 5ae54f0..360ba41 100644
--- a/worktree.c
+++ b/worktree.c
@@ -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;
}
diff --git a/worktree.h b/worktree.h
index 3198c8d..ca50e73 100644
--- a/worktree.h
+++ b/worktree.h
@@ -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