@@ -2444,6 +2444,15 @@ static int fn_out_consume(void *priv, char *line, unsigned long len)
24442444 return 0 ;
24452445}
24462446
2447+ static int quick_consume (void * priv , char * line UNUSED , unsigned long len UNUSED )
2448+ {
2449+ struct emit_callback * ecbdata = priv ;
2450+ struct diff_options * o = ecbdata -> opt ;
2451+
2452+ o -> found_changes = 1 ;
2453+ return 1 ;
2454+ }
2455+
24472456static void pprint_rename (struct strbuf * name , const char * a , const char * b )
24482457{
24492458 const char * old_name = a ;
@@ -3759,8 +3768,21 @@ static void builtin_diff(const char *name_a,
37593768
37603769 if (o -> word_diff )
37613770 init_diff_words_data (& ecbdata , o , one , two );
3762- if (xdi_diff_outf (& mf1 , & mf2 , NULL , fn_out_consume ,
3763- & ecbdata , & xpp , & xecfg ))
3771+ if (o -> dry_run ) {
3772+ /*
3773+ * Unlike the !dry_run case, we need to ignore the
3774+ * return value from xdi_diff_outf() here, because
3775+ * xdi_diff_outf() takes non-zero return from its
3776+ * callback function as a sign of error and returns
3777+ * early (which is why we return non-zero from our
3778+ * callback, quick_consume()). Unfortunately,
3779+ * xdi_diff_outf() signals an error by returning
3780+ * non-zero.
3781+ */
3782+ xdi_diff_outf (& mf1 , & mf2 , NULL , quick_consume ,
3783+ & ecbdata , & xpp , & xecfg );
3784+ } else if (xdi_diff_outf (& mf1 , & mf2 , NULL , fn_out_consume ,
3785+ & ecbdata , & xpp , & xecfg ))
37643786 die ("unable to generate diff for %s" , one -> path );
37653787 if (o -> word_diff )
37663788 free_diff_words_data (& ecbdata );
@@ -6150,6 +6172,22 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
61506172 run_diff (p , o );
61516173}
61526174
6175+ /* return 1 if any change is found; otherwise, return 0 */
6176+ static int diff_flush_patch_quietly (struct diff_filepair * p , struct diff_options * o )
6177+ {
6178+ int saved_dry_run = o -> dry_run ;
6179+ int saved_found_changes = o -> found_changes ;
6180+ int ret ;
6181+
6182+ o -> dry_run = 1 ;
6183+ o -> found_changes = 0 ;
6184+ diff_flush_patch (p , o );
6185+ ret = o -> found_changes ;
6186+ o -> dry_run = saved_dry_run ;
6187+ o -> found_changes |= saved_found_changes ;
6188+ return ret ;
6189+ }
6190+
61536191static void diff_flush_stat (struct diff_filepair * p , struct diff_options * o ,
61546192 struct diffstat_t * diffstat )
61556193{
@@ -6778,8 +6816,15 @@ void diff_flush(struct diff_options *options)
67786816 DIFF_FORMAT_CHECKDIFF )) {
67796817 for (i = 0 ; i < q -> nr ; i ++ ) {
67806818 struct diff_filepair * p = q -> queue [i ];
6781- if (check_pair_status (p ))
6782- flush_one_pair (p , options );
6819+
6820+ if (!check_pair_status (p ))
6821+ continue ;
6822+
6823+ if (options -> flags .diff_from_contents &&
6824+ !diff_flush_patch_quietly (p , options ))
6825+ continue ;
6826+
6827+ flush_one_pair (p , options );
67836828 }
67846829 separator ++ ;
67856830 }
@@ -6831,19 +6876,10 @@ void diff_flush(struct diff_options *options)
68316876 if (output_format & DIFF_FORMAT_NO_OUTPUT &&
68326877 options -> flags .exit_with_status &&
68336878 options -> flags .diff_from_contents ) {
6834- /*
6835- * run diff_flush_patch for the exit status. setting
6836- * options->file to /dev/null should be safe, because we
6837- * aren't supposed to produce any output anyway.
6838- */
6839- diff_free_file (options );
6840- options -> file = xfopen ("/dev/null" , "w" );
6841- options -> close_file = 1 ;
6842- options -> color_moved = 0 ;
68436879 for (i = 0 ; i < q -> nr ; i ++ ) {
68446880 struct diff_filepair * p = q -> queue [i ];
68456881 if (check_pair_status (p ))
6846- diff_flush_patch (p , options );
6882+ diff_flush_patch_quietly (p , options );
68476883 if (options -> found_changes )
68486884 break ;
68496885 }
0 commit comments