Skip to content

Commit 51da15e

Browse files
stefanbellergitster
authored andcommitted
diff.c: add a blocks mode for moved code detection
The new "blocks" mode provides a middle ground between plain and zebra. It is as intuitive (few colors) as plain, but still has the requirement for a minimum of lines/characters to count a block as moved. Suggested-by: Ævar Arnfjörð Bjarmason <[email protected]> (https://public-inbox.org/git/[email protected]/) Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ee1df66 commit 51da15e

File tree

4 files changed

+60
-8
lines changed

4 files changed

+60
-8
lines changed

Documentation/diff-options.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,14 @@ plain::
276276
that are added somewhere else in the diff. This mode picks up any
277277
moved line, but it is not very useful in a review to determine
278278
if a block of code was moved without permutation.
279-
zebra::
279+
blocks::
280280
Blocks of moved text of at least 20 alphanumeric characters
281281
are detected greedily. The detected blocks are
282-
painted using either the 'color.diff.{old,new}Moved' color or
282+
painted using either the 'color.diff.{old,new}Moved' color.
283+
Adjacent blocks cannot be told apart.
284+
zebra::
285+
Blocks of moved text are detected as in 'blocks' mode. The blocks
286+
are painted using either the 'color.diff.{old,new}Moved' color or
283287
'color.diff.{old,new}MovedAlternative'. The change between
284288
the two colors indicates that a new block was detected.
285289
dimmed_zebra::

diff.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,16 @@ static int parse_color_moved(const char *arg)
271271
return COLOR_MOVED_NO;
272272
else if (!strcmp(arg, "plain"))
273273
return COLOR_MOVED_PLAIN;
274+
else if (!strcmp(arg, "blocks"))
275+
return COLOR_MOVED_BLOCKS;
274276
else if (!strcmp(arg, "zebra"))
275277
return COLOR_MOVED_ZEBRA;
276278
else if (!strcmp(arg, "default"))
277279
return COLOR_MOVED_DEFAULT;
278280
else if (!strcmp(arg, "dimmed_zebra"))
279281
return COLOR_MOVED_ZEBRA_DIM;
280282
else
281-
return error(_("color moved setting must be one of 'no', 'default', 'zebra', 'dimmed_zebra', 'plain'"));
283+
return error(_("color moved setting must be one of 'no', 'default', 'blocks', 'zebra', 'dimmed_zebra', 'plain'"));
282284
}
283285

284286
int git_diff_ui_config(const char *var, const char *value, void *cb)
@@ -903,7 +905,7 @@ static void mark_color_as_moved(struct diff_options *o,
903905

904906
block_length++;
905907

906-
if (flipped_block)
908+
if (flipped_block && o->color_moved != COLOR_MOVED_BLOCKS)
907909
l->flags |= DIFF_SYMBOL_MOVED_LINE_ALT;
908910
}
909911
adjust_last_block(o, n, block_length);

diff.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,9 @@ struct diff_options {
208208
enum {
209209
COLOR_MOVED_NO = 0,
210210
COLOR_MOVED_PLAIN = 1,
211-
COLOR_MOVED_ZEBRA = 2,
212-
COLOR_MOVED_ZEBRA_DIM = 3,
211+
COLOR_MOVED_BLOCKS = 2,
212+
COLOR_MOVED_ZEBRA = 3,
213+
COLOR_MOVED_ZEBRA_DIM = 4,
213214
} color_moved;
214215
#define COLOR_MOVED_DEFAULT COLOR_MOVED_ZEBRA
215216
#define COLOR_MOVED_MIN_ALNUM_COUNT 20

t/t4015-diff-whitespace.sh

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ test_expect_success 'plain moved code, inside file' '
12231223
test_cmp expected actual
12241224
'
12251225

1226-
test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
1226+
test_expect_success 'detect blocks of moved code' '
12271227
git reset --hard &&
12281228
cat <<-\EOF >lines.txt &&
12291229
long line 1
@@ -1271,6 +1271,50 @@ test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
12711271
test_config color.diff.newMovedDimmed "normal cyan" &&
12721272
test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
12731273
test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
1274+
git diff HEAD --no-renames --color-moved=blocks --color >actual.raw &&
1275+
grep -v "index" actual.raw | test_decode_color >actual &&
1276+
cat <<-\EOF >expected &&
1277+
<BOLD>diff --git a/lines.txt b/lines.txt<RESET>
1278+
<BOLD>--- a/lines.txt<RESET>
1279+
<BOLD>+++ b/lines.txt<RESET>
1280+
<CYAN>@@ -1,16 +1,16 @@<RESET>
1281+
<MAGENTA>-long line 1<RESET>
1282+
<MAGENTA>-long line 2<RESET>
1283+
<MAGENTA>-long line 3<RESET>
1284+
line 4<RESET>
1285+
line 5<RESET>
1286+
line 6<RESET>
1287+
line 7<RESET>
1288+
line 8<RESET>
1289+
line 9<RESET>
1290+
<CYAN>+<RESET><CYAN>long line 1<RESET>
1291+
<CYAN>+<RESET><CYAN>long line 2<RESET>
1292+
<CYAN>+<RESET><CYAN>long line 3<RESET>
1293+
<CYAN>+<RESET><CYAN>long line 14<RESET>
1294+
<CYAN>+<RESET><CYAN>long line 15<RESET>
1295+
<CYAN>+<RESET><CYAN>long line 16<RESET>
1296+
line 10<RESET>
1297+
line 11<RESET>
1298+
line 12<RESET>
1299+
line 13<RESET>
1300+
<MAGENTA>-long line 14<RESET>
1301+
<MAGENTA>-long line 15<RESET>
1302+
<MAGENTA>-long line 16<RESET>
1303+
EOF
1304+
test_cmp expected actual
1305+
1306+
'
1307+
1308+
test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
1309+
# reuse setup from test before!
1310+
test_config color.diff.oldMoved "magenta" &&
1311+
test_config color.diff.newMoved "cyan" &&
1312+
test_config color.diff.oldMovedAlternative "blue" &&
1313+
test_config color.diff.newMovedAlternative "yellow" &&
1314+
test_config color.diff.oldMovedDimmed "normal magenta" &&
1315+
test_config color.diff.newMovedDimmed "normal cyan" &&
1316+
test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
1317+
test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
12741318
git diff HEAD --no-renames --color-moved=dimmed_zebra --color >actual.raw &&
12751319
grep -v "index" actual.raw | test_decode_color >actual &&
12761320
cat <<-\EOF >expected &&
@@ -1669,7 +1713,8 @@ test_expect_success '--color-moved treats adjacent blocks as separate for MIN_AL
16691713
7charsA
16701714
EOF
16711715
1672-
git diff HEAD --color-moved=zebra --color --no-renames | grep -v "index" | test_decode_color >actual &&
1716+
git diff HEAD --color-moved=zebra --color --no-renames >actual.raw &&
1717+
grep -v "index" actual.raw | test_decode_color >actual &&
16731718
cat >expected <<-\EOF &&
16741719
<BOLD>diff --git a/bar b/bar<RESET>
16751720
<BOLD>--- a/bar<RESET>

0 commit comments

Comments
 (0)