--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
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;
}
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;
}
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);
}
/* 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
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;
const char *filename;
int lineno, color_diff;
unsigned ws_rule;
+ unsigned status;
};
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");
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)
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)
#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)
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.
'
+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