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@xxxxxxxxx> Mentored-by: Matthieu Moy <matthieu.moy@xxxxxxxxxxxxxxx> Signed-off-by: Karthik Nayak <karthik.188@xxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html