diff options
Diffstat (limited to 'diff.c')
| -rw-r--r-- | diff.c | 75 |
1 files changed, 70 insertions, 5 deletions
@@ -2444,6 +2444,15 @@ static int fn_out_consume(void *priv, char *line, unsigned long len) return 0; } +static int quick_consume(void *priv, char *line UNUSED, unsigned long len UNUSED) +{ + struct emit_callback *ecbdata = priv; + struct diff_options *o = ecbdata->opt; + + o->found_changes = 1; + return 1; +} + static void pprint_rename(struct strbuf *name, const char *a, const char *b) { const char *old_name = a; @@ -3759,8 +3768,21 @@ static void builtin_diff(const char *name_a, if (o->word_diff) init_diff_words_data(&ecbdata, o, one, two); - if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume, - &ecbdata, &xpp, &xecfg)) + if (o->dry_run) { + /* + * Unlike the !dry_run case, we need to ignore the + * return value from xdi_diff_outf() here, because + * xdi_diff_outf() takes non-zero return from its + * callback function as a sign of error and returns + * early (which is why we return non-zero from our + * callback, quick_consume()). Unfortunately, + * xdi_diff_outf() signals an error by returning + * non-zero. + */ + xdi_diff_outf(&mf1, &mf2, NULL, quick_consume, + &ecbdata, &xpp, &xecfg); + } else if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume, + &ecbdata, &xpp, &xecfg)) die("unable to generate diff for %s", one->path); if (o->word_diff) free_diff_words_data(&ecbdata); @@ -6150,6 +6172,22 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o) run_diff(p, o); } +/* return 1 if any change is found; otherwise, return 0 */ +static int diff_flush_patch_quietly(struct diff_filepair *p, struct diff_options *o) +{ + int saved_dry_run = o->dry_run; + int saved_found_changes = o->found_changes; + int ret; + + o->dry_run = 1; + o->found_changes = 0; + diff_flush_patch(p, o); + ret = o->found_changes; + o->dry_run = saved_dry_run; + o->found_changes |= saved_found_changes; + return ret; +} + static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o, struct diffstat_t *diffstat) { @@ -6776,10 +6814,37 @@ void diff_flush(struct diff_options *options) DIFF_FORMAT_NAME | DIFF_FORMAT_NAME_STATUS | DIFF_FORMAT_CHECKDIFF)) { + /* + * make sure diff_Flush_patch_quietly() to be silent. + */ + FILE *dev_null = NULL; + int saved_color_moved = options->color_moved; + + if (options->flags.diff_from_contents) { + dev_null = xfopen("/dev/null", "w"); + options->color_moved = 0; + } for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - if (check_pair_status(p)) - flush_one_pair(p, options); + + if (!check_pair_status(p)) + continue; + + if (options->flags.diff_from_contents) { + FILE *saved_file = options->file; + int found_changes; + + options->file = dev_null; + found_changes = diff_flush_patch_quietly(p, options); + options->file = saved_file; + if (!found_changes) + continue; + } + flush_one_pair(p, options); + } + if (options->flags.diff_from_contents) { + fclose(dev_null); + options->color_moved = saved_color_moved; } separator++; } @@ -6843,7 +6908,7 @@ void diff_flush(struct diff_options *options) for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; if (check_pair_status(p)) - diff_flush_patch(p, options); + diff_flush_patch_quietly(p, options); if (options->found_changes) break; } |
