@@ -93,6 +93,69 @@ static VALUE rb_git_tree_entrycount(VALUE self)
93
93
return INT2FIX (git_tree_entrycount (tree ));
94
94
}
95
95
96
+ struct rugged_treecount_cb_payload
97
+ {
98
+ int count ;
99
+ int limit ;
100
+ };
101
+
102
+ static int rugged__treecount_cb (const char * root , const git_tree_entry * entry , void * data )
103
+ {
104
+ struct rugged_treecount_cb_payload * payload = data ;
105
+
106
+ if (payload -> limit >= 0 && payload -> count >= payload -> limit ) {
107
+ return -1 ;
108
+ } else if (git_tree_entry_type (entry ) == GIT_OBJ_TREE ) {
109
+ return 0 ;
110
+ } else {
111
+ ++ (payload -> count );
112
+ return 1 ;
113
+ }
114
+ }
115
+
116
+ /*
117
+ * call-seq:
118
+ * tree.count_recursive(limit=nil) -> count
119
+ *
120
+ * `limit` - The maximum number of blobs to the count in the repository.
121
+ * Rugged will stop walking the tree after `limit` items to avoid long
122
+ * execution times.
123
+ *
124
+ * Return the number of blobs (up to the limit) contained in the tree and
125
+ * all subtrees.
126
+ */
127
+ static VALUE rb_git_tree_entrycount_recursive (int argc , VALUE * argv , VALUE self )
128
+ {
129
+ git_tree * tree ;
130
+ int error ;
131
+ struct rugged_treecount_cb_payload payload ;
132
+ VALUE rb_limit ;
133
+
134
+ Data_Get_Struct (self , git_tree , tree );
135
+
136
+ rb_scan_args (argc , argv , "01" , & rb_limit );
137
+
138
+ payload .limit = -1 ;
139
+ payload .count = 0 ;
140
+
141
+ if (!NIL_P (rb_limit )) {
142
+ Check_Type (rb_limit , T_FIXNUM );
143
+ payload .limit = FIX2INT (rb_limit );
144
+ }
145
+
146
+
147
+ error = git_tree_walk (tree , GIT_TREEWALK_PRE , & rugged__treecount_cb , (void * )& payload );
148
+
149
+ if (error && giterr_last ()-> klass == GITERR_CALLBACK ) {
150
+ giterr_clear ();
151
+ error = 0 ;
152
+ }
153
+
154
+ rugged_exception_check (error );
155
+
156
+ return INT2FIX (payload .count );
157
+ }
158
+
96
159
/*
97
160
* call-seq:
98
161
* tree[e] -> entry
@@ -813,6 +876,7 @@ void Init_rugged_tree(void)
813
876
*/
814
877
rb_cRuggedTree = rb_define_class_under (rb_mRugged , "Tree" , rb_cRuggedObject );
815
878
rb_define_method (rb_cRuggedTree , "count" , rb_git_tree_entrycount , 0 );
879
+ rb_define_method (rb_cRuggedTree , "count_recursive" , rb_git_tree_entrycount_recursive , -1 );
816
880
rb_define_method (rb_cRuggedTree , "length" , rb_git_tree_entrycount , 0 );
817
881
rb_define_method (rb_cRuggedTree , "get_entry" , rb_git_tree_get_entry , 1 );
818
882
rb_define_method (rb_cRuggedTree , "get_entry_by_oid" , rb_git_tree_get_entry_by_oid , 1 );
0 commit comments