refs: unify parse_worktree_ref() and ref_type()
The logic to handle worktree refs (worktrees/NAME/REF and main-worktree/REF) existed in two places: * ref_type() in refs.c * parse_worktree_ref() in worktree.c Collapse this logic together in one function parse_worktree_ref(): this avoids having to cross-check the result of parse_worktree_ref() and ref_type(). Introduce enum ref_worktree_type, which is slightly different from enum ref_type. The latter is a misleading name (one would think that 'ref_type' would have the symref option). Instead, enum ref_worktree_type only makes explicit how a refname relates to a worktree. From this point of view, HEAD and refs/bisect/abc are the same: they specify the current worktree implicitly. The files-backend must avoid packing refs/bisect/* and friends into packed-refs, so expose is_per_worktree_ref() separately. Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
d3fa443f97
commit
71e5473493
76
refs.c
76
refs.c
@ -811,7 +811,7 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **log)
|
||||
return repo_dwim_log(the_repository, str, len, oid, log);
|
||||
}
|
||||
|
||||
static int is_per_worktree_ref(const char *refname)
|
||||
int is_per_worktree_ref(const char *refname)
|
||||
{
|
||||
return starts_with(refname, "refs/worktree/") ||
|
||||
starts_with(refname, "refs/bisect/") ||
|
||||
@ -827,37 +827,63 @@ static int is_pseudoref_syntax(const char *refname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* HEAD is not a pseudoref, but it certainly uses the
|
||||
* pseudoref syntax.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_main_pseudoref_syntax(const char *refname)
|
||||
{
|
||||
return skip_prefix(refname, "main-worktree/", &refname) &&
|
||||
*refname &&
|
||||
is_pseudoref_syntax(refname);
|
||||
static int is_current_worktree_ref(const char *ref) {
|
||||
return is_pseudoref_syntax(ref) || is_per_worktree_ref(ref);
|
||||
}
|
||||
|
||||
static int is_other_pseudoref_syntax(const char *refname)
|
||||
enum ref_worktree_type parse_worktree_ref(const char *maybe_worktree_ref,
|
||||
const char **worktree_name, int *worktree_name_length,
|
||||
const char **bare_refname)
|
||||
{
|
||||
if (!skip_prefix(refname, "worktrees/", &refname))
|
||||
return 0;
|
||||
refname = strchr(refname, '/');
|
||||
if (!refname || !refname[1])
|
||||
return 0;
|
||||
return is_pseudoref_syntax(refname + 1);
|
||||
}
|
||||
const char *name_dummy;
|
||||
int name_length_dummy;
|
||||
const char *ref_dummy;
|
||||
|
||||
enum ref_type ref_type(const char *refname)
|
||||
{
|
||||
if (is_per_worktree_ref(refname))
|
||||
return REF_TYPE_PER_WORKTREE;
|
||||
if (is_pseudoref_syntax(refname))
|
||||
return REF_TYPE_PSEUDOREF;
|
||||
if (is_main_pseudoref_syntax(refname))
|
||||
return REF_TYPE_MAIN_PSEUDOREF;
|
||||
if (is_other_pseudoref_syntax(refname))
|
||||
return REF_TYPE_OTHER_PSEUDOREF;
|
||||
return REF_TYPE_NORMAL;
|
||||
if (!worktree_name)
|
||||
worktree_name = &name_dummy;
|
||||
if (!worktree_name_length)
|
||||
worktree_name_length = &name_length_dummy;
|
||||
if (!bare_refname)
|
||||
bare_refname = &ref_dummy;
|
||||
|
||||
if (skip_prefix(maybe_worktree_ref, "worktrees/", bare_refname)) {
|
||||
const char *slash = strchr(*bare_refname, '/');
|
||||
|
||||
*worktree_name = *bare_refname;
|
||||
if (!slash) {
|
||||
*worktree_name_length = strlen(*worktree_name);
|
||||
|
||||
/* This is an error condition, and the caller tell because the bare_refname is "" */
|
||||
*bare_refname = *worktree_name + *worktree_name_length;
|
||||
return REF_WORKTREE_OTHER;
|
||||
}
|
||||
|
||||
*worktree_name_length = slash - *bare_refname;
|
||||
*bare_refname = slash + 1;
|
||||
|
||||
if (is_current_worktree_ref(*bare_refname))
|
||||
return REF_WORKTREE_OTHER;
|
||||
}
|
||||
|
||||
*worktree_name = NULL;
|
||||
*worktree_name_length = 0;
|
||||
|
||||
if (skip_prefix(maybe_worktree_ref, "main-worktree/", bare_refname)
|
||||
&& is_current_worktree_ref(*bare_refname))
|
||||
return REF_WORKTREE_MAIN;
|
||||
|
||||
*bare_refname = maybe_worktree_ref;
|
||||
if (is_current_worktree_ref(maybe_worktree_ref))
|
||||
return REF_WORKTREE_CURRENT;
|
||||
|
||||
return REF_WORKTREE_SHARED;
|
||||
}
|
||||
|
||||
long get_files_ref_lock_timeout_ms(void)
|
||||
|
Reference in New Issue
Block a user