@@ -2438,6 +2438,15 @@ static int fn_out_consume(void *priv, char *line, unsigned long len)
2438
2438
return 0 ;
2439
2439
}
2440
2440
2441
+ static int quick_consume (void * priv , char * line UNUSED , unsigned long len UNUSED )
2442
+ {
2443
+ struct emit_callback * ecbdata = priv ;
2444
+ struct diff_options * o = ecbdata -> opt ;
2445
+
2446
+ o -> found_changes = 1 ;
2447
+ return 1 ;
2448
+ }
2449
+
2441
2450
static void pprint_rename (struct strbuf * name , const char * a , const char * b )
2442
2451
{
2443
2452
const char * old_name = a ;
@@ -3753,8 +3762,21 @@ static void builtin_diff(const char *name_a,
3753
3762
3754
3763
if (o -> word_diff )
3755
3764
init_diff_words_data (& ecbdata , o , one , two );
3756
- if (xdi_diff_outf (& mf1 , & mf2 , NULL , fn_out_consume ,
3757
- & ecbdata , & xpp , & xecfg ))
3765
+ if (o -> dry_run ) {
3766
+ /*
3767
+ * Unlike the !dry_run case, we need to ignore the
3768
+ * return value from xdi_diff_outf() here, because
3769
+ * xdi_diff_outf() takes non-zero return from its
3770
+ * callback function as a sign of error and returns
3771
+ * early (which is why we return non-zero from our
3772
+ * callback, quick_consume()). Unfortunately,
3773
+ * xdi_diff_outf() signals an error by returning
3774
+ * non-zero.
3775
+ */
3776
+ xdi_diff_outf (& mf1 , & mf2 , NULL , quick_consume ,
3777
+ & ecbdata , & xpp , & xecfg );
3778
+ } else if (xdi_diff_outf (& mf1 , & mf2 , NULL , fn_out_consume ,
3779
+ & ecbdata , & xpp , & xecfg ))
3758
3780
die ("unable to generate diff for %s" , one -> path );
3759
3781
if (o -> word_diff )
3760
3782
free_diff_words_data (& ecbdata );
@@ -6168,6 +6190,22 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
6168
6190
run_diff (p , o );
6169
6191
}
6170
6192
6193
+ /* return 1 if any change is found; otherwise, return 0 */
6194
+ static int diff_flush_patch_quietly (struct diff_filepair * p , struct diff_options * o )
6195
+ {
6196
+ int saved_dry_run = o -> dry_run ;
6197
+ int saved_found_changes = o -> found_changes ;
6198
+ int ret ;
6199
+
6200
+ o -> dry_run = 1 ;
6201
+ o -> found_changes = 0 ;
6202
+ diff_flush_patch (p , o );
6203
+ ret = o -> found_changes ;
6204
+ o -> dry_run = saved_dry_run ;
6205
+ o -> found_changes |= saved_found_changes ;
6206
+ return ret ;
6207
+ }
6208
+
6171
6209
static void diff_flush_stat (struct diff_filepair * p , struct diff_options * o ,
6172
6210
struct diffstat_t * diffstat )
6173
6211
{
@@ -6796,8 +6834,15 @@ void diff_flush(struct diff_options *options)
6796
6834
DIFF_FORMAT_CHECKDIFF )) {
6797
6835
for (i = 0 ; i < q -> nr ; i ++ ) {
6798
6836
struct diff_filepair * p = q -> queue [i ];
6799
- if (check_pair_status (p ))
6800
- flush_one_pair (p , options );
6837
+
6838
+ if (!check_pair_status (p ))
6839
+ continue ;
6840
+
6841
+ if (options -> flags .diff_from_contents &&
6842
+ !diff_flush_patch_quietly (p , options ))
6843
+ continue ;
6844
+
6845
+ flush_one_pair (p , options );
6801
6846
}
6802
6847
separator ++ ;
6803
6848
}
@@ -6849,19 +6894,10 @@ void diff_flush(struct diff_options *options)
6849
6894
if (output_format & DIFF_FORMAT_NO_OUTPUT &&
6850
6895
options -> flags .exit_with_status &&
6851
6896
options -> flags .diff_from_contents ) {
6852
- /*
6853
- * run diff_flush_patch for the exit status. setting
6854
- * options->file to /dev/null should be safe, because we
6855
- * aren't supposed to produce any output anyway.
6856
- */
6857
- diff_free_file (options );
6858
- options -> file = xfopen ("/dev/null" , "w" );
6859
- options -> close_file = 1 ;
6860
- options -> color_moved = 0 ;
6861
6897
for (i = 0 ; i < q -> nr ; i ++ ) {
6862
6898
struct diff_filepair * p = q -> queue [i ];
6863
6899
if (check_pair_status (p ))
6864
- diff_flush_patch (p , options );
6900
+ diff_flush_patch_quietly (p , options );
6865
6901
if (options -> found_changes )
6866
6902
break ;
6867
6903
}
0 commit comments