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

[PATCH 2/4] ref-filter: add ref-filter API

From
Karthik Nayak <karthik.188@gmail.com>
Date
May 20, 2015, 13:18 UTC
Message-ID
<1432127904-21070-2-git-send-email-karthik.188@gmail.com>
In-Reply-To
<555C88C2.8060902@gmail.com>

add a ref-filter API to provide functions to filter refs for listing. This will act as a common library for commands like 'tag -l', 'branch -l' and 'for-each-ref'. ref-filter will enable each of these commands to benefit from the features of the others.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 Makefile     |  1 +
 ref-filter.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ref-filter.h | 47 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 ref-filter.c
 create mode 100644 ref-filter.h
diff --git a/Makefile b/Makefile
index 5f3987f..1e03bda 100644
--- a/Makefile
+++ b/Makefile
@@ -759,6 +759,7 @@ LIB_OBJS += reachable.o
 LIB_OBJS += read-cache.o
 LIB_OBJS += reflog-walk.o
 LIB_OBJS += refs.o
+LIB_OBJS += ref-filter.o
 LIB_OBJS += remote.o
 LIB_OBJS += replace_object.o
 LIB_OBJS += rerere.o
diff --git a/ref-filter.c b/ref-filter.c
new file mode 100644
index 0000000..df571a6
--- /dev/null
+++ b/ref-filter.c
@@ -0,0 +1,73 @@
+#include "builtin.h"
+#include "cache.h"
+#include "refs.h"
+#include "ref-filter.h"
+#include "wildmatch.h"
+#include "commit.h"
+
+static int match_name_as_path(const char **pattern, const char *refname)
+{
+	int namelen = strlen(refname);
+	for (; *pattern; pattern++) {
+		const char *p = *pattern;
+		int plen = strlen(p);
+
+		if ((plen <= namelen) &&
+		    !strncmp(refname, p, plen) &&
+		    (refname[plen] == '\0' ||
+		     refname[plen] == '/' ||
+		     p[plen-1] == '/'))
+			return 1;
+		if (!wildmatch(p, refname, WM_PATHNAME, NULL))
+			return 1;
+	}
+	return 0;
+}
+
+static struct ref_filter_item *new_ref_filter_item(const char *refname,
+						   const unsigned char *sha1,
+						   int flag)
+{
+	struct ref_filter_item *ref =  xcalloc(1, sizeof(struct ref_filter_item));
+	ref->name = xstrdup(refname);
+	hashcpy(ref->sha1, sha1);
+	ref->flags = flag;
+
+	return ref;
+}
+
+/*
+ * A call-back given to for_each_ref().  Filter refs and keep them for
+ * later object processing.
+ */
+int ref_filter_add(const char *refname, const unsigned char *sha1, int flag, void *data)
+{
+	struct ref_filter *ref_list = data;
+	struct ref_filter_item *ref;
+
+	if (flag & REF_BAD_NAME) {
+		warning("ignoring ref with broken name %s", refname);
+		return 0;
+	}
+
+	if (*ref_list->name_patterns && !match_name_as_path(ref_list->name_patterns, refname))
+		return 0;
+
+	ref = new_ref_filter_item(refname, sha1, flag);
+
+	REALLOC_ARRAY(ref_list->items, ref_list->count + 1);
+	ref_list->items[ref_list->count++] = ref;
+
+	return 0;
+}
+
+void ref_filter_clear(struct ref_filter *refs)
+{
+	int i;
+
+	for (i = 0; i < refs->count; i++)
+		free(refs->items[i]);
+	free(refs->items);
+	refs->items = NULL;
+	refs->count = refs->alloc = 0;
+}
diff --git a/ref-filter.h b/ref-filter.h
new file mode 100644
index 0000000..3010d13
--- /dev/null
+++ b/ref-filter.h
@@ -0,0 +1,47 @@
+#ifndef REF_FILTER_H
+#define REF_FILTER_H
+
+#include "sha1-array.h"
+#include "refs.h"
+#include "commit.h"
+
+/*
+ * ref-filter is meant to act as a common provider of API's for
+ * 'tag -l', 'branch -l' and 'for-each-ref'. ref-filter is the attempt
+ * at unification of these three commands so that they ay benefit from
+ * the functionality of each other.
+ */
+
+/* An atom is a valid field atom used for sorting and formatting of refs.*/
+struct atom_value {
+	const char *s;
+	unsigned long ul; /* used for sorting when not FIELD_STR */
+};
+
+struct ref_sort {
+	struct ref_sort *next;
+	int atom; /* index into used_atom array */
+	unsigned reverse : 1;
+};
+
+/* ref_filter_item will hold the data pertaining to a particular ref. */
+struct ref_filter_item {
+	unsigned char sha1[20];
+	int flags;
+	const char *symref;
+	struct atom_value *value;
+	char *name;
+};
+
+/*  ref_filter will hold data pertaining to a list of refs. */
+struct ref_filter {
+	int count, alloc;
+	struct ref_filter_item **items;
+	const char **name_patterns;
+};
+
+/*  ref_filter_add is used to add refs to the ref_filter list. */
+int ref_filter_add(const char *refname, const unsigned char *sha1, int flags, void *data);
+void ref_filter_clear(struct ref_filter *refs);
+
+#endif /*  REF_FILTER_H  */
-- 
2.4.1
Previous: karthik nayakNext: Eric Sunshine
Message 5 of 24 in “Unifying git branch -l, git tag -l, and git for-each-ref”
  1. karthik nayakMay 20, 2015
  2. 1/4 for-each-ref: rename refinfo members to match similar structuresKarthik Nayak, May 20, 2015
  3. Matthieu MoyMay 20, 2015
  4. karthik nayakMay 21, 2015
  5. 2/4 ref-filter: add ref-filter APIKarthik Nayak, May 20, 2015
  6. Eric SunshineMay 20, 2015
  7. karthik nayakMay 21, 2015
  8. Eric SunshineMay 21, 2015
  9. karthik nayakMay 22, 2015
  10. Matthieu MoyMay 21, 2015
  11. karthik nayakMay 21, 2015
  12. karthik nayakMay 21, 2015
  13. Matthieu MoyMay 22, 2015
  14. karthik nayakMay 22, 2015
  15. Matthieu MoyMay 23, 2015
  16. Christian CouderMay 23, 2015
  17. Matthieu MoyMay 23, 2015
  18. Junio C HamanoMay 23, 2015
  19. Matthieu MoyMay 23, 2015
  20. Karthik NayakMay 23, 2015
  21. 3/4 for-each-ref: convert to ref-filterKarthik Nayak, May 20, 2015
  22. Junio C HamanoMay 20, 2015
  23. karthik nayakMay 21, 2015
  24. 4/4 ref-filter: move formatting/sorting options from 'for-each-ref'Karthik Nayak, May 20, 2015

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.