Skip to content

Commit 74a2e88

Browse files
committed
Merge branch 'jc/diff-exit-code-with-w-fixes'
"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
2 parents 5ba560b + a64f8b2 commit 74a2e88

File tree

3 files changed

+64
-18
lines changed

3 files changed

+64
-18
lines changed

diff.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3563,18 +3563,21 @@ static void builtin_diff(const char *name_a,
35633563
strbuf_addf(&header, "%s%snew file mode %06o%s\n", line_prefix, meta, two->mode, reset);
35643564
if (xfrm_msg)
35653565
strbuf_addstr(&header, xfrm_msg);
3566+
o->found_changes = 1;
35663567
must_show_header = 1;
35673568
}
35683569
else if (lbl[1][0] == '/') {
35693570
strbuf_addf(&header, "%s%sdeleted file mode %06o%s\n", line_prefix, meta, one->mode, reset);
35703571
if (xfrm_msg)
35713572
strbuf_addstr(&header, xfrm_msg);
3573+
o->found_changes = 1;
35723574
must_show_header = 1;
35733575
}
35743576
else {
35753577
if (one->mode != two->mode) {
35763578
strbuf_addf(&header, "%s%sold mode %06o%s\n", line_prefix, meta, one->mode, reset);
35773579
strbuf_addf(&header, "%s%snew mode %06o%s\n", line_prefix, meta, two->mode, reset);
3580+
o->found_changes = 1;
35783581
must_show_header = 1;
35793582
}
35803583
if (xfrm_msg)
@@ -4832,6 +4835,10 @@ void diff_setup_done(struct diff_options *options)
48324835
else
48334836
options->prefix_length = 0;
48344837

4838+
/*
4839+
* --name-only, --name-status, --checkdiff, and -s
4840+
* turn other output format off.
4841+
*/
48354842
if (options->output_format & (DIFF_FORMAT_NAME |
48364843
DIFF_FORMAT_NAME_STATUS |
48374844
DIFF_FORMAT_CHECKDIFF |
@@ -6206,6 +6213,8 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt)
62066213
fprintf(opt->file, "%s", diff_line_prefix(opt));
62076214
write_name_quoted(name_a, opt->file, opt->line_termination);
62086215
}
6216+
6217+
opt->found_changes = 1;
62096218
}
62106219

62116220
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)
66846693
separator++;
66856694
}
66866695

6696+
if (output_format & DIFF_FORMAT_PATCH) {
6697+
if (separator) {
6698+
emit_diff_symbol(options, DIFF_SYMBOL_SEPARATOR, NULL, 0, 0);
6699+
if (options->stat_sep)
6700+
/* attach patch instead of inline */
6701+
emit_diff_symbol(options, DIFF_SYMBOL_STAT_SEP,
6702+
NULL, 0, 0);
6703+
}
6704+
6705+
diff_flush_patch_all_file_pairs(options);
6706+
}
6707+
6708+
if (output_format & DIFF_FORMAT_CALLBACK)
6709+
options->format_callback(q, options, options->format_callback_data);
6710+
66876711
if (output_format & DIFF_FORMAT_NO_OUTPUT &&
66886712
options->flags.exit_with_status &&
66896713
options->flags.diff_from_contents) {
@@ -6705,21 +6729,6 @@ void diff_flush(struct diff_options *options)
67056729
}
67066730
}
67076731

6708-
if (output_format & DIFF_FORMAT_PATCH) {
6709-
if (separator) {
6710-
emit_diff_symbol(options, DIFF_SYMBOL_SEPARATOR, NULL, 0, 0);
6711-
if (options->stat_sep)
6712-
/* attach patch instead of inline */
6713-
emit_diff_symbol(options, DIFF_SYMBOL_STAT_SEP,
6714-
NULL, 0, 0);
6715-
}
6716-
6717-
diff_flush_patch_all_file_pairs(options);
6718-
}
6719-
6720-
if (output_format & DIFF_FORMAT_CALLBACK)
6721-
options->format_callback(q, options, options->format_callback_data);
6722-
67236732
free_queue:
67246733
diff_free_queue(q);
67256734
DIFF_QUEUE_CLEAR(q);
@@ -7029,6 +7038,7 @@ void compute_diffstat(struct diff_options *options,
70297038
if (check_pair_status(p))
70307039
diff_flush_stat(p, options, diffstat);
70317040
}
7041+
options->found_changes = !!diffstat->nr;
70327042
}
70337043

70347044
void diff_addremove(struct diff_options *options,

t/t4015-diff-whitespace.sh

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/sh
22
#
33
# Copyright (c) 2006 Johannes E. Schindelin
4-
#
4+
# Copyright (c) 2023 Google LLC
55

66
test_description='Test special whitespace in diff engine.
77
@@ -11,6 +11,43 @@ TEST_PASSES_SANITIZE_LEAK=true
1111
. ./test-lib.sh
1212
. "$TEST_DIRECTORY"/lib-diff.sh
1313

14+
for opt_res in --patch --quiet -s --stat --shortstat --dirstat=lines \
15+
--raw! --name-only! --name-status!
16+
do
17+
opts=${opt_res%!} expect_failure=
18+
test "$opts" = "$opt_res" ||
19+
expect_failure="test_expect_code 1"
20+
21+
test_expect_success "status with $opts (different)" '
22+
echo foo >x &&
23+
git add x &&
24+
echo bar >x &&
25+
test_expect_code 1 git diff -w $opts --exit-code x
26+
'
27+
28+
test_expect_success POSIXPERM "status with $opts (mode differs)" '
29+
test_when_finished "git update-index --chmod=-x x" &&
30+
echo foo >x &&
31+
git add x &&
32+
git update-index --chmod=+x x &&
33+
test_expect_code 1 git diff -w $opts --exit-code x
34+
'
35+
36+
test_expect_success "status with $opts (removing an empty file)" '
37+
: >x &&
38+
git add x &&
39+
rm x &&
40+
test_expect_code 1 git diff -w $opts --exit-code -- x
41+
'
42+
43+
test_expect_success "status with $opts (different but equivalent)" '
44+
echo foo >x &&
45+
git add x &&
46+
echo " foo" >x &&
47+
$expect_failure git diff -w $opts --exit-code x
48+
'
49+
done
50+
1451
test_expect_success "Ray Lehtiniemi's example" '
1552
cat <<-\EOF >x &&
1653
do {

t/t4040-whitespace-status.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ test_expect_success 'diff-tree --exit-code' '
2828

2929
test_expect_success 'diff-tree -b --exit-code' '
3030
git diff -b --exit-code HEAD^ HEAD &&
31-
git diff-tree -b -p --exit-code HEAD^ HEAD &&
32-
git diff-tree -b --exit-code HEAD^ HEAD
31+
git diff-tree -b -p --exit-code HEAD^ HEAD
3332
'
3433

3534
test_expect_success 'diff-index --cached --exit-code' '

0 commit comments

Comments
 (0)