for-each-ref: introduce filter_refs()
authorKarthik Nayak <karthik.188@gmail.com>
Sat, 13 Jun 2015 19:37:28 +0000 (01:07 +0530)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 17:24:07 +0000 (10:24 -0700)
Introduce filter_refs() which will act as an API for filtering
a set of refs. Based on the type of refs the user has requested,
we iterate through those refs and apply filters as per the
given ref_filter structure and finally store the filtered refs
in the ref_array structure.

Currently this will wrap around ref_filter_handler(). Hence,
ref_filter_handler is made file scope static.

As users of this API will no longer send a ref_filter_cbdata
structure directly, we make the elements of ref_filter_cbdata
pointers. We can now use the information given by the users
to obtain our own ref_filter_cbdata structure. Changes are made to
support the change in ref_filter_cbdata structure.

Make 'for-each-ref' use this API.

Helped-by: Junio C Hamano <gitster@pobox.com>
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>
Reviewed-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/for-each-ref.c
ref-filter.c
ref-filter.h
index 637fc4ad9fe407eaea244ae94b9a5489235f0952..7919206187c9968cc974c10bb9b5f75c7574e630 100644 (file)
@@ -16,7 +16,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
        const char *format = "%(objectname) %(objecttype)\t%(refname)";
        struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
        int maxcount = 0, quote_style = 0;
-       struct ref_filter_cbdata ref_cbdata;
+       struct ref_array array;
+       struct ref_filter filter;
 
        struct option opts[] = {
                OPT_BIT('s', "shell", &quote_style,
@@ -54,16 +55,16 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
        /* for warn_ambiguous_refs */
        git_config(git_default_config, NULL);
 
-       memset(&ref_cbdata, 0, sizeof(ref_cbdata));
-       ref_cbdata.filter.name_patterns = argv;
-       for_each_rawref(ref_filter_handler, &ref_cbdata);
+       memset(&array, 0, sizeof(array));
+       memset(&filter, 0, sizeof(filter));
+       filter.name_patterns = argv;
+       filter_refs(&array, &filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN);
+       ref_array_sort(sorting, &array);
 
-       ref_array_sort(sorting, &ref_cbdata.array);
-
-       if (!maxcount || ref_cbdata.array.nr < maxcount)
-               maxcount = ref_cbdata.array.nr;
+       if (!maxcount || array.nr < maxcount)
+               maxcount = array.nr;
        for (i = 0; i < maxcount; i++)
-               show_ref_array_item(ref_cbdata.array.items[i], format, quote_style);
-       ref_array_clear(&ref_cbdata.array);
+               show_ref_array_item(array.items[i], format, quote_style);
+       ref_array_clear(&array);
        return 0;
 }
index cfc0e8a89249fbe2b16aa5f29c26355b206a81b8..7b39303810c0e059b8d740ce208f65820a960f82 100644 (file)
@@ -859,10 +859,10 @@ static struct ref_array_item *new_ref_array_item(const char *refname,
  * A call-back given to for_each_ref().  Filter refs and keep them for
  * later object processing.
  */
-int ref_filter_handler(const char *refname, const struct object_id *oid, int flag, void *cb_data)
+static int ref_filter_handler(const char *refname, const struct object_id *oid, int flag, void *cb_data)
 {
        struct ref_filter_cbdata *ref_cbdata = cb_data;
-       struct ref_filter *filter = &ref_cbdata->filter;
+       struct ref_filter *filter = ref_cbdata->filter;
        struct ref_array_item *ref;
 
        if (flag & REF_BAD_NAME) {
@@ -880,8 +880,8 @@ int ref_filter_handler(const char *refname, const struct object_id *oid, int fla
         */
        ref = new_ref_array_item(refname, oid->hash, flag);
 
-       REALLOC_ARRAY(ref_cbdata->array.items, ref_cbdata->array.nr + 1);
-       ref_cbdata->array.items[ref_cbdata->array.nr++] = ref;
+       REALLOC_ARRAY(ref_cbdata->array->items, ref_cbdata->array->nr + 1);
+       ref_cbdata->array->items[ref_cbdata->array->nr++] = ref;
        return 0;
 }
 
@@ -905,6 +905,28 @@ void ref_array_clear(struct ref_array *array)
        array->nr = array->alloc = 0;
 }
 
+/*
+ * API for filtering a set of refs. Based on the type of refs the user
+ * has requested, we iterate through those refs and apply filters
+ * as per the given ref_filter structure and finally store the
+ * filtered refs in the ref_array structure.
+ */
+int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type)
+{
+       struct ref_filter_cbdata ref_cbdata;
+
+       ref_cbdata.array = array;
+       ref_cbdata.filter = filter;
+
+       if (type & (FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN))
+               return for_each_rawref(ref_filter_handler, &ref_cbdata);
+       else if (type & FILTER_REFS_ALL)
+               return for_each_ref(ref_filter_handler, &ref_cbdata);
+       else
+               die("filter_refs: invalid type");
+       return 0;
+}
+
 static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b)
 {
        struct atom_value *va, *vb;
index 506ac8f3599af866da2437af2f245d046e981f42..697b609064c0ce7a3a9f52b8217acf6bdb8a3a40 100644 (file)
@@ -13,6 +13,9 @@
 #define QUOTE_PYTHON 4
 #define QUOTE_TCL 8
 
+#define FILTER_REFS_INCLUDE_BROKEN 0x1
+#define FILTER_REFS_ALL 0x2
+
 struct atom_value {
        const char *s;
        unsigned long ul; /* used for sorting when not FIELD_STR */
@@ -42,12 +45,17 @@ struct ref_filter {
 };
 
 struct ref_filter_cbdata {
-       struct ref_array array;
-       struct ref_filter filter;
+       struct ref_array *array;
+       struct ref_filter *filter;
 };
 
-/*  Callback function for for_each_*ref(). This filters the refs based on the filters set */
-int ref_filter_handler(const char *refname, const struct object_id *oid, int flag, void *cb_data);
+/*
+ * API for filtering a set of refs. Based on the type of refs the user
+ * has requested, we iterate through those refs and apply filters
+ * as per the given ref_filter structure and finally store the
+ * filtered refs in the ref_array structure.
+ */
+int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type);
 /*  Clear all memory allocated to ref_array */
 void ref_array_clear(struct ref_array *array);
 /*  Parse format string and sort specifiers */