]> git.ipfire.org Git - thirdparty/git.git/commitdiff
ref-filter.c: refactor to create common helper functions
authorVictoria Dye <vdye@github.com>
Tue, 14 Nov 2023 19:53:54 +0000 (19:53 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Nov 2023 05:03:00 +0000 (14:03 +0900)
Factor out parts of 'ref_array_push()', 'ref_filter_handler()', and
'filter_refs()' into new helper functions:

* Extract the code to grow a 'struct ref_array' and append a given 'struct
  ref_array_item *' to it from 'ref_array_push()' into 'ref_array_append()'.
* Extract the code to filter a given ref by refname & object ID then create
  a new 'struct ref_array_item *' from 'filter_one()' into
  'apply_ref_filter()'.
* Extract the code for filter pre-processing, contains cache creation, and
  ref iteration from 'filter_refs()' into 'do_filter_refs()'.

In later patches, these helpers will be used by new ref-filter API
functions. This patch does not result in any user-facing behavior changes or
changes to callers outside of 'ref-filter.c'.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
ref-filter.c

index 02a852bb348ebbc55fbd5420a1272f1a64b09443..8bfdc66e447212488c1de2469ad7af644b7efa93 100644 (file)
@@ -2632,15 +2632,18 @@ static struct ref_array_item *new_ref_array_item(const char *refname,
        return ref;
 }
 
+static void ref_array_append(struct ref_array *array, struct ref_array_item *ref)
+{
+       ALLOC_GROW(array->items, array->nr + 1, array->alloc);
+       array->items[array->nr++] = ref;
+}
+
 struct ref_array_item *ref_array_push(struct ref_array *array,
                                      const char *refname,
                                      const struct object_id *oid)
 {
        struct ref_array_item *ref = new_ref_array_item(refname, oid);
-
-       ALLOC_GROW(array->items, array->nr + 1, array->alloc);
-       array->items[array->nr++] = ref;
-
+       ref_array_append(array, ref);
        return ref;
 }
 
@@ -2677,46 +2680,36 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname)
        return ref_kind_from_refname(refname);
 }
 
-struct ref_filter_cbdata {
-       struct ref_array *array;
-       struct ref_filter *filter;
-};
-
-/*
- * A call-back given to for_each_ref().  Filter refs and keep them for
- * later object processing.
- */
-static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data)
+static struct ref_array_item *apply_ref_filter(const char *refname, const struct object_id *oid,
+                           int flag, struct ref_filter *filter)
 {
-       struct ref_filter_cbdata *ref_cbdata = cb_data;
-       struct ref_filter *filter = ref_cbdata->filter;
        struct ref_array_item *ref;
        struct commit *commit = NULL;
        unsigned int kind;
 
        if (flag & REF_BAD_NAME) {
                warning(_("ignoring ref with broken name %s"), refname);
-               return 0;
+               return NULL;
        }
 
        if (flag & REF_ISBROKEN) {
                warning(_("ignoring broken ref %s"), refname);
-               return 0;
+               return NULL;
        }
 
        /* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */
        kind = filter_ref_kind(filter, refname);
        if (!(kind & filter->kind))
-               return 0;
+               return NULL;
 
        if (!filter_pattern_match(filter, refname))
-               return 0;
+               return NULL;
 
        if (filter_exclude_match(filter, refname))
-               return 0;
+               return NULL;
 
        if (filter->points_at.nr && !match_points_at(&filter->points_at, oid, refname))
-               return 0;
+               return NULL;
 
        /*
         * A merge filter is applied on refs pointing to commits. Hence
@@ -2727,15 +2720,15 @@ static int filter_one(const char *refname, const struct object_id *oid, int flag
            filter->with_commit || filter->no_commit || filter->verbose) {
                commit = lookup_commit_reference_gently(the_repository, oid, 1);
                if (!commit)
-                       return 0;
+                       return NULL;
                /* We perform the filtering for the '--contains' option... */
                if (filter->with_commit &&
                    !commit_contains(filter, commit, filter->with_commit, &filter->internal.contains_cache))
-                       return 0;
+                       return NULL;
                /* ...or for the `--no-contains' option */
                if (filter->no_commit &&
                    commit_contains(filter, commit, filter->no_commit, &filter->internal.no_contains_cache))
-                       return 0;
+                       return NULL;
        }
 
        /*
@@ -2743,11 +2736,32 @@ static int filter_one(const char *refname, const struct object_id *oid, int flag
         * to do its job and the resulting list may yet to be pruned
         * by maxcount logic.
         */
-       ref = ref_array_push(ref_cbdata->array, refname, oid);
+       ref = new_ref_array_item(refname, oid);
        ref->commit = commit;
        ref->flag = flag;
        ref->kind = kind;
 
+       return ref;
+}
+
+struct ref_filter_cbdata {
+       struct ref_array *array;
+       struct ref_filter *filter;
+};
+
+/*
+ * A call-back given to for_each_ref().  Filter refs and keep them for
+ * later object processing.
+ */
+static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data)
+{
+       struct ref_filter_cbdata *ref_cbdata = cb_data;
+       struct ref_array_item *ref;
+
+       ref = apply_ref_filter(refname, oid, flag, ref_cbdata->filter);
+       if (ref)
+               ref_array_append(ref_cbdata->array, ref);
+
        return 0;
 }
 
@@ -2883,26 +2897,12 @@ void filter_ahead_behind(struct repository *r,
        free(commits);
 }
 
-/*
- * 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)
+static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref_fn fn, void *cb_data)
 {
-       struct ref_filter_cbdata ref_cbdata;
-       int save_commit_buffer_orig;
        int ret = 0;
 
-       ref_cbdata.array = array;
-       ref_cbdata.filter = filter;
-
        filter->kind = type & FILTER_REFS_KIND_MASK;
 
-       save_commit_buffer_orig = save_commit_buffer;
-       save_commit_buffer = 0;
-
        init_contains_cache(&filter->internal.contains_cache);
        init_contains_cache(&filter->internal.no_contains_cache);
 
@@ -2917,20 +2917,43 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int
                 * of filter_ref_kind().
                 */
                if (filter->kind == FILTER_REFS_BRANCHES)
-                       ret = for_each_fullref_in("refs/heads/", filter_one, &ref_cbdata);
+                       ret = for_each_fullref_in("refs/heads/", fn, cb_data);
                else if (filter->kind == FILTER_REFS_REMOTES)
-                       ret = for_each_fullref_in("refs/remotes/", filter_one, &ref_cbdata);
+                       ret = for_each_fullref_in("refs/remotes/", fn, cb_data);
                else if (filter->kind == FILTER_REFS_TAGS)
-                       ret = for_each_fullref_in("refs/tags/", filter_one, &ref_cbdata);
+                       ret = for_each_fullref_in("refs/tags/", fn, cb_data);
                else if (filter->kind & FILTER_REFS_ALL)
-                       ret = for_each_fullref_in_pattern(filter, filter_one, &ref_cbdata);
+                       ret = for_each_fullref_in_pattern(filter, fn, cb_data);
                if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD))
-                       head_ref(filter_one, &ref_cbdata);
+                       head_ref(fn, cb_data);
        }
 
        clear_contains_cache(&filter->internal.contains_cache);
        clear_contains_cache(&filter->internal.no_contains_cache);
 
+       return ret;
+}
+
+/*
+ * 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;
+       int save_commit_buffer_orig;
+       int ret = 0;
+
+       ref_cbdata.array = array;
+       ref_cbdata.filter = filter;
+
+       save_commit_buffer_orig = save_commit_buffer;
+       save_commit_buffer = 0;
+
+       ret = do_filter_refs(filter, type, filter_one, &ref_cbdata);
+
        /*  Filters that need revision walking */
        reach_filter(array, &filter->reachable_from, INCLUDE_REACHED);
        reach_filter(array, &filter->unreachable_from, EXCLUDE_REACHED);