2632
return ref;
2633
}
2634
2635
+static void ref_array_append(struct ref_array *array, struct ref_array_item *ref)
2636
+{
2637
+ ALLOC_GROW(array->items, array->nr + 1, array->alloc);
2638
+ array->items[array->nr++] = ref;
2639
+}
2640
+
2641
struct ref_array_item *ref_array_push(struct ref_array *array,
2642
const char *refname,
2643
const struct object_id *oid)
2644
{
2645
struct ref_array_item *ref = new_ref_array_item(refname, oid);
2640
-
2641
- ALLOC_GROW(array->items, array->nr + 1, array->alloc);
2642
- array->items[array->nr++] = ref;
2643
-
2646
+ ref_array_append(array, ref);
2647
return ref;
2648
}
2649
2680
return ref_kind_from_refname(refname);
2681
}
2682
2680
-struct ref_filter_cbdata {
2681
- struct ref_array *array;
2682
- struct ref_filter *filter;
2683
-};
2684
-
2685
-/*
2686
- * A call-back given to for_each_ref(). Filter refs and keep them for
2687
- * later object processing.
2688
- */
2689
-static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data)
2683
+static struct ref_array_item *apply_ref_filter(const char *refname, const struct object_id *oid,
2684
+ int flag, struct ref_filter *filter)
2685
{
2691
- struct ref_filter_cbdata *ref_cbdata = cb_data;
2692
- struct ref_filter *filter = ref_cbdata->filter;
2686
struct ref_array_item *ref;
2687
struct commit *commit = NULL;
2688
unsigned int kind;
2689
2690
if (flag & REF_BAD_NAME) {
2691
warning(_("ignoring ref with broken name %s"), refname);
2699
- return 0;
2692
+ return NULL;
2693
}
2694
2695
if (flag & REF_ISBROKEN) {
2696
warning(_("ignoring broken ref %s"), refname);
2704
- return 0;
2697
+ return NULL;
2698
}
2699
2700
/* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */
2701
kind = filter_ref_kind(filter, refname);
2702
if (!(kind & filter->kind))
2710
- return 0;
2703
+ return NULL;
2704
2705
if (!filter_pattern_match(filter, refname))
2713
- return 0;
2706
+ return NULL;
2707
2708
if (filter_exclude_match(filter, refname))
2716
- return 0;
2709
+ return NULL;
2710
2711
if (filter->points_at.nr && !match_points_at(&filter->points_at, oid, refname))
2719
- return 0;
2712
+ return NULL;
2713
2714
/*
2715
* A merge filter is applied on refs pointing to commits. Hence
2720
filter->with_commit || filter->no_commit || filter->verbose) {
2721
commit = lookup_commit_reference_gently(the_repository, oid, 1);
2722
if (!commit)
2730
- return 0;
2723
+ return NULL;
2724
/* We perform the filtering for the '--contains' option... */
2725
if (filter->with_commit &&
2726
!commit_contains(filter, commit, filter->with_commit, &filter->internal.contains_cache))
2734
- return 0;
2727
+ return NULL;
2728
/* ...or for the `--no-contains' option */
2729
if (filter->no_commit &&
2730
commit_contains(filter, commit, filter->no_commit, &filter->internal.no_contains_cache))
2738
- return 0;
2731
+ return NULL;
2732
}
2733
2734
/*
2736
* to do its job and the resulting list may yet to be pruned
2737
* by maxcount logic.
2738
*/
2746
- ref = ref_array_push(ref_cbdata->array, refname, oid);
2739
+ ref = new_ref_array_item(refname, oid);
2740
ref->commit = commit;
2741
ref->flag = flag;
2742
ref->kind = kind;
2743
2744
+ return ref;
2745
+}
2746
+
2747
+struct ref_filter_cbdata {
2748
+ struct ref_array *array;
2749
+ struct ref_filter *filter;
2750
+};
2751
+
2752
+/*
2753
+ * A call-back given to for_each_ref(). Filter refs and keep them for
2754
+ * later object processing.
2755
+ */
2756
+static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data)
2757
+{
2758
+ struct ref_filter_cbdata *ref_cbdata = cb_data;
2759
+ struct ref_array_item *ref;
2760
+
2761
+ ref = apply_ref_filter(refname, oid, flag, ref_cbdata->filter);
2762
+ if (ref)
2763
+ ref_array_append(ref_cbdata->array, ref);
2764
+
2765
return 0;
2766
}
2767
2897
free(commits);
2898
}
2899
2886
-/*
2887
- * API for filtering a set of refs. Based on the type of refs the user
2888
- * has requested, we iterate through those refs and apply filters
2889
- * as per the given ref_filter structure and finally store the
2890
- * filtered refs in the ref_array structure.
2891
- */
2892
-int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type)
2900
+static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref_fn fn, void *cb_data)
2901
{
2894
- struct ref_filter_cbdata ref_cbdata;
2895
- int save_commit_buffer_orig;
2902
int ret = 0;
2903
2898
- ref_cbdata.array = array;
2899
- ref_cbdata.filter = filter;
2900
-
2904
filter->kind = type & FILTER_REFS_KIND_MASK;
2905
2903
- save_commit_buffer_orig = save_commit_buffer;
2904
- save_commit_buffer = 0;
2905
-
2906
init_contains_cache(&filter->internal.contains_cache);
2907
init_contains_cache(&filter->internal.no_contains_cache);
2908
2917
* of filter_ref_kind().
2918
*/
2919
if (filter->kind == FILTER_REFS_BRANCHES)
2920
- ret = for_each_fullref_in("refs/heads/", filter_one, &ref_cbdata);
2920
+ ret = for_each_fullref_in("refs/heads/", fn, cb_data);
2921
else if (filter->kind == FILTER_REFS_REMOTES)
2922
- ret = for_each_fullref_in("refs/remotes/", filter_one, &ref_cbdata);
2922
+ ret = for_each_fullref_in("refs/remotes/", fn, cb_data);
2923
else if (filter->kind == FILTER_REFS_TAGS)
2924
- ret = for_each_fullref_in("refs/tags/", filter_one, &ref_cbdata);
2924
+ ret = for_each_fullref_in("refs/tags/", fn, cb_data);
2925
else if (filter->kind & FILTER_REFS_ALL)
2926
- ret = for_each_fullref_in_pattern(filter, filter_one, &ref_cbdata);
2926
+ ret = for_each_fullref_in_pattern(filter, fn, cb_data);
2927
if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD))
2928
- head_ref(filter_one, &ref_cbdata);
2928
+ head_ref(fn, cb_data);
2929
}
2930
2931
clear_contains_cache(&filter->internal.contains_cache);
2932
clear_contains_cache(&filter->internal.no_contains_cache);
2933
2934
+ return ret;
2935
+}
2936
+
2937
+/*
2938
+ * API for filtering a set of refs. Based on the type of refs the user
2939
+ * has requested, we iterate through those refs and apply filters
2940
+ * as per the given ref_filter structure and finally store the
2941
+ * filtered refs in the ref_array structure.
2942
+ */
2943
+int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type)
2944
+{
2945
+ struct ref_filter_cbdata ref_cbdata;
2946
+ int save_commit_buffer_orig;
2947
+ int ret = 0;
2948
+
2949
+ ref_cbdata.array = array;
2950
+ ref_cbdata.filter = filter;
2951
+
2952
+ save_commit_buffer_orig = save_commit_buffer;
2953
+ save_commit_buffer = 0;
2954
+
2955
+ ret = do_filter_refs(filter, type, filter_one, &ref_cbdata);
2956
+
2957
/* Filters that need revision walking */
2958
reach_filter(array, &filter->reachable_from, INCLUDE_REACHED);
2959
reach_filter(array, &filter->unreachable_from, EXCLUDE_REACHED);