@@ -157,19 +157,15 @@ static void diffcore_pickaxe_grep(struct diff_options *o)
157157 return ;
158158}
159159
160- static unsigned int contains (struct diff_filespec * one , struct diff_options * o ,
160+ static unsigned int contains (mmfile_t * mf , struct diff_options * o ,
161161 regex_t * regexp , kwset_t kws )
162162{
163163 unsigned int cnt ;
164164 unsigned long sz ;
165165 const char * data ;
166- if (!o -> pickaxe [0 ])
167- return 0 ;
168- if (diff_populate_filespec (one , 0 ))
169- return 0 ;
170166
171- sz = one -> size ;
172- data = one -> data ;
167+ sz = mf -> size ;
168+ data = mf -> ptr ;
173169 cnt = 0 ;
174170
175171 if (regexp ) {
@@ -199,26 +195,53 @@ static unsigned int contains(struct diff_filespec *one, struct diff_options *o,
199195 cnt ++ ;
200196 }
201197 }
202- diff_free_filespec_data (one );
203198 return cnt ;
204199}
205200
206201static int has_changes (struct diff_filepair * p , struct diff_options * o ,
207202 regex_t * regexp , kwset_t kws )
208203{
209- if (!DIFF_FILE_VALID (p -> one )) {
210- if (!DIFF_FILE_VALID (p -> two ))
211- return 0 ; /* ignore unmerged */
204+ struct userdiff_driver * textconv_one = get_textconv (p -> one );
205+ struct userdiff_driver * textconv_two = get_textconv (p -> two );
206+ mmfile_t mf1 , mf2 ;
207+ int ret ;
208+
209+ if (!o -> pickaxe [0 ])
210+ return 0 ;
211+
212+ /*
213+ * If we have an unmodified pair, we know that the count will be the
214+ * same and don't even have to load the blobs. Unless textconv is in
215+ * play, _and_ we are using two different textconv filters (e.g.,
216+ * because a pair is an exact rename with different textconv attributes
217+ * for each side, which might generate different content).
218+ */
219+ if (textconv_one == textconv_two && diff_unmodified_pair (p ))
220+ return 0 ;
221+
222+ fill_one (p -> one , & mf1 , & textconv_one );
223+ fill_one (p -> two , & mf2 , & textconv_two );
224+
225+ if (!mf1 .ptr ) {
226+ if (!mf2 .ptr )
227+ ret = 0 ; /* ignore unmerged */
212228 /* created */
213- return contains (p -> two , o , regexp , kws ) != 0 ;
214- }
215- if (!DIFF_FILE_VALID (p -> two ))
216- return contains (p -> one , o , regexp , kws ) != 0 ;
217- if (!diff_unmodified_pair (p )) {
218- return contains (p -> one , o , regexp , kws ) !=
219- contains (p -> two , o , regexp , kws );
229+ ret = contains (& mf2 , o , regexp , kws ) != 0 ;
220230 }
221- return 0 ;
231+ else if (!mf2 .ptr ) /* removed */
232+ ret = contains (& mf1 , o , regexp , kws ) != 0 ;
233+ else
234+ ret = contains (& mf1 , o , regexp , kws ) !=
235+ contains (& mf2 , o , regexp , kws );
236+
237+ if (textconv_one )
238+ free (mf1 .ptr );
239+ if (textconv_two )
240+ free (mf2 .ptr );
241+ diff_free_filespec_data (p -> one );
242+ diff_free_filespec_data (p -> two );
243+
244+ return ret ;
222245}
223246
224247static void diffcore_pickaxe_count (struct diff_options * o )
0 commit comments