1
0
mirror of https://github.com/git/git.git synced 2024-11-08 14:09:26 +01:00

ref-filter: properly distinuish pseudo and root refs

The ref-filter interfaces currently define root refs as either a
detached HEAD or a pseudo ref. Pseudo refs aren't root refs though, so
let's properly distinguish those ref types.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt 2024-05-15 08:51:05 +02:00 committed by Junio C Hamano
parent 993d57eded
commit f1701f279a
5 changed files with 31 additions and 27 deletions

@ -98,7 +98,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
} }
if (include_root_refs) if (include_root_refs)
flags |= FILTER_REFS_ROOT_REFS; flags |= FILTER_REFS_ROOT_REFS | FILTER_REFS_DETACHED_HEAD;
filter.match_as_path = 1; filter.match_as_path = 1;
filter_and_format_refs(&filter, flags, sorting, &format); filter_and_format_refs(&filter, flags, sorting, &format);

@ -2628,7 +2628,7 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
each_ref_fn cb, each_ref_fn cb,
void *cb_data) void *cb_data)
{ {
if (filter->kind == FILTER_REFS_KIND_MASK) { if (filter->kind & FILTER_REFS_ROOT_REFS) {
/* In this case, we want to print all refs including root refs. */ /* In this case, we want to print all refs including root refs. */
return refs_for_each_include_root_refs(get_main_ref_store(the_repository), return refs_for_each_include_root_refs(get_main_ref_store(the_repository),
cb, cb_data); cb, cb_data);
@ -2756,8 +2756,10 @@ static int ref_kind_from_refname(const char *refname)
return ref_kind[i].kind; return ref_kind[i].kind;
} }
if (is_root_ref(refname)) if (is_pseudo_ref(refname))
return FILTER_REFS_PSEUDOREFS; return FILTER_REFS_PSEUDOREFS;
if (is_root_ref(refname))
return FILTER_REFS_ROOT_REFS;
return FILTER_REFS_OTHERS; return FILTER_REFS_OTHERS;
} }
@ -2794,11 +2796,11 @@ static struct ref_array_item *apply_ref_filter(const char *refname, const struct
/* /*
* Generally HEAD refs are printed with special description denoting a rebase, * Generally HEAD refs are printed with special description denoting a rebase,
* detached state and so forth. This is useful when only printing the HEAD ref * detached state and so forth. This is useful when only printing the HEAD ref
* But when it is being printed along with other pseudorefs, it makes sense to * But when it is being printed along with other root refs, it makes sense to
* keep the formatting consistent. So we mask the type to act like a pseudoref. * keep the formatting consistent. So we mask the type to act like a root ref.
*/ */
if (filter->kind == FILTER_REFS_KIND_MASK && kind == FILTER_REFS_DETACHED_HEAD) if (filter->kind & FILTER_REFS_ROOT_REFS && kind == FILTER_REFS_DETACHED_HEAD)
kind = FILTER_REFS_PSEUDOREFS; kind = FILTER_REFS_ROOT_REFS;
else if (!(kind & filter->kind)) else if (!(kind & filter->kind))
return NULL; return NULL;
@ -3072,7 +3074,7 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref
* When printing all ref types, HEAD is already included, * When printing all ref types, HEAD is already included,
* so we don't want to print HEAD again. * so we don't want to print HEAD again.
*/ */
if (!ret && (filter->kind != FILTER_REFS_KIND_MASK) && if (!ret && !(filter->kind & FILTER_REFS_ROOT_REFS) &&
(filter->kind & FILTER_REFS_DETACHED_HEAD)) (filter->kind & FILTER_REFS_DETACHED_HEAD))
head_ref(fn, cb_data); head_ref(fn, cb_data);
} }

@ -23,9 +23,9 @@
FILTER_REFS_REMOTES | FILTER_REFS_OTHERS) FILTER_REFS_REMOTES | FILTER_REFS_OTHERS)
#define FILTER_REFS_DETACHED_HEAD 0x0020 #define FILTER_REFS_DETACHED_HEAD 0x0020
#define FILTER_REFS_PSEUDOREFS 0x0040 #define FILTER_REFS_PSEUDOREFS 0x0040
#define FILTER_REFS_ROOT_REFS (FILTER_REFS_DETACHED_HEAD | FILTER_REFS_PSEUDOREFS) #define FILTER_REFS_ROOT_REFS 0x0080
#define FILTER_REFS_KIND_MASK (FILTER_REFS_REGULAR | FILTER_REFS_DETACHED_HEAD | \ #define FILTER_REFS_KIND_MASK (FILTER_REFS_REGULAR | FILTER_REFS_DETACHED_HEAD | \
FILTER_REFS_PSEUDOREFS) FILTER_REFS_PSEUDOREFS | FILTER_REFS_ROOT_REFS)
struct atom_value; struct atom_value;
struct ref_sorting; struct ref_sorting;

18
refs.c

@ -844,24 +844,8 @@ int is_per_worktree_ref(const char *refname)
starts_with(refname, "refs/rewritten/"); starts_with(refname, "refs/rewritten/");
} }
static int is_pseudo_ref(const char *refname) int is_pseudo_ref(const char *refname)
{ {
/*
* Pseudorefs are refs that have different semantics compared to
* "normal" refs. These refs can thus not be stored in the ref backend,
* but must always be accessed via the filesystem. The following refs
* are pseudorefs:
*
* - FETCH_HEAD may contain multiple object IDs, and each one of them
* carries additional metadata like where it came from.
*
* - MERGE_HEAD may contain multiple object IDs when merging multiple
* heads.
*
* Reading, writing or deleting references must consistently go either
* through the filesystem (pseudorefs) or through the reference
* backend (normal ones).
*/
static const char * const pseudo_refs[] = { static const char * const pseudo_refs[] = {
"FETCH_HEAD", "FETCH_HEAD",
"MERGE_HEAD", "MERGE_HEAD",

18
refs.h

@ -1080,4 +1080,22 @@ void update_ref_namespace(enum ref_namespace namespace, char *ref);
*/ */
int is_root_ref(const char *refname); int is_root_ref(const char *refname);
/*
* Pseudorefs are refs that have different semantics compared to
* "normal" refs. These refs can thus not be stored in the ref backend,
* but must always be accessed via the filesystem. The following refs
* are pseudorefs:
*
* - FETCH_HEAD may contain multiple object IDs, and each one of them
* carries additional metadata like where it came from.
*
* - MERGE_HEAD may contain multiple object IDs when merging multiple
* heads.
*
* Reading, writing or deleting references must consistently go either
* through the filesystem (pseudorefs) or through the reference
* backend (normal ones).
*/
int is_pseudo_ref(const char *refname);
#endif /* REFS_H */ #endif /* REFS_H */