diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-11-02 16:53:15 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-11-02 16:53:15 +0900 |
commit | 87644914638e7090334bb123a706fca6840f5763 (patch) | |
tree | d07f143748d06baeb29f2e5c779d25540a7be434 | |
parent | 1ea39ad4677a7572717a0137aaa46f1cda4e9c4d (diff) | |
parent | a64f8b25953b9cf0f6d81ed24e87448ae513b094 (diff) | |
download | git-87644914638e7090334bb123a706fca6840f5763.tar.gz |
Merge branch 'jc/diff-exit-code-with-w-fixes' into maint-2.42
"git diff -w --exit-code" with various options did not work
correctly, which is being addressed.
* jc/diff-exit-code-with-w-fixes:
diff: the -w option breaks --exit-code for --raw and other output modes
t4040: remove test that succeeded for a wrong reason
diff: teach "--stat -w --exit-code" to notice differences
diff: mode-only change should be noticed by "--patch -w --exit-code"
diff: move the fallback "--exit-code" code down
-rw-r--r-- | diff.c | 40 | ||||
-rwxr-xr-x | t/t4015-diff-whitespace.sh | 39 | ||||
-rwxr-xr-x | t/t4040-whitespace-status.sh | 3 |
3 files changed, 64 insertions, 18 deletions
@@ -3563,18 +3563,21 @@ static void builtin_diff(const char *name_a, strbuf_addf(&header, "%s%snew file mode %06o%s\n", line_prefix, meta, two->mode, reset); if (xfrm_msg) strbuf_addstr(&header, xfrm_msg); + o->found_changes = 1; must_show_header = 1; } else if (lbl[1][0] == '/') { strbuf_addf(&header, "%s%sdeleted file mode %06o%s\n", line_prefix, meta, one->mode, reset); if (xfrm_msg) strbuf_addstr(&header, xfrm_msg); + o->found_changes = 1; must_show_header = 1; } else { if (one->mode != two->mode) { strbuf_addf(&header, "%s%sold mode %06o%s\n", line_prefix, meta, one->mode, reset); strbuf_addf(&header, "%s%snew mode %06o%s\n", line_prefix, meta, two->mode, reset); + o->found_changes = 1; must_show_header = 1; } if (xfrm_msg) @@ -4832,6 +4835,10 @@ void diff_setup_done(struct diff_options *options) else options->prefix_length = 0; + /* + * --name-only, --name-status, --checkdiff, and -s + * turn other output format off. + */ if (options->output_format & (DIFF_FORMAT_NAME | DIFF_FORMAT_NAME_STATUS | DIFF_FORMAT_CHECKDIFF | @@ -6206,6 +6213,8 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt) fprintf(opt->file, "%s", diff_line_prefix(opt)); write_name_quoted(name_a, opt->file, opt->line_termination); } + + opt->found_changes = 1; } static void show_file_mode_name(struct diff_options *opt, const char *newdelete, struct diff_filespec *fs) @@ -6684,6 +6693,21 @@ void diff_flush(struct diff_options *options) separator++; } + if (output_format & DIFF_FORMAT_PATCH) { + if (separator) { + emit_diff_symbol(options, DIFF_SYMBOL_SEPARATOR, NULL, 0, 0); + if (options->stat_sep) + /* attach patch instead of inline */ + emit_diff_symbol(options, DIFF_SYMBOL_STAT_SEP, + NULL, 0, 0); + } + + diff_flush_patch_all_file_pairs(options); + } + + if (output_format & DIFF_FORMAT_CALLBACK) + options->format_callback(q, options, options->format_callback_data); + if (output_format & DIFF_FORMAT_NO_OUTPUT && options->flags.exit_with_status && options->flags.diff_from_contents) { @@ -6705,21 +6729,6 @@ void diff_flush(struct diff_options *options) } } - if (output_format & DIFF_FORMAT_PATCH) { - if (separator) { - emit_diff_symbol(options, DIFF_SYMBOL_SEPARATOR, NULL, 0, 0); - if (options->stat_sep) - /* attach patch instead of inline */ - emit_diff_symbol(options, DIFF_SYMBOL_STAT_SEP, - NULL, 0, 0); - } - - diff_flush_patch_all_file_pairs(options); - } - - if (output_format & DIFF_FORMAT_CALLBACK) - options->format_callback(q, options, options->format_callback_data); - free_queue: diff_free_queue(q); DIFF_QUEUE_CLEAR(q); @@ -7029,6 +7038,7 @@ void compute_diffstat(struct diff_options *options, if (check_pair_status(p)) diff_flush_stat(p, options, diffstat); } + options->found_changes = !!diffstat->nr; } void diff_addremove(struct diff_options *options, diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index b298f220e0..fcd2473e52 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -1,7 +1,7 @@ #!/bin/sh # # Copyright (c) 2006 Johannes E. Schindelin -# +# Copyright (c) 2023 Google LLC test_description='Test special whitespace in diff engine. @@ -11,6 +11,43 @@ TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh +for opt_res in --patch --quiet -s --stat --shortstat --dirstat=lines \ + --raw! --name-only! --name-status! +do + opts=${opt_res%!} expect_failure= + test "$opts" = "$opt_res" || + expect_failure="test_expect_code 1" + + test_expect_success "status with $opts (different)" ' + echo foo >x && + git add x && + echo bar >x && + test_expect_code 1 git diff -w $opts --exit-code x + ' + + test_expect_success POSIXPERM "status with $opts (mode differs)" ' + test_when_finished "git update-index --chmod=-x x" && + echo foo >x && + git add x && + git update-index --chmod=+x x && + test_expect_code 1 git diff -w $opts --exit-code x + ' + + test_expect_success "status with $opts (removing an empty file)" ' + : >x && + git add x && + rm x && + test_expect_code 1 git diff -w $opts --exit-code -- x + ' + + test_expect_success "status with $opts (different but equivalent)" ' + echo foo >x && + git add x && + echo " foo" >x && + $expect_failure git diff -w $opts --exit-code x + ' +done + test_expect_success "Ray Lehtiniemi's example" ' cat <<-\EOF >x && do { diff --git a/t/t4040-whitespace-status.sh b/t/t4040-whitespace-status.sh index e70e020ae9..eec3d73dc2 100755 --- a/t/t4040-whitespace-status.sh +++ b/t/t4040-whitespace-status.sh @@ -28,8 +28,7 @@ test_expect_success 'diff-tree --exit-code' ' test_expect_success 'diff-tree -b --exit-code' ' git diff -b --exit-code HEAD^ HEAD && - git diff-tree -b -p --exit-code HEAD^ HEAD && - git diff-tree -b --exit-code HEAD^ HEAD + git diff-tree -b -p --exit-code HEAD^ HEAD ' test_expect_success 'diff-index --cached --exit-code' ' |