"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::
|
--check::
|
||||||
Warn if changes introduce trailing whitespace
|
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::
|
--full-index::
|
||||||
Instead of the first handful characters, show full
|
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);
|
result = run_diff_files_cmd(&rev, argc, argv);
|
||||||
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||||
return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -46,5 +46,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
|
|||||||
result = run_diff_index(&rev, cached);
|
result = run_diff_index(&rev, cached);
|
||||||
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||||
return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -117,23 +117,23 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!read_stdin)
|
if (read_stdin) {
|
||||||
return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
|
if (opt->diffopt.detect_rename)
|
||||||
&& DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
|
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)
|
if (get_sha1_hex(line, sha1)) {
|
||||||
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
|
fputs(line, stdout);
|
||||||
DIFF_SETUP_USE_CACHE);
|
fflush(stdout);
|
||||||
while (fgets(line, sizeof(line), stdin)) {
|
}
|
||||||
unsigned char sha1[20];
|
else
|
||||||
|
diff_tree_stdin(line);
|
||||||
if (get_sha1_hex(line, sha1)) {
|
|
||||||
fputs(line, stdout);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
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)
|
return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
|
||||||
&& DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
|
&& 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
|
/* If the user asked for our exit code then don't start a
|
||||||
* pager or we would end up reporting its exit code instead.
|
* 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();
|
setup_pager();
|
||||||
|
|
||||||
/* Do we have --cached and not have a pending object, then
|
/* 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);
|
ent, ents);
|
||||||
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
|
||||||
result = DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
|
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)
|
if (1 < rev.diffopt.skip_stat_unmatch)
|
||||||
refresh_index_quietly();
|
refresh_index_quietly();
|
||||||
return result;
|
return result;
|
||||||
|
9
diff.c
9
diff.c
@ -1031,6 +1031,7 @@ struct checkdiff_t {
|
|||||||
const char *filename;
|
const char *filename;
|
||||||
int lineno, color_diff;
|
int lineno, color_diff;
|
||||||
unsigned ws_rule;
|
unsigned ws_rule;
|
||||||
|
unsigned status;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void checkdiff_consume(void *priv, char *line, unsigned long len)
|
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;
|
white_space_at_end = 1;
|
||||||
|
|
||||||
if (space_before_tab || white_space_at_end) {
|
if (space_before_tab || white_space_at_end) {
|
||||||
|
data->status = 1;
|
||||||
printf("%s:%d: %s", data->filename, data->lineno, ws);
|
printf("%s:%d: %s", data->filename, data->lineno, ws);
|
||||||
if (space_before_tab) {
|
if (space_before_tab) {
|
||||||
printf("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:
|
free_and_return:
|
||||||
diff_free_filespec_data(one);
|
diff_free_filespec_data(one);
|
||||||
diff_free_filespec_data(two);
|
diff_free_filespec_data(two);
|
||||||
|
if (data.status)
|
||||||
|
DIFF_OPT_SET(o, CHECK_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct diff_filespec *alloc_filespec(const char *path)
|
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)
|
if (options->output_format & DIFF_FORMAT_NAME_STATUS)
|
||||||
count++;
|
count++;
|
||||||
if (options->output_format & DIFF_FORMAT_CHECKDIFF)
|
if (options->output_format & DIFF_FORMAT_CHECKDIFF)
|
||||||
|
{
|
||||||
count++;
|
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)
|
if (options->output_format & DIFF_FORMAT_NO_OUTPUT)
|
||||||
count++;
|
count++;
|
||||||
if (count > 1)
|
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_ALLOW_EXTERNAL (1 << 13)
|
||||||
#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
|
#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
|
||||||
#define DIFF_OPT_REVERSE_DIFF (1 << 15)
|
#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_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
|
||||||
#define DIFF_OPT_SET(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)
|
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
|
||||||
|
@ -117,7 +117,6 @@ EOF
|
|||||||
git diff -b > out
|
git diff -b > out
|
||||||
test_expect_success 'another test, with -b' 'git diff expect out'
|
test_expect_success 'another test, with -b' 'git diff expect out'
|
||||||
|
|
||||||
|
|
||||||
test_expect_success 'check mixed spaces and tabs in indent' '
|
test_expect_success 'check mixed spaces and tabs in indent' '
|
||||||
|
|
||||||
# This is indented with SP HT SP.
|
# 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
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user