提交 62c64895 编写于 作者: W Wincent Colaiuta 提交者: Junio C Hamano

"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: NWincent Colaiuta <win@wincent.com>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 913b45f5
......@@ -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;
......
......@@ -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)
......
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册