@@ -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 );
@@ -6144,6 +6166,22 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
6144
6166
run_diff (p , o );
6145
6167
}
6146
6168
6169
+ /* return 1 if any change is found; otherwise, return 0 */
6170
+ static int diff_flush_patch_quietly (struct diff_filepair * p , struct diff_options * o )
6171
+ {
6172
+ int saved_dry_run = o -> dry_run ;
6173
+ int saved_found_changes = o -> found_changes ;
6174
+ int ret ;
6175
+
6176
+ o -> dry_run = 1 ;
6177
+ o -> found_changes = 0 ;
6178
+ diff_flush_patch (p , o );
6179
+ ret = o -> found_changes ;
6180
+ o -> dry_run = saved_dry_run ;
6181
+ o -> found_changes |= saved_found_changes ;
6182
+ return ret ;
6183
+ }
6184
+
6147
6185
static void diff_flush_stat (struct diff_filepair * p , struct diff_options * o ,
6148
6186
struct diffstat_t * diffstat )
6149
6187
{
@@ -6772,8 +6810,15 @@ void diff_flush(struct diff_options *options)
6772
6810
DIFF_FORMAT_CHECKDIFF )) {
6773
6811
for (i = 0 ; i < q -> nr ; i ++ ) {
6774
6812
struct diff_filepair * p = q -> queue [i ];
6775
- if (check_pair_status (p ))
6776
- flush_one_pair (p , options );
6813
+
6814
+ if (!check_pair_status (p ))
6815
+ continue ;
6816
+
6817
+ if (options -> flags .diff_from_contents &&
6818
+ !diff_flush_patch_quietly (p , options ))
6819
+ continue ;
6820
+
6821
+ flush_one_pair (p , options );
6777
6822
}
6778
6823
separator ++ ;
6779
6824
}
@@ -6825,19 +6870,10 @@ void diff_flush(struct diff_options *options)
6825
6870
if (output_format & DIFF_FORMAT_NO_OUTPUT &&
6826
6871
options -> flags .exit_with_status &&
6827
6872
options -> flags .diff_from_contents ) {
6828
- /*
6829
- * run diff_flush_patch for the exit status. setting
6830
- * options->file to /dev/null should be safe, because we
6831
- * aren't supposed to produce any output anyway.
6832
- */
6833
- diff_free_file (options );
6834
- options -> file = xfopen ("/dev/null" , "w" );
6835
- options -> close_file = 1 ;
6836
- options -> color_moved = 0 ;
6837
6873
for (i = 0 ; i < q -> nr ; i ++ ) {
6838
6874
struct diff_filepair * p = q -> queue [i ];
6839
6875
if (check_pair_status (p ))
6840
- diff_flush_patch (p , options );
6876
+ diff_flush_patch_quietly (p , options );
6841
6877
if (options -> found_changes )
6842
6878
break ;
6843
6879
}
0 commit comments