]> git.ipfire.org Git - thirdparty/git.git/commitdiff
ref-filter: properly distinuish pseudo and root refs
authorPatrick Steinhardt <ps@pks.im>
Wed, 15 May 2024 06:51:05 +0000 (08:51 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 15 May 2024 14:30:52 +0000 (07:30 -0700)
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>
builtin/for-each-ref.c
ref-filter.c
ref-filter.h
refs.c
refs.h

index 919282e12a335a5a7491b905f27dcfface0120a3..5517a4a1c084eef8982e1cb95daa444a9eb60606 100644 (file)
@@ -98,7 +98,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
        }
 
        if (include_root_refs)
-               flags |= FILTER_REFS_ROOT_REFS;
+               flags |= FILTER_REFS_ROOT_REFS | FILTER_REFS_DETACHED_HEAD;
 
        filter.match_as_path = 1;
        filter_and_format_refs(&filter, flags, sorting, &format);
index 23e81e3e047bf4b4f795b8ac844ee08bb4940872..41f639bc2fd87fede7fa5747e289abf1e8a431ea 100644 (file)
@@ -2628,7 +2628,7 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
                                       each_ref_fn cb,
                                       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. */
                return refs_for_each_include_root_refs(get_main_ref_store(the_repository),
                                                       cb, cb_data);
@@ -2756,8 +2756,10 @@ static int ref_kind_from_refname(const char *refname)
                        return ref_kind[i].kind;
        }
 
-       if (is_root_ref(refname))
+       if (is_pseudo_ref(refname))
                return FILTER_REFS_PSEUDOREFS;
+       if (is_root_ref(refname))
+               return FILTER_REFS_ROOT_REFS;
 
        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,
         * 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
-        * keep the formatting consistent. So we mask the type to act like a pseudoref.
+        * 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 root ref.
         */
-       if (filter->kind == FILTER_REFS_KIND_MASK && kind == FILTER_REFS_DETACHED_HEAD)
-               kind = FILTER_REFS_PSEUDOREFS;
+       if (filter->kind & FILTER_REFS_ROOT_REFS && kind == FILTER_REFS_DETACHED_HEAD)
+               kind = FILTER_REFS_ROOT_REFS;
        else if (!(kind & filter->kind))
                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,
                 * 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))
                        head_ref(fn, cb_data);
        }
index 0ca28d2bba6f2aed4b8d084972739f3a88f44caa..27ae1aa0d1ac70d6dc37c265db5d9d2e8b266809 100644 (file)
@@ -23,9 +23,9 @@
                                    FILTER_REFS_REMOTES | FILTER_REFS_OTHERS)
 #define FILTER_REFS_DETACHED_HEAD  0x0020
 #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 | \
-                                   FILTER_REFS_PSEUDOREFS)
+                                   FILTER_REFS_PSEUDOREFS | FILTER_REFS_ROOT_REFS)
 
 struct atom_value;
 struct ref_sorting;
diff --git a/refs.c b/refs.c
index 2074281a0e21f62aa610686ee28572e7ef8d4ef8..c13b8ff6d801b93c0087af0792f845722762d349 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -844,24 +844,8 @@ int is_per_worktree_ref(const char *refname)
               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[] = {
                "FETCH_HEAD",
                "MERGE_HEAD",
diff --git a/refs.h b/refs.h
index 8489b45265c49d59668d9752e9e8e8da952d9fea..dc4358727f3f76ad336fcadc6c2dd60df4ea28a2 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -1080,4 +1080,22 @@ void update_ref_namespace(enum ref_namespace namespace, char *ref);
  */
 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 */