@@ -2632,15 +2632,18 @@ static struct ref_array_item *new_ref_array_item(const char *refname,
2632
2632
return ref ;
2633
2633
}
2634
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
+
2635
2641
struct ref_array_item * ref_array_push (struct ref_array * array ,
2636
2642
const char * refname ,
2637
2643
const struct object_id * oid )
2638
2644
{
2639
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 );
2644
2647
return ref ;
2645
2648
}
2646
2649
@@ -2677,46 +2680,36 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname)
2677
2680
return ref_kind_from_refname (refname );
2678
2681
}
2679
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 )
2690
2685
{
2691
- struct ref_filter_cbdata * ref_cbdata = cb_data ;
2692
- struct ref_filter * filter = ref_cbdata -> filter ;
2693
2686
struct ref_array_item * ref ;
2694
2687
struct commit * commit = NULL ;
2695
2688
unsigned int kind ;
2696
2689
2697
2690
if (flag & REF_BAD_NAME ) {
2698
2691
warning (_ ("ignoring ref with broken name %s" ), refname );
2699
- return 0 ;
2692
+ return NULL ;
2700
2693
}
2701
2694
2702
2695
if (flag & REF_ISBROKEN ) {
2703
2696
warning (_ ("ignoring broken ref %s" ), refname );
2704
- return 0 ;
2697
+ return NULL ;
2705
2698
}
2706
2699
2707
2700
/* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */
2708
2701
kind = filter_ref_kind (filter , refname );
2709
2702
if (!(kind & filter -> kind ))
2710
- return 0 ;
2703
+ return NULL ;
2711
2704
2712
2705
if (!filter_pattern_match (filter , refname ))
2713
- return 0 ;
2706
+ return NULL ;
2714
2707
2715
2708
if (filter_exclude_match (filter , refname ))
2716
- return 0 ;
2709
+ return NULL ;
2717
2710
2718
2711
if (filter -> points_at .nr && !match_points_at (& filter -> points_at , oid , refname ))
2719
- return 0 ;
2712
+ return NULL ;
2720
2713
2721
2714
/*
2722
2715
* A merge filter is applied on refs pointing to commits. Hence
@@ -2727,27 +2720,48 @@ static int filter_one(const char *refname, const struct object_id *oid, int flag
2727
2720
filter -> with_commit || filter -> no_commit || filter -> verbose ) {
2728
2721
commit = lookup_commit_reference_gently (the_repository , oid , 1 );
2729
2722
if (!commit )
2730
- return 0 ;
2723
+ return NULL ;
2731
2724
/* We perform the filtering for the '--contains' option... */
2732
2725
if (filter -> with_commit &&
2733
2726
!commit_contains (filter , commit , filter -> with_commit , & filter -> internal .contains_cache ))
2734
- return 0 ;
2727
+ return NULL ;
2735
2728
/* ...or for the `--no-contains' option */
2736
2729
if (filter -> no_commit &&
2737
2730
commit_contains (filter , commit , filter -> no_commit , & filter -> internal .no_contains_cache ))
2738
- return 0 ;
2731
+ return NULL ;
2739
2732
}
2740
2733
2741
2734
/*
2742
2735
* We do not open the object yet; sort may only need refname
2743
2736
* to do its job and the resulting list may yet to be pruned
2744
2737
* by maxcount logic.
2745
2738
*/
2746
- ref = ref_array_push ( ref_cbdata -> array , refname , oid );
2739
+ ref = new_ref_array_item ( refname , oid );
2747
2740
ref -> commit = commit ;
2748
2741
ref -> flag = flag ;
2749
2742
ref -> kind = kind ;
2750
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
+
2751
2765
return 0 ;
2752
2766
}
2753
2767
@@ -2883,26 +2897,12 @@ void filter_ahead_behind(struct repository *r,
2883
2897
free (commits );
2884
2898
}
2885
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 )
2893
2901
{
2894
- struct ref_filter_cbdata ref_cbdata ;
2895
- int save_commit_buffer_orig ;
2896
2902
int ret = 0 ;
2897
2903
2898
- ref_cbdata .array = array ;
2899
- ref_cbdata .filter = filter ;
2900
-
2901
2904
filter -> kind = type & FILTER_REFS_KIND_MASK ;
2902
2905
2903
- save_commit_buffer_orig = save_commit_buffer ;
2904
- save_commit_buffer = 0 ;
2905
-
2906
2906
init_contains_cache (& filter -> internal .contains_cache );
2907
2907
init_contains_cache (& filter -> internal .no_contains_cache );
2908
2908
@@ -2917,20 +2917,43 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int
2917
2917
* of filter_ref_kind().
2918
2918
*/
2919
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
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
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
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
2927
if (!ret && (filter -> kind & FILTER_REFS_DETACHED_HEAD ))
2928
- head_ref (filter_one , & ref_cbdata );
2928
+ head_ref (fn , cb_data );
2929
2929
}
2930
2930
2931
2931
clear_contains_cache (& filter -> internal .contains_cache );
2932
2932
clear_contains_cache (& filter -> internal .no_contains_cache );
2933
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
+
2934
2957
/* Filters that need revision walking */
2935
2958
reach_filter (array , & filter -> reachable_from , INCLUDE_REACHED );
2936
2959
reach_filter (array , & filter -> unreachable_from , EXCLUDE_REACHED );
0 commit comments