"diff --check" should affect exit status
"git diff" has a --check option that can be used to check for whitespace problems but it only reported by printing warnings to the console. Now when the --check option is used we give a non-zero exit status, making "git diff --check" nicer to use in scripts and hooks. Signed-off-by: Wincent Colaiuta <win@wincent.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
913b45f51b
commit
62c64895cf
@ -93,7 +93,9 @@ endif::git-format-patch[]
|
||||
|
||||
--check::
|
||||
Warn if changes introduce trailing whitespace
|
||||
or an indent that uses a space before a tab.
|
||||
or an indent that uses a space before a tab. Exits with
|
||||
non-zero status if problems are found. Not compatible with
|
||||
--exit-code.
|
||||
|
||||
--full-index::
|
||||
Instead of the first handful characters, show full
|
||||
|
@ -33,5 +33,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
|
||||
result = run_diff_files_cmd(&rev, argc, argv);
|
||||
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||
return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
|
||||
if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
|
||||
return DIFF_OPT_TST(&rev.diffopt, CHECK_FAILED) != 0;
|
||||
return result;
|
||||
}
|
||||
|
@ -46,5 +46,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
|
||||
result = run_diff_index(&rev, cached);
|
||||
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||
return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
|
||||
if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
|
||||
return DIFF_OPT_TST(&rev.diffopt, CHECK_FAILED) != 0;
|
||||
return result;
|
||||
}
|
||||
|
@ -117,23 +117,23 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!read_stdin)
|
||||
return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
|
||||
&& DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
|
||||
if (read_stdin) {
|
||||
if (opt->diffopt.detect_rename)
|
||||
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
|
||||
DIFF_SETUP_USE_CACHE);
|
||||
while (fgets(line, sizeof(line), stdin)) {
|
||||
unsigned char sha1[20];
|
||||
|
||||
if (opt->diffopt.detect_rename)
|
||||
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
|
||||
DIFF_SETUP_USE_CACHE);
|
||||
while (fgets(line, sizeof(line), stdin)) {
|
||||
unsigned char sha1[20];
|
||||
|
||||
if (get_sha1_hex(line, sha1)) {
|
||||
fputs(line, stdout);
|
||||
fflush(stdout);
|
||||
if (get_sha1_hex(line, sha1)) {
|
||||
fputs(line, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
diff_tree_stdin(line);
|
||||
}
|
||||
else
|
||||
diff_tree_stdin(line);
|
||||
}
|
||||
if (opt->diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
|
||||
return DIFF_OPT_TST(&opt->diffopt, CHECK_FAILED) != 0;
|
||||
return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
|
||||
&& DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
|
||||
}
|
||||
|
@ -247,7 +247,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
|
||||
/* If the user asked for our exit code then don't start a
|
||||
* pager or we would end up reporting its exit code instead.
|
||||
*/
|
||||
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS) &&
|
||||
(!(rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)))
|
||||
setup_pager();
|
||||
|
||||
/* Do we have --cached and not have a pending object, then
|
||||
@ -353,7 +354,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
|
||||
ent, ents);
|
||||
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||
result = DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
|
||||
|
||||
if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
|
||||
return DIFF_OPT_TST(&rev.diffopt, CHECK_FAILED) != 0;
|
||||
if (1 < rev.diffopt.skip_stat_unmatch)
|
||||
refresh_index_quietly();
|
||||
return result;
|
||||
|
9
diff.c
9
diff.c
@ -1031,6 +1031,7 @@ struct checkdiff_t {
|
||||
const char *filename;
|
||||
int lineno, color_diff;
|
||||
unsigned ws_rule;
|
||||
unsigned status;
|
||||
};
|
||||
|
||||
static void checkdiff_consume(void *priv, char *line, unsigned long len)
|
||||
@ -1064,6 +1065,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
|
||||
white_space_at_end = 1;
|
||||
|
||||
if (space_before_tab || white_space_at_end) {
|
||||
data->status = 1;
|
||||
printf("%s:%d: %s", data->filename, data->lineno, ws);
|
||||
if (space_before_tab) {
|
||||
printf("space before tab");
|
||||
@ -1491,6 +1493,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
|
||||
free_and_return:
|
||||
diff_free_filespec_data(one);
|
||||
diff_free_filespec_data(two);
|
||||
if (data.status)
|
||||
DIFF_OPT_SET(o, CHECK_FAILED);
|
||||
}
|
||||
|
||||
struct diff_filespec *alloc_filespec(const char *path)
|
||||
@ -2121,7 +2125,12 @@ int diff_setup_done(struct diff_options *options)
|
||||
if (options->output_format & DIFF_FORMAT_NAME_STATUS)
|
||||
count++;
|
||||
if (options->output_format & DIFF_FORMAT_CHECKDIFF)
|
||||
{
|
||||
count++;
|
||||
if (DIFF_OPT_TST(options, QUIET) ||
|
||||
DIFF_OPT_TST(options, EXIT_WITH_STATUS))
|
||||
die("--check may not be used with --quiet or --exit-code");
|
||||
}
|
||||
if (options->output_format & DIFF_FORMAT_NO_OUTPUT)
|
||||
count++;
|
||||
if (count > 1)
|
||||
|
1
diff.h
1
diff.h
@ -59,6 +59,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
|
||||
#define DIFF_OPT_ALLOW_EXTERNAL (1 << 13)
|
||||
#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
|
||||
#define DIFF_OPT_REVERSE_DIFF (1 << 15)
|
||||
#define DIFF_OPT_CHECK_FAILED (1 << 16)
|
||||
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
|
||||
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
|
||||
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
|
||||
|
@ -117,7 +117,6 @@ EOF
|
||||
git diff -b > out
|
||||
test_expect_success 'another test, with -b' 'git diff expect out'
|
||||
|
||||
|
||||
test_expect_success 'check mixed spaces and tabs in indent' '
|
||||
|
||||
# This is indented with SP HT SP.
|
||||
@ -126,4 +125,140 @@ test_expect_success 'check mixed spaces and tabs in indent' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'check with no whitespace errors' '
|
||||
|
||||
git commit -m "snapshot" &&
|
||||
echo "foo();" > x &&
|
||||
git diff --check
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check with trailing whitespace' '
|
||||
|
||||
echo "foo(); " > x &&
|
||||
git diff --check
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check with space before tab in indent' '
|
||||
|
||||
# indent has space followed by hard tab
|
||||
echo " foo();" > x &&
|
||||
git diff --check
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure '--check and --exit-code are exclusive' '
|
||||
|
||||
git checkout x &&
|
||||
git diff --check --exit-code
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure '--check and --quiet are exclusive' '
|
||||
|
||||
git diff --check --quiet
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'check staged with no whitespace errors' '
|
||||
|
||||
echo "foo();" > x &&
|
||||
git add x &&
|
||||
git diff --cached --check
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check staged with trailing whitespace' '
|
||||
|
||||
echo "foo(); " > x &&
|
||||
git add x &&
|
||||
git diff --cached --check
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check staged with space before tab in indent' '
|
||||
|
||||
# indent has space followed by hard tab
|
||||
echo " foo();" > x &&
|
||||
git add x &&
|
||||
git diff --cached --check
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'check with no whitespace errors (diff-index)' '
|
||||
|
||||
echo "foo();" > x &&
|
||||
git add x &&
|
||||
git diff-index --check HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check with trailing whitespace (diff-index)' '
|
||||
|
||||
echo "foo(); " > x &&
|
||||
git add x &&
|
||||
git diff-index --check HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check with space before tab in indent (diff-index)' '
|
||||
|
||||
# indent has space followed by hard tab
|
||||
echo " foo();" > x &&
|
||||
git add x &&
|
||||
git diff-index --check HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'check staged with no whitespace errors (diff-index)' '
|
||||
|
||||
echo "foo();" > x &&
|
||||
git add x &&
|
||||
git diff-index --cached --check HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check staged with trailing whitespace (diff-index)' '
|
||||
|
||||
echo "foo(); " > x &&
|
||||
git add x &&
|
||||
git diff-index --cached --check HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check staged with space before tab in indent (diff-index)' '
|
||||
|
||||
# indent has space followed by hard tab
|
||||
echo " foo();" > x &&
|
||||
git add x &&
|
||||
git diff-index --cached --check HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'check with no whitespace errors (diff-tree)' '
|
||||
|
||||
echo "foo();" > x &&
|
||||
git commit -m "new commit" x &&
|
||||
git diff-tree --check HEAD^ HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check with trailing whitespace (diff-tree)' '
|
||||
|
||||
echo "foo(); " > x &&
|
||||
git commit -m "another commit" x &&
|
||||
git diff-tree --check HEAD^ HEAD
|
||||
|
||||
'
|
||||
|
||||
test_expect_failure 'check with space before tab in indent (diff-tree)' '
|
||||
|
||||
# indent has space followed by hard tab
|
||||
echo " foo();" > x &&
|
||||
git commit -m "yet another" x &&
|
||||
git diff-tree --check HEAD^ HEAD
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user