summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--revision.c21
-rw-r--r--worktree.c49
-rw-r--r--worktree.h15
3 files changed, 74 insertions, 11 deletions
diff --git a/revision.c b/revision.c
index 63aae722c1..8ce660e3b1 100644
--- a/revision.c
+++ b/revision.c
@@ -1177,7 +1177,7 @@ struct all_refs_cb {
int warned_bad_reflog;
struct rev_info *all_revs;
const char *name_for_errormsg;
- struct ref_store *refs;
+ struct worktree *wt;
};
int ref_excluded(struct string_list *ref_excludes, const char *path)
@@ -1214,7 +1214,7 @@ static void init_all_refs_cb(struct all_refs_cb *cb, struct rev_info *revs,
cb->all_revs = revs;
cb->all_flags = flags;
revs->rev_input_given = 1;
- cb->refs = NULL;
+ cb->wt = NULL;
}
void clear_ref_exclusion(struct string_list **ref_excludes_p)
@@ -1277,15 +1277,20 @@ static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
return 0;
}
-static int handle_one_reflog(const char *refname,
+static int handle_one_reflog(const char *refname_in_wt,
const struct object_id *oid,
int flag, void *cb_data)
{
struct all_refs_cb *cb = cb_data;
+ struct strbuf refname = STRBUF_INIT;
+
cb->warned_bad_reflog = 0;
- cb->name_for_errormsg = refname;
- refs_for_each_reflog_ent(cb->refs, refname,
+ strbuf_worktree_ref(cb->wt, &refname, refname_in_wt);
+ cb->name_for_errormsg = refname.buf;
+ refs_for_each_reflog_ent(get_main_ref_store(the_repository),
+ refname.buf,
handle_one_reflog_ent, cb_data);
+ strbuf_release(&refname);
return 0;
}
@@ -1300,8 +1305,8 @@ static void add_other_reflogs_to_pending(struct all_refs_cb *cb)
if (wt->is_current)
continue;
- cb->refs = get_worktree_ref_store(wt);
- refs_for_each_reflog(cb->refs,
+ cb->wt = wt;
+ refs_for_each_reflog(get_worktree_ref_store(wt),
handle_one_reflog,
cb);
}
@@ -1314,7 +1319,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
cb.all_revs = revs;
cb.all_flags = flags;
- cb.refs = get_main_ref_store(the_repository);
+ cb.wt = NULL;
for_each_reflog(handle_one_reflog, &cb);
if (!revs->single_worktree)
diff --git a/worktree.c b/worktree.c
index 4193496f2a..e6a65ec684 100644
--- a/worktree.c
+++ b/worktree.c
@@ -517,6 +517,45 @@ int parse_worktree_ref(const char *worktree_ref, const char **name,
return -1;
}
+void strbuf_worktree_ref(const struct worktree *wt,
+ struct strbuf *sb,
+ const char *refname)
+{
+ switch (ref_type(refname)) {
+ case REF_TYPE_PSEUDOREF:
+ case REF_TYPE_PER_WORKTREE:
+ if (wt && !wt->is_current) {
+ if (is_main_worktree(wt))
+ strbuf_addstr(sb, "main-worktree/");
+ else
+ strbuf_addf(sb, "worktrees/%s/", wt->id);
+ }
+ break;
+
+ case REF_TYPE_MAIN_PSEUDOREF:
+ case REF_TYPE_OTHER_PSEUDOREF:
+ break;
+
+ case REF_TYPE_NORMAL:
+ /*
+ * For shared refs, don't prefix worktrees/ or
+ * main-worktree/. It's not necessary and
+ * files-backend.c can't handle it anyway.
+ */
+ break;
+ }
+ strbuf_addstr(sb, refname);
+}
+
+const char *worktree_ref(const struct worktree *wt, const char *refname)
+{
+ static struct strbuf sb = STRBUF_INIT;
+
+ strbuf_reset(&sb);
+ strbuf_worktree_ref(wt, &sb, refname);
+ return sb.buf;
+}
+
int other_head_refs(each_ref_fn fn, void *cb_data)
{
struct worktree **worktrees, **p;
@@ -525,13 +564,17 @@ int other_head_refs(each_ref_fn fn, void *cb_data)
worktrees = get_worktrees(0);
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
- struct ref_store *refs;
+ struct object_id oid;
+ int flag;
if (wt->is_current)
continue;
- refs = get_worktree_ref_store(wt);
- ret = refs_head_ref(refs, fn, cb_data);
+ if (!refs_read_ref_full(get_main_ref_store(the_repository),
+ worktree_ref(wt, "HEAD"),
+ RESOLVE_REF_READING,
+ &oid, &flag))
+ ret = fn(worktree_ref(wt, "HEAD"), &oid, flag, cb_data);
if (ret)
break;
}
diff --git a/worktree.h b/worktree.h
index 440bb219dd..1164ca396f 100644
--- a/worktree.h
+++ b/worktree.h
@@ -117,4 +117,19 @@ extern const char *worktree_git_path(const struct worktree *wt,
*/
int parse_worktree_ref(const char *worktree_ref, const char **name,
int *name_length, const char **ref);
+
+/*
+ * Return a refname suitable for access from the current ref store.
+ */
+void strbuf_worktree_ref(const struct worktree *wt,
+ struct strbuf *sb,
+ const char *refname);
+
+/*
+ * Return a refname suitable for access from the current ref
+ * store. The result will be destroyed at the next call.
+ */
+const char *worktree_ref(const struct worktree *wt,
+ const char *refname);
+
#endif