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>

Patrick Steinhardt committed May 15, 2024 at 08:51 UTC f1701f279a3678e95daa5c093b8d30e815c1701b
5 files changed +31 -27
builtin/for-each-ref.c
+1 -1
@@ -98,7 +98,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
98 }
99
100 if (include_root_refs)
101 - flags |= FILTER_REFS_ROOT_REFS;
101 + flags |= FILTER_REFS_ROOT_REFS | FILTER_REFS_DETACHED_HEAD;
102
103 filter.match_as_path = 1;
104 filter_and_format_refs(&filter, flags, sorting, &format);
ref-filter.c
+9 -7
@@ -2628,7 +2628,7 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
2628 each_ref_fn cb,
2629 void *cb_data)
2630 {
2631 - if (filter->kind == FILTER_REFS_KIND_MASK) {
2631 + if (filter->kind & FILTER_REFS_ROOT_REFS) {
2632 /* In this case, we want to print all refs including root refs. */
2633 return refs_for_each_include_root_refs(get_main_ref_store(the_repository),
2634 cb, cb_data);
@@ -2756,8 +2756,10 @@ static int ref_kind_from_refname(const char *refname)
2756 return ref_kind[i].kind;
2757 }
2758
2759 - if (is_root_ref(refname))
2759 + if (is_pseudo_ref(refname))
2760 return FILTER_REFS_PSEUDOREFS;
2761 + if (is_root_ref(refname))
2762 + return FILTER_REFS_ROOT_REFS;
2763
2764 return FILTER_REFS_OTHERS;
2765 }
@@ -2794,11 +2796,11 @@ static struct ref_array_item *apply_ref_filter(const char *refname, const struct
2796 /*
2797 * Generally HEAD refs are printed with special description denoting a rebase,
2798 * detached state and so forth. This is useful when only printing the HEAD ref
2797 - * But when it is being printed along with other pseudorefs, it makes sense to
2798 - * keep the formatting consistent. So we mask the type to act like a pseudoref.
2799 + * But when it is being printed along with other root refs, it makes sense to
2800 + * keep the formatting consistent. So we mask the type to act like a root ref.
2801 */
2800 - if (filter->kind == FILTER_REFS_KIND_MASK && kind == FILTER_REFS_DETACHED_HEAD)
2801 - kind = FILTER_REFS_PSEUDOREFS;
2802 + if (filter->kind & FILTER_REFS_ROOT_REFS && kind == FILTER_REFS_DETACHED_HEAD)
2803 + kind = FILTER_REFS_ROOT_REFS;
2804 else if (!(kind & filter->kind))
2805 return NULL;
2806
@@ -3072,7 +3074,7 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref
3074 * When printing all ref types, HEAD is already included,
3075 * so we don't want to print HEAD again.
3076 */
3075 - if (!ret && (filter->kind != FILTER_REFS_KIND_MASK) &&
3077 + if (!ret && !(filter->kind & FILTER_REFS_ROOT_REFS) &&
3078 (filter->kind & FILTER_REFS_DETACHED_HEAD))
3079 head_ref(fn, cb_data);
3080 }
ref-filter.h
+2 -2
@@ -23,9 +23,9 @@
23 FILTER_REFS_REMOTES | FILTER_REFS_OTHERS)
24 #define FILTER_REFS_DETACHED_HEAD 0x0020
25 #define FILTER_REFS_PSEUDOREFS 0x0040
26 -#define FILTER_REFS_ROOT_REFS (FILTER_REFS_DETACHED_HEAD | FILTER_REFS_PSEUDOREFS)
26 +#define FILTER_REFS_ROOT_REFS 0x0080
27 #define FILTER_REFS_KIND_MASK (FILTER_REFS_REGULAR | FILTER_REFS_DETACHED_HEAD | \
28 - FILTER_REFS_PSEUDOREFS)
28 + FILTER_REFS_PSEUDOREFS | FILTER_REFS_ROOT_REFS)
29
30 struct atom_value;
31 struct ref_sorting;
refs.c
+1 -17
@@ -844,24 +844,8 @@ int is_per_worktree_ref(const char *refname)
844 starts_with(refname, "refs/rewritten/");
845 }
846
847 -static int is_pseudo_ref(const char *refname)
847 +int is_pseudo_ref(const char *refname)
848 {
849 - /*
850 - * Pseudorefs are refs that have different semantics compared to
851 - * "normal" refs. These refs can thus not be stored in the ref backend,
852 - * but must always be accessed via the filesystem. The following refs
853 - * are pseudorefs:
854 - *
855 - * - FETCH_HEAD may contain multiple object IDs, and each one of them
856 - * carries additional metadata like where it came from.
857 - *
858 - * - MERGE_HEAD may contain multiple object IDs when merging multiple
859 - * heads.
860 - *
861 - * Reading, writing or deleting references must consistently go either
862 - * through the filesystem (pseudorefs) or through the reference
863 - * backend (normal ones).
864 - */
849 static const char * const pseudo_refs[] = {
850 "FETCH_HEAD",
851 "MERGE_HEAD",
refs.h
+18
@@ -1080,4 +1080,22 @@ void update_ref_namespace(enum ref_namespace namespace, char *ref);
1080 */
1081 int is_root_ref(const char *refname);
1082
1083 +/*
1084 + * Pseudorefs are refs that have different semantics compared to
1085 + * "normal" refs. These refs can thus not be stored in the ref backend,
1086 + * but must always be accessed via the filesystem. The following refs
1087 + * are pseudorefs:
1088 + *
1089 + * - FETCH_HEAD may contain multiple object IDs, and each one of them
1090 + * carries additional metadata like where it came from.
1091 + *
1092 + * - MERGE_HEAD may contain multiple object IDs when merging multiple
1093 + * heads.
1094 + *
1095 + * Reading, writing or deleting references must consistently go either
1096 + * through the filesystem (pseudorefs) or through the reference
1097 + * backend (normal ones).
1098 + */
1099 +int is_pseudo_ref(const char *refname);
1100 +
1101 #endif /* REFS_H */