diff options
| author | Junio C Hamano <gitster@pobox.com> | 2025-08-22 13:13:22 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-08-22 13:13:22 -0700 |
| commit | 244214e9b6fc35466bf050aa4d50771adc87d96f (patch) | |
| tree | ca1396856ee804b44f02fb88f74951d5a6f925a8 /diff.c | |
| parent | Merge branch 'kr/clone-synopsis-fix' (diff) | |
| parent | diff: ensure consistent diff behavior with ignore options (diff) | |
| download | git-244214e9b6fc35466bf050aa4d50771adc87d96f.tar.gz git-244214e9b6fc35466bf050aa4d50771adc87d96f.zip | |
Merge branch 'ly/diff-name-only-with-diff-from-content'
Various options to "git diff" that makes comparison ignore certain
aspects of the differences (like "space changes are ignored",
"differences in lines that match these regular expressions are
ignored") did not work well with "--name-only" and friends.
* ly/diff-name-only-with-diff-from-content:
diff: ensure consistent diff behavior with ignore options
Diffstat (limited to 'diff.c')
| -rw-r--r-- | diff.c | 64 |
1 files changed, 50 insertions, 14 deletions
@@ -2438,6 +2438,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; @@ -3753,8 +3762,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); @@ -6144,6 +6166,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) { @@ -6772,8 +6810,15 @@ void diff_flush(struct diff_options *options) DIFF_FORMAT_CHECKDIFF)) { 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 && + !diff_flush_patch_quietly(p, options)) + continue; + + flush_one_pair(p, options); } separator++; } @@ -6825,19 +6870,10 @@ void diff_flush(struct diff_options *options) if (output_format & DIFF_FORMAT_NO_OUTPUT && options->flags.exit_with_status && options->flags.diff_from_contents) { - /* - * run diff_flush_patch for the exit status. setting - * options->file to /dev/null should be safe, because we - * aren't supposed to produce any output anyway. - */ - diff_free_file(options); - options->file = xfopen("/dev/null", "w"); - options->close_file = 1; - options->color_moved = 0; 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; } |
