@@ -2444,6 +2444,15 @@ static int fn_out_consume(void *priv, char *line, unsigned long len)
2444
2444
return 0 ;
2445
2445
}
2446
2446
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
+
2447
2456
static void pprint_rename (struct strbuf * name , const char * a , const char * b )
2448
2457
{
2449
2458
const char * old_name = a ;
@@ -3759,8 +3768,21 @@ static void builtin_diff(const char *name_a,
3759
3768
3760
3769
if (o -> word_diff )
3761
3770
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 ))
3764
3786
die ("unable to generate diff for %s" , one -> path );
3765
3787
if (o -> word_diff )
3766
3788
free_diff_words_data (& ecbdata );
@@ -6150,6 +6172,22 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
6150
6172
run_diff (p , o );
6151
6173
}
6152
6174
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
+
6153
6191
static void diff_flush_stat (struct diff_filepair * p , struct diff_options * o ,
6154
6192
struct diffstat_t * diffstat )
6155
6193
{
@@ -6778,8 +6816,15 @@ void diff_flush(struct diff_options *options)
6778
6816
DIFF_FORMAT_CHECKDIFF )) {
6779
6817
for (i = 0 ; i < q -> nr ; i ++ ) {
6780
6818
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 );
6783
6828
}
6784
6829
separator ++ ;
6785
6830
}
@@ -6831,19 +6876,10 @@ void diff_flush(struct diff_options *options)
6831
6876
if (output_format & DIFF_FORMAT_NO_OUTPUT &&
6832
6877
options -> flags .exit_with_status &&
6833
6878
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 ;
6843
6879
for (i = 0 ; i < q -> nr ; i ++ ) {
6844
6880
struct diff_filepair * p = q -> queue [i ];
6845
6881
if (check_pair_status (p ))
6846
- diff_flush_patch (p , options );
6882
+ diff_flush_patch_quietly (p , options );
6847
6883
if (options -> found_changes )
6848
6884
break ;
6849
6885
}
0 commit comments