git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/2] ref-filter: support filtering of operational refs

From
Karthik Nayak <karthik.188@gmail.com>
Date
Dec 21, 2023, 17:07 UTC
Message-ID
<20231221170715.110565-3-karthik.188@gmail.com>
In-Reply-To
<20231221170715.110565-1-karthik.188@gmail.com>

With the upcoming introduction of the reftable backend, it becomes ever so important to provide the necessary tooling for printing all refs associated with a repository.

While regular refs stored within the "refs/" namespace are currently supported by multiple commands like git-for-each-ref(1), git-show-ref(1). Neither support printing all the operational refs within the repository.

This is crucial because with the reftable backend, all these refs will also move to reftable. It would be necessary to identify all the refs that are stored within the reftable since there is no easy way to do so otherwise. This is because the reftable itself is a binary format and all access will be via git. Unlike the filesystem backend, which allows access directly via the filesystem.

This commit adds the necessary code to iterate over operational refs present in a repository and provides a new filter flag 'FILTER_REFS_OPERATIONAL' to iterate over operational refs.

This flag can now be used to extend existing git commands to print operational refs.

Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 ref-filter.c | 12 ++++++++++++
 ref-filter.h |  4 +++-
 refs.c       | 14 ++++++++++++++
 refs.h       |  3 +++
 4 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/ref-filter.c b/ref-filter.c
index fdaabb5bb4..307a512c27 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2756,6 +2756,10 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname)
 	    filter->kind == FILTER_REFS_REMOTES ||
 	    filter->kind == FILTER_REFS_TAGS)
 		return filter->kind;
+
+	if (filter->kind & FILTER_REFS_OPERATIONAL)
+		return filter->kind;
+
 	return ref_kind_from_refname(refname);
 }
 
@@ -3032,6 +3036,14 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref
 	if (!filter->kind)
 		die("filter_refs: invalid type");
 	else {
+		size_t i;
+		if (filter->kind & FILTER_REFS_OPERATIONAL) {
+			for (i = 0; i < operational_refs_max; i++) {
+				refs_single_ref(get_main_ref_store(the_repository),
+								operational_refs[i], fn, cb_data);
+			}
+		}
+
 		/*
 		 * For common cases where we need only branches or remotes or tags,
 		 * we only iterate through those refs. If a mix of refs is needed,
diff --git a/ref-filter.h b/ref-filter.h
index 0ce5af58ab..eec1d29514 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -23,7 +23,9 @@
 #define FILTER_REFS_ALL            (FILTER_REFS_TAGS | FILTER_REFS_BRANCHES | \
 				    FILTER_REFS_REMOTES | FILTER_REFS_OTHERS)
 #define FILTER_REFS_DETACHED_HEAD  0x0020
-#define FILTER_REFS_KIND_MASK      (FILTER_REFS_ALL | FILTER_REFS_DETACHED_HEAD)
+#define FILTER_REFS_OPERATIONAL    0x0040
+#define FILTER_REFS_KIND_MASK      (FILTER_REFS_ALL | FILTER_REFS_DETACHED_HEAD | \
+				    FILTER_REFS_OPERATIONAL)
 
 struct atom_value;
 struct ref_sorting;
diff --git a/refs.c b/refs.c
index cebc5458d3..70f6854301 100644
--- a/refs.c
+++ b/refs.c
@@ -82,6 +82,20 @@ static unsigned char refname_disposition[256] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
 };
 
+const char *operational_refs[] = {
+	"HEAD",
+	"ORIG_HEAD",
+	"REBASE_HEAD",
+	"REVERT_HEAD",
+	"CHERRY_PICK_HEAD",
+	"BISECT_HEAD",
+	"BISECT_EXPECTED_REV",
+	"NOTES_MERGE_PARTIAL",
+	"NOTES_MERGE_REF",
+};
+
+const int operational_refs_max = ARRAY_SIZE(operational_refs) - 1;
+
 struct ref_namespace_info ref_namespace[] = {
 	[NAMESPACE_HEAD] = {
 		.ref = "HEAD",
diff --git a/refs.h b/refs.h
index e147f13a85..b01938a91a 100644
--- a/refs.h
+++ b/refs.h
@@ -15,6 +15,9 @@ int default_ref_storage_format(void);
 int ref_storage_format_by_name(const char *name);
 const char *ref_storage_format_to_name(int ref_storage_format);
 
+extern const char *operational_refs[];
+extern const int operational_refs_max;
+
 /*
  * Resolve a reference, recursively following symbolic refererences.
  *
-- 
2.43.GIT
Previous: Karthik NayakNext: Junio C Hamano
Message 3 of 27 in “[RFC 0/2] Initial changes to support printing all refs”
  1. Karthik NayakDec 21, 2023
  2. 1/2 refs: introduce the `refs_single_ref` functionKarthik Nayak, Dec 21, 2023
  3. 2/2 ref-filter: support filtering of operational refsKarthik Nayak, Dec 21, 2023
  4. Junio C HamanoDec 21, 2023
  5. Karthik NayakDec 22, 2023
  6. Junio C HamanoDec 26, 2023
  7. Karthik NayakJan 2, 2024
  8. Junio C HamanoJan 2, 2024
  9. Taylor BlauJan 2, 2024
  10. Patrick SteinhardtJan 3, 2024
  11. Karthik NayakJan 3, 2024
  12. Junio C HamanoJan 3, 2024
  13. Patrick SteinhardtJan 3, 2024
  14. Junio C HamanoJan 3, 2024
  15. Patrick SteinhardtJan 3, 2024
  16. Junio C HamanoJan 3, 2024
  17. Patrick SteinhardtJan 3, 2024
  18. Junio C HamanoJan 3, 2024
  19. Patrick SteinhardtJan 3, 2024
  20. Karthik NayakJan 4, 2024
  21. Junio C HamanoJan 4, 2024
  22. Taylor BlauJan 3, 2024
  23. Patrick SteinhardtJan 3, 2024
  24. Taylor BlauJan 3, 2024
  25. Patrick SteinhardtDec 28, 2023
  26. Karthik NayakJan 2, 2024
  27. Taylor BlauJan 2, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.