#include "string-list.h"
#include "argv-array.h"
#include "graph.h"
+#include "packfile.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
return 0;
}
- if (git_color_config(var, value, cb) < 0)
- return -1;
-
return git_diff_basic_config(var, value, cb);
}
return 0;
}
- if (starts_with(var, "submodule."))
- return parse_submodule_config_option(var, value);
-
if (git_diff_heuristic_config(var, value, cb) < 0)
return -1;
* If this diff_tempfile instance refers to a temporary file,
* this tempfile object is used to manage its lifetime.
*/
- struct tempfile tempfile;
+ struct tempfile *tempfile;
} diff_temp[2];
-typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
-
struct emit_callback {
int color_diff;
unsigned ws_rule;
int blank_at_eof_in_postimage;
int lno_in_preimage;
int lno_in_postimage;
- sane_truncate_fn truncate;
const char **label_path;
struct diff_words_data *diff_words;
struct diff_options *opt;
if (*cp > *endp)
return -1;
- if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_CHANGE)) {
- while (*cp < *endp && isspace(**cp))
- (*cp)++;
- /*
- * After skipping a couple of whitespaces, we still have to
- * account for one space.
- */
- return (int)' ';
- }
+ if (isspace(**cp)) {
+ if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_CHANGE)) {
+ while (*cp < *endp && isspace(**cp))
+ (*cp)++;
+ /*
+ * After skipping a couple of whitespaces,
+ * we still have to account for one space.
+ */
+ return (int)' ';
+ }
- if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE)) {
- while (*cp < *endp && isspace(**cp))
- (*cp)++;
- /* return the first non-ws character via the usual below */
+ if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE)) {
+ while (*cp < *endp && isspace(**cp))
+ (*cp)++;
+ /* return the first non-ws character via the usual below */
+ }
}
retval = (unsigned char)(**cp);
return rp + 1;
}
+/*
+ * If o->color_moved is COLOR_MOVED_PLAIN, this function does nothing.
+ *
+ * Otherwise, if the last block has fewer alphanumeric characters than
+ * COLOR_MOVED_MIN_ALNUM_COUNT, unset DIFF_SYMBOL_MOVED_LINE on all lines in
+ * that block.
+ *
+ * The last block consists of the (n - block_length)'th line up to but not
+ * including the nth line.
+ *
+ * NEEDSWORK: This uses the same heuristic as blame_entry_score() in blame.c.
+ * Think of a way to unify them.
+ */
+static void adjust_last_block(struct diff_options *o, int n, int block_length)
+{
+ int i, alnum_count = 0;
+ if (o->color_moved == COLOR_MOVED_PLAIN)
+ return;
+ for (i = 1; i < block_length + 1; i++) {
+ const char *c = o->emitted_symbols->buf[n - i].line;
+ for (; *c; c++) {
+ if (!isalnum(*c))
+ continue;
+ alnum_count++;
+ if (alnum_count >= COLOR_MOVED_MIN_ALNUM_COUNT)
+ return;
+ }
+ }
+ for (i = 1; i < block_length + 1; i++)
+ o->emitted_symbols->buf[n - i].flags &= ~DIFF_SYMBOL_MOVED_LINE;
+}
+
/* Find blocks of moved code, delegate actual coloring decision to helper */
static void mark_color_as_moved(struct diff_options *o,
struct hashmap *add_lines,
}
if (!match) {
- if (block_length < COLOR_MOVED_MIN_BLOCK_LENGTH &&
- o->color_moved != COLOR_MOVED_PLAIN) {
- for (i = 0; i < block_length + 1; i++) {
- l = &o->emitted_symbols->buf[n - i];
- l->flags &= ~DIFF_SYMBOL_MOVED_LINE;
- }
- }
+ adjust_last_block(o, n, block_length);
pmb_nr = 0;
block_length = 0;
continue;
}
l->flags |= DIFF_SYMBOL_MOVED_LINE;
- block_length++;
if (o->color_moved == COLOR_MOVED_PLAIN)
continue;
}
flipped_block = (flipped_block + 1) % 2;
+
+ adjust_last_block(o, n, block_length);
+ block_length = 0;
}
+ block_length++;
+
if (flipped_block)
l->flags |= DIFF_SYMBOL_MOVED_LINE_ALT;
}
+ adjust_last_block(o, n, block_length);
free(pmb);
}
{
int i;
for (i = 0; i < ARRAY_SIZE(diff_temp); i++) {
- if (is_tempfile_active(&diff_temp[i].tempfile))
+ if (is_tempfile_active(diff_temp[i].tempfile))
delete_tempfile(&diff_temp[i].tempfile);
diff_temp[i].name = NULL;
}
struct diff_words_buffer {
mmfile_t text;
- long alloc;
+ unsigned long alloc;
struct diff_words_orig {
const char *begin, *end;
} *orig;
unsigned long allot;
size_t l = len;
- if (ecb->truncate)
- return ecb->truncate(line, len);
cp = line;
allot = l;
while (0 < l) {
}
print_stat_summary_inserts_deletes(options, total_files, adds, dels);
+ strbuf_release(&out);
}
static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
* bytes per "line".
* This is stupid and ugly, but very cheap...
*/
- damage = (damage + 63) / 64;
+ damage = DIV_ROUND_UP(damage, 64);
ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
dir.files[dir.nr].name = file->name;
dir.files[dir.nr].changed = damage;
const struct object_id *oid,
int mode)
{
- int fd;
struct strbuf buf = STRBUF_INIT;
struct strbuf template = STRBUF_INIT;
char *path_dup = xstrdup(path);
strbuf_addstr(&template, "XXXXXX_");
strbuf_addstr(&template, base);
- fd = mks_tempfile_ts(&temp->tempfile, template.buf, strlen(base) + 1);
- if (fd < 0)
+ temp->tempfile = mks_tempfile_ts(template.buf, strlen(base) + 1);
+ if (!temp->tempfile)
die_errno("unable to create temp-file");
if (convert_to_working_tree(path,
(const char *)blob, (size_t)size, &buf)) {
blob = buf.buf;
size = buf.len;
}
- if (write_in_full(fd, blob, size) != size)
+ if (write_in_full(temp->tempfile->fd, blob, size) < 0 ||
+ close_tempfile_gently(temp->tempfile))
die_errno("unable to write temp-file");
- close_tempfile(&temp->tempfile);
- temp->name = get_tempfile_path(&temp->tempfile);
+ temp->name = get_tempfile_path(temp->tempfile);
oid_to_hex_r(temp->hex, oid);
xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode);
strbuf_release(&buf);
}
if (lstat(one->path, &st) < 0)
die_errno("stat '%s'", one->path);
- if (index_path(one->oid.hash, one->path, &st, 0))
+ if (index_path(&one->oid, one->path, &st, 0))
die("cannot hash %s", one->path);
}
}
emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
sb.buf, sb.len, 0);
show_mode_change(opt, p, 0);
+ strbuf_release(&sb);
}
static void diff_summary(struct diff_options *opt, struct diff_filepair *p)
strbuf_addf(&sb, " (%d%%)\n", similarity_index(p));
emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
sb.buf, sb.len, 0);
+ strbuf_release(&sb);
}
show_mode_change(opt, p, !p->score);
break;
" >x &&
git diff --ignore-blank-lines >out &&
>expect &&
- test_cmp out expect
+ test_cmp expect out
'
test_expect_success 'ignore-blank-lines: only new lines with space' '
" >x &&
git diff -w --ignore-blank-lines >out &&
>expect &&
- test_cmp out expect
+ test_cmp expect out
'
test_expect_success 'ignore-blank-lines: after change' '
# Start testing the colored format for whitespace checks
test_expect_success 'setup diff colors' '
- git config color.diff always &&
git config color.diff.plain normal &&
git config color.diff.meta bold &&
git config color.diff.frag cyan &&
echo "test" >x &&
git commit -m "initial" x &&
echo "{NTN}" | tr "NT" "\n\t" >>x &&
- git -c color.diff=always diff | test_decode_color >current &&
+ git diff --color | test_decode_color >current &&
cat >expected <<-\EOF &&
<BOLD>diff --git a/x b/x<RESET>
echo "2. and a new line "
} >x &&
- git -c color.diff=always diff |
+ git diff --color |
test_decode_color >current &&
cat >expected <<-\EOF &&
test_expect_success 'test --ws-error-highlight option' '
- git -c color.diff=always diff --ws-error-highlight=default,old |
+ git diff --color --ws-error-highlight=default,old |
test_decode_color >current &&
test_cmp expect.default-old current &&
- git -c color.diff=always diff --ws-error-highlight=all |
+ git diff --color --ws-error-highlight=all |
test_decode_color >current &&
test_cmp expect.all current &&
- git -c color.diff=always diff --ws-error-highlight=none |
+ git diff --color --ws-error-highlight=none |
test_decode_color >current &&
test_cmp expect.none current
test_expect_success 'test diff.wsErrorHighlight config' '
- git -c color.diff=always -c diff.wsErrorHighlight=default,old diff |
+ git -c diff.wsErrorHighlight=default,old diff --color |
test_decode_color >current &&
test_cmp expect.default-old current &&
- git -c color.diff=always -c diff.wsErrorHighlight=all diff |
+ git -c diff.wsErrorHighlight=all diff --color |
test_decode_color >current &&
test_cmp expect.all current &&
- git -c color.diff=always -c diff.wsErrorHighlight=none diff |
+ git -c diff.wsErrorHighlight=none diff --color |
test_decode_color >current &&
test_cmp expect.none current
test_expect_success 'option overrides diff.wsErrorHighlight' '
- git -c color.diff=always -c diff.wsErrorHighlight=none \
- diff --ws-error-highlight=default,old |
+ git -c diff.wsErrorHighlight=none \
+ diff --color --ws-error-highlight=default,old |
test_decode_color >current &&
test_cmp expect.default-old current &&
- git -c color.diff=always -c diff.wsErrorHighlight=default \
- diff --ws-error-highlight=all |
+ git -c diff.wsErrorHighlight=default \
+ diff --color --ws-error-highlight=all |
test_decode_color >current &&
test_cmp expect.all current &&
- git -c color.diff=always -c diff.wsErrorHighlight=all \
- diff --ws-error-highlight=none |
+ git -c diff.wsErrorHighlight=all \
+ diff --color --ws-error-highlight=none |
test_decode_color >current &&
test_cmp expect.none current
git mv test.c main.c &&
test_config color.diff.oldMoved "normal red" &&
test_config color.diff.newMoved "normal green" &&
- git diff HEAD --color-moved=zebra --no-renames | test_decode_color >actual &&
+ git diff HEAD --color-moved=zebra --color --no-renames | test_decode_color >actual &&
cat >expected <<-\EOF &&
<BOLD>diff --git a/main.c b/main.c<RESET>
<BOLD>new file mode 100644<RESET>
bar();
}
EOF
- git diff HEAD --no-renames --color-moved=zebra| test_decode_color >actual &&
+ git diff HEAD --no-renames --color-moved=zebra --color | test_decode_color >actual &&
cat <<-\EOF >expected &&
<BOLD>diff --git a/main.c b/main.c<RESET>
<BOLD>index 27a619c..7cf9336 100644<RESET>
<BRED>-{<RESET>
<BLUE>-if (!u->is_allowed_foo)<RESET>
<BLUE>-return;<RESET>
- <BRED>-foo(u);<RESET>
- <BLUE>-}<RESET>
- <BLUE>-<RESET>
+ <RED>-foo(u);<RESET>
+ <RED>-}<RESET>
+ <RED>-<RESET>
int main()<RESET>
{<RESET>
foo();<RESET>
<RESET>
<BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
<BGREEN>+<RESET><BGREEN>{<RESET>
- <YELLOW>+<RESET><YELLOW>foo(u);<RESET>
+ <GREEN>+<RESET><GREEN>foo(u);<RESET>
<BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
<BGREEN>+<RESET><BGREEN>return;<RESET>
- <YELLOW>+<RESET><YELLOW>}<RESET>
- <YELLOW>+<RESET>
+ <GREEN>+<RESET><GREEN>}<RESET>
+ <GREEN>+<RESET>
int another_function()<RESET>
{<RESET>
bar();<RESET>
test_config color.diff.oldMovedAlternative "blue" &&
test_config color.diff.newMovedAlternative "yellow" &&
# needs previous test as setup
- git diff HEAD --no-renames --color-moved=plain| test_decode_color >actual &&
+ git diff HEAD --no-renames --color-moved=plain --color | test_decode_color >actual &&
cat <<-\EOF >expected &&
<BOLD>diff --git a/main.c b/main.c<RESET>
<BOLD>index 27a619c..7cf9336 100644<RESET>
test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
git reset --hard &&
cat <<-\EOF >lines.txt &&
- line 1
- line 2
- line 3
+ long line 1
+ long line 2
+ long line 3
line 4
line 5
line 6
line 11
line 12
line 13
- line 14
- line 15
- line 16
+ long line 14
+ long line 15
+ long line 16
EOF
git add lines.txt &&
git commit -m "add poetry" &&
line 7
line 8
line 9
- line 1
- line 2
- line 3
- line 14
- line 15
- line 16
+ long line 1
+ long line 2
+ long line 3
+ long line 14
+ long line 15
+ long line 16
line 10
line 11
line 12
test_config color.diff.newMovedDimmed "normal cyan" &&
test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
- git diff HEAD --no-renames --color-moved=dimmed_zebra| test_decode_color >actual &&
+ git diff HEAD --no-renames --color-moved=dimmed_zebra --color |
+ grep -v "index" |
+ test_decode_color >actual &&
cat <<-\EOF >expected &&
<BOLD>diff --git a/lines.txt b/lines.txt<RESET>
- <BOLD>index 47ea9c3..ba96a38 100644<RESET>
<BOLD>--- a/lines.txt<RESET>
<BOLD>+++ b/lines.txt<RESET>
<CYAN>@@ -1,16 +1,16 @@<RESET>
- <BMAGENTA>-line 1<RESET>
- <BMAGENTA>-line 2<RESET>
- <BMAGENTA>-line 3<RESET>
+ <BMAGENTA>-long line 1<RESET>
+ <BMAGENTA>-long line 2<RESET>
+ <BMAGENTA>-long line 3<RESET>
line 4<RESET>
line 5<RESET>
line 6<RESET>
line 7<RESET>
line 8<RESET>
line 9<RESET>
- <BCYAN>+<RESET><BCYAN>line 1<RESET>
- <BCYAN>+<RESET><BCYAN>line 2<RESET>
- <CYAN>+<RESET><CYAN>line 3<RESET>
- <YELLOW>+<RESET><YELLOW>line 14<RESET>
- <BYELLOW>+<RESET><BYELLOW>line 15<RESET>
- <BYELLOW>+<RESET><BYELLOW>line 16<RESET>
+ <BCYAN>+<RESET><BCYAN>long line 1<RESET>
+ <BCYAN>+<RESET><BCYAN>long line 2<RESET>
+ <CYAN>+<RESET><CYAN>long line 3<RESET>
+ <YELLOW>+<RESET><YELLOW>long line 14<RESET>
+ <BYELLOW>+<RESET><BYELLOW>long line 15<RESET>
+ <BYELLOW>+<RESET><BYELLOW>long line 16<RESET>
line 10<RESET>
line 11<RESET>
line 12<RESET>
line 13<RESET>
- <BMAGENTA>-line 14<RESET>
- <BMAGENTA>-line 15<RESET>
- <BMAGENTA>-line 16<RESET>
+ <BMAGENTA>-long line 14<RESET>
+ <BMAGENTA>-long line 15<RESET>
+ <BMAGENTA>-long line 16<RESET>
EOF
test_cmp expected actual
'
test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
test_config diff.colorMoved zebra &&
- git diff HEAD --no-renames --color-moved| test_decode_color >actual &&
+ git diff HEAD --no-renames --color-moved --color |
+ grep -v "index" |
+ test_decode_color >actual &&
cat <<-\EOF >expected &&
<BOLD>diff --git a/lines.txt b/lines.txt<RESET>
- <BOLD>index 47ea9c3..ba96a38 100644<RESET>
<BOLD>--- a/lines.txt<RESET>
<BOLD>+++ b/lines.txt<RESET>
<CYAN>@@ -1,16 +1,16 @@<RESET>
- <MAGENTA>-line 1<RESET>
- <MAGENTA>-line 2<RESET>
- <MAGENTA>-line 3<RESET>
+ <MAGENTA>-long line 1<RESET>
+ <MAGENTA>-long line 2<RESET>
+ <MAGENTA>-long line 3<RESET>
line 4<RESET>
line 5<RESET>
line 6<RESET>
line 7<RESET>
line 8<RESET>
line 9<RESET>
- <CYAN>+<RESET><CYAN>line 1<RESET>
- <CYAN>+<RESET><CYAN>line 2<RESET>
- <CYAN>+<RESET><CYAN>line 3<RESET>
- <YELLOW>+<RESET><YELLOW>line 14<RESET>
- <YELLOW>+<RESET><YELLOW>line 15<RESET>
- <YELLOW>+<RESET><YELLOW>line 16<RESET>
+ <CYAN>+<RESET><CYAN>long line 1<RESET>
+ <CYAN>+<RESET><CYAN>long line 2<RESET>
+ <CYAN>+<RESET><CYAN>long line 3<RESET>
+ <YELLOW>+<RESET><YELLOW>long line 14<RESET>
+ <YELLOW>+<RESET><YELLOW>long line 15<RESET>
+ <YELLOW>+<RESET><YELLOW>long line 16<RESET>
line 10<RESET>
line 11<RESET>
line 12<RESET>
line 13<RESET>
- <MAGENTA>-line 14<RESET>
- <MAGENTA>-line 15<RESET>
- <MAGENTA>-line 16<RESET>
+ <MAGENTA>-long line 14<RESET>
+ <MAGENTA>-long line 15<RESET>
+ <MAGENTA>-long line 16<RESET>
EOF
test_cmp expected actual
'
line 2
line 3
line 4
-line 5
-line 6
-line 7
+long line 5
+long line 6
+long line 7
EOF
git add lines.txt &&
git commit -m "add poetry" &&
cat <<\EOF >lines.txt &&
- line 5
- line 6
- line 7
+ long line 5
+ long line 6
+ long line 7
line 1
line 2
line 3
EOF
test_config color.diff.oldMoved "magenta" &&
test_config color.diff.newMoved "cyan" &&
- git diff HEAD --no-renames --color-moved| test_decode_color >actual &&
+ git diff HEAD --no-renames --color-moved --color |
+ grep -v "index" |
+ test_decode_color >actual &&
cat <<-\EOF >expected &&
<BOLD>diff --git a/lines.txt b/lines.txt<RESET>
- <BOLD>index 734156d..eb89ead 100644<RESET>
<BOLD>--- a/lines.txt<RESET>
<BOLD>+++ b/lines.txt<RESET>
<CYAN>@@ -1,7 +1,7 @@<RESET>
- <GREEN>+<RESET> <GREEN>line 5<RESET>
- <GREEN>+<RESET> <GREEN>line 6<RESET>
- <GREEN>+<RESET> <GREEN>line 7<RESET>
+ <GREEN>+<RESET> <GREEN>long line 5<RESET>
+ <GREEN>+<RESET> <GREEN>long line 6<RESET>
+ <GREEN>+<RESET> <GREEN>long line 7<RESET>
line 1<RESET>
line 2<RESET>
line 3<RESET>
line 4<RESET>
- <RED>-line 5<RESET>
- <RED>-line 6<RESET>
- <RED>-line 7<RESET>
+ <RED>-long line 5<RESET>
+ <RED>-long line 6<RESET>
+ <RED>-long line 7<RESET>
EOF
test_cmp expected actual &&
- git diff HEAD --no-renames -w --color-moved| test_decode_color >actual &&
+ git diff HEAD --no-renames -w --color-moved --color |
+ grep -v "index" |
+ test_decode_color >actual &&
cat <<-\EOF >expected &&
<BOLD>diff --git a/lines.txt b/lines.txt<RESET>
- <BOLD>index 734156d..eb89ead 100644<RESET>
<BOLD>--- a/lines.txt<RESET>
<BOLD>+++ b/lines.txt<RESET>
<CYAN>@@ -1,7 +1,7 @@<RESET>
- <CYAN>+<RESET> <CYAN>line 5<RESET>
- <CYAN>+<RESET> <CYAN>line 6<RESET>
- <CYAN>+<RESET> <CYAN>line 7<RESET>
+ <CYAN>+<RESET> <CYAN>long line 5<RESET>
+ <CYAN>+<RESET> <CYAN>long line 6<RESET>
+ <CYAN>+<RESET> <CYAN>long line 7<RESET>
line 1<RESET>
line 2<RESET>
line 3<RESET>
line 4<RESET>
- <MAGENTA>-line 5<RESET>
- <MAGENTA>-line 6<RESET>
- <MAGENTA>-line 7<RESET>
+ <MAGENTA>-long line 5<RESET>
+ <MAGENTA>-long line 6<RESET>
+ <MAGENTA>-long line 7<RESET>
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' '
+ git reset --hard &&
+ >bar &&
+ cat <<-\EOF >foo &&
+ irrelevant_line
+ line1
+ EOF
+ git add foo bar &&
+ git commit -m x &&
+
+ cat <<-\EOF >bar &&
+ line1
+ EOF
+ cat <<-\EOF >foo &&
+ irrelevant_line
+ EOF
+
+ git diff HEAD --color-moved=zebra --color --no-renames |
+ grep -v "index" |
+ test_decode_color >actual &&
+ cat >expected <<-\EOF &&
+ <BOLD>diff --git a/bar b/bar<RESET>
+ <BOLD>--- a/bar<RESET>
+ <BOLD>+++ b/bar<RESET>
+ <CYAN>@@ -0,0 +1 @@<RESET>
+ <GREEN>+<RESET><GREEN>line1<RESET>
+ <BOLD>diff --git a/foo b/foo<RESET>
+ <BOLD>--- a/foo<RESET>
+ <BOLD>+++ b/foo<RESET>
+ <CYAN>@@ -1,2 +1 @@<RESET>
+ irrelevant_line<RESET>
+ <RED>-line1<RESET>
+ EOF
+
+ test_cmp expected actual
+'
+
+test_expect_success '--color-moved respects MIN_ALNUM_COUNT' '
+ git reset --hard &&
+ cat <<-\EOF >foo &&
+ nineteen chars 456789
+ irrelevant_line
+ twenty chars 234567890
+ EOF
+ >bar &&
+ git add foo bar &&
+ git commit -m x &&
+
+ cat <<-\EOF >foo &&
+ irrelevant_line
+ EOF
+ cat <<-\EOF >bar &&
+ twenty chars 234567890
+ nineteen chars 456789
+ EOF
+
+ git diff HEAD --color-moved=zebra --color --no-renames |
+ grep -v "index" |
+ test_decode_color >actual &&
+ cat >expected <<-\EOF &&
+ <BOLD>diff --git a/bar b/bar<RESET>
+ <BOLD>--- a/bar<RESET>
+ <BOLD>+++ b/bar<RESET>
+ <CYAN>@@ -0,0 +1,2 @@<RESET>
+ <BOLD;CYAN>+<RESET><BOLD;CYAN>twenty chars 234567890<RESET>
+ <GREEN>+<RESET><GREEN>nineteen chars 456789<RESET>
+ <BOLD>diff --git a/foo b/foo<RESET>
+ <BOLD>--- a/foo<RESET>
+ <BOLD>+++ b/foo<RESET>
+ <CYAN>@@ -1,3 +1 @@<RESET>
+ <RED>-nineteen chars 456789<RESET>
+ irrelevant_line<RESET>
+ <BOLD;MAGENTA>-twenty chars 234567890<RESET>
+ EOF
+
+ test_cmp expected actual
+'
+
+test_expect_success '--color-moved treats adjacent blocks as separate for MIN_ALNUM_COUNT' '
+ git reset --hard &&
+ cat <<-\EOF >foo &&
+ 7charsA
+ irrelevant_line
+ 7charsB
+ 7charsC
+ EOF
+ >bar &&
+ git add foo bar &&
+ git commit -m x &&
+
+ cat <<-\EOF >foo &&
+ irrelevant_line
EOF
+ cat <<-\EOF >bar &&
+ 7charsB
+ 7charsC
+ 7charsA
+ EOF
+
+ git diff HEAD --color-moved=zebra --color --no-renames | grep -v "index" | test_decode_color >actual &&
+ cat >expected <<-\EOF &&
+ <BOLD>diff --git a/bar b/bar<RESET>
+ <BOLD>--- a/bar<RESET>
+ <BOLD>+++ b/bar<RESET>
+ <CYAN>@@ -0,0 +1,3 @@<RESET>
+ <GREEN>+<RESET><GREEN>7charsB<RESET>
+ <GREEN>+<RESET><GREEN>7charsC<RESET>
+ <GREEN>+<RESET><GREEN>7charsA<RESET>
+ <BOLD>diff --git a/foo b/foo<RESET>
+ <BOLD>--- a/foo<RESET>
+ <BOLD>+++ b/foo<RESET>
+ <CYAN>@@ -1,4 +1 @@<RESET>
+ <RED>-7charsA<RESET>
+ irrelevant_line<RESET>
+ <RED>-7charsB<RESET>
+ <RED>-7charsC<RESET>
+ EOF
+
test_cmp expected actual
'
echo foul >bananas/recipe &&
echo ripe >fruit.t &&
- git diff --submodule=diff --color-moved >actual &&
+ git diff --submodule=diff --color-moved --color >actual &&
# no move detection as the moved line is across repository boundaries.
test_decode_color <actual >decoded_actual &&
! grep BRED decoded_actual &&
# nor did we mess with it another way
- git diff --submodule=diff | test_decode_color >expect &&
+ git diff --submodule=diff --color | test_decode_color >expect &&
test_cmp expect decoded_actual
'
+ test_expect_success 'move detection with whitespace changes' '
+ test_when_finished "git reset --hard" &&
+ test_seq 10 >test &&
+ git add test &&
+ sed s/3/42/ <test >test.tmp &&
+ mv test.tmp test &&
+ git -c diff.colormoved diff --ignore-space-change -- test
+ '
+
test_done