Skip to content

Commit ab3e1f7

Browse files
pcloudsgitster
authored andcommitted
revision.c: better error reporting on ref from different worktrees
Make use of the new ref aliases to pass refs from another worktree around and access them from the current ref store instead. This does not change any functionality, but when a problem arises, we would like the reported messages to mention full ref aliases, like this: fatal: bad object worktrees/ztemp/HEAD warning: reflog of 'main-worktree/HEAD' references pruned commits instead of fatal: bad object HEAD warning: reflog of 'HEAD' references pruned commits which does not really tell where the refs are from. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 061e420 commit ab3e1f7

File tree

3 files changed

+74
-11
lines changed

3 files changed

+74
-11
lines changed

revision.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ struct all_refs_cb {
11771177
int warned_bad_reflog;
11781178
struct rev_info *all_revs;
11791179
const char *name_for_errormsg;
1180-
struct ref_store *refs;
1180+
struct worktree *wt;
11811181
};
11821182

11831183
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,
12141214
cb->all_revs = revs;
12151215
cb->all_flags = flags;
12161216
revs->rev_input_given = 1;
1217-
cb->refs = NULL;
1217+
cb->wt = NULL;
12181218
}
12191219

12201220
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,
12771277
return 0;
12781278
}
12791279

1280-
static int handle_one_reflog(const char *refname,
1280+
static int handle_one_reflog(const char *refname_in_wt,
12811281
const struct object_id *oid,
12821282
int flag, void *cb_data)
12831283
{
12841284
struct all_refs_cb *cb = cb_data;
1285+
struct strbuf refname = STRBUF_INIT;
1286+
12851287
cb->warned_bad_reflog = 0;
1286-
cb->name_for_errormsg = refname;
1287-
refs_for_each_reflog_ent(cb->refs, refname,
1288+
strbuf_worktree_ref(cb->wt, &refname, refname_in_wt);
1289+
cb->name_for_errormsg = refname.buf;
1290+
refs_for_each_reflog_ent(get_main_ref_store(the_repository),
1291+
refname.buf,
12881292
handle_one_reflog_ent, cb_data);
1293+
strbuf_release(&refname);
12891294
return 0;
12901295
}
12911296

@@ -1300,8 +1305,8 @@ static void add_other_reflogs_to_pending(struct all_refs_cb *cb)
13001305
if (wt->is_current)
13011306
continue;
13021307

1303-
cb->refs = get_worktree_ref_store(wt);
1304-
refs_for_each_reflog(cb->refs,
1308+
cb->wt = wt;
1309+
refs_for_each_reflog(get_worktree_ref_store(wt),
13051310
handle_one_reflog,
13061311
cb);
13071312
}
@@ -1314,7 +1319,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
13141319

13151320
cb.all_revs = revs;
13161321
cb.all_flags = flags;
1317-
cb.refs = get_main_ref_store(the_repository);
1322+
cb.wt = NULL;
13181323
for_each_reflog(handle_one_reflog, &cb);
13191324

13201325
if (!revs->single_worktree)

worktree.c

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,45 @@ int parse_worktree_ref(const char *worktree_ref, const char **name,
517517
return -1;
518518
}
519519

520+
void strbuf_worktree_ref(const struct worktree *wt,
521+
struct strbuf *sb,
522+
const char *refname)
523+
{
524+
switch (ref_type(refname)) {
525+
case REF_TYPE_PSEUDOREF:
526+
case REF_TYPE_PER_WORKTREE:
527+
if (wt && !wt->is_current) {
528+
if (is_main_worktree(wt))
529+
strbuf_addstr(sb, "main-worktree/");
530+
else
531+
strbuf_addf(sb, "worktrees/%s/", wt->id);
532+
}
533+
break;
534+
535+
case REF_TYPE_MAIN_PSEUDOREF:
536+
case REF_TYPE_OTHER_PSEUDOREF:
537+
break;
538+
539+
case REF_TYPE_NORMAL:
540+
/*
541+
* For shared refs, don't prefix worktrees/ or
542+
* main-worktree/. It's not necessary and
543+
* files-backend.c can't handle it anyway.
544+
*/
545+
break;
546+
}
547+
strbuf_addstr(sb, refname);
548+
}
549+
550+
const char *worktree_ref(const struct worktree *wt, const char *refname)
551+
{
552+
static struct strbuf sb = STRBUF_INIT;
553+
554+
strbuf_reset(&sb);
555+
strbuf_worktree_ref(wt, &sb, refname);
556+
return sb.buf;
557+
}
558+
520559
int other_head_refs(each_ref_fn fn, void *cb_data)
521560
{
522561
struct worktree **worktrees, **p;
@@ -525,13 +564,17 @@ int other_head_refs(each_ref_fn fn, void *cb_data)
525564
worktrees = get_worktrees(0);
526565
for (p = worktrees; *p; p++) {
527566
struct worktree *wt = *p;
528-
struct ref_store *refs;
567+
struct object_id oid;
568+
int flag;
529569

530570
if (wt->is_current)
531571
continue;
532572

533-
refs = get_worktree_ref_store(wt);
534-
ret = refs_head_ref(refs, fn, cb_data);
573+
if (!refs_read_ref_full(get_main_ref_store(the_repository),
574+
worktree_ref(wt, "HEAD"),
575+
RESOLVE_REF_READING,
576+
&oid, &flag))
577+
ret = fn(worktree_ref(wt, "HEAD"), &oid, flag, cb_data);
535578
if (ret)
536579
break;
537580
}

worktree.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,19 @@ extern const char *worktree_git_path(const struct worktree *wt,
117117
*/
118118
int parse_worktree_ref(const char *worktree_ref, const char **name,
119119
int *name_length, const char **ref);
120+
121+
/*
122+
* Return a refname suitable for access from the current ref store.
123+
*/
124+
void strbuf_worktree_ref(const struct worktree *wt,
125+
struct strbuf *sb,
126+
const char *refname);
127+
128+
/*
129+
* Return a refname suitable for access from the current ref
130+
* store. The result will be destroyed at the next call.
131+
*/
132+
const char *worktree_ref(const struct worktree *wt,
133+
const char *refname);
134+
120135
#endif

0 commit comments

Comments
 (0)