Skip to content

Commit 0b96358

Browse files
committed
Merge branch 'jt/diff-color-move-fix'
A handful of bugfixes and an improvement to "diff --color-moved". * jt/diff-color-move-fix: diff: define block by number of alphanumeric chars diff: respect MIN_BLOCK_LENGTH for last block diff: avoid redundantly clearing a flag
2 parents b6c4058 + f0b8fb6 commit 0b96358

File tree

4 files changed

+236
-82
lines changed

4 files changed

+236
-82
lines changed

Documentation/diff-options.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,11 @@ plain::
254254
moved line, but it is not very useful in a review to determine
255255
if a block of code was moved without permutation.
256256
zebra::
257-
Blocks of moved code are detected greedily. The detected blocks are
257+
Blocks of moved text of at least 20 alphanumeric characters
258+
are detected greedily. The detected blocks are
258259
painted using either the 'color.diff.{old,new}Moved' color or
259260
'color.diff.{old,new}MovedAlternative'. The change between
260-
the two colors indicates that a new block was detected. If there
261-
are fewer than 3 adjacent moved lines, they are not marked up
262-
as moved, but the regular colors 'color.diff.{old,new}' will be
263-
used.
261+
the two colors indicates that a new block was detected.
264262
dimmed_zebra::
265263
Similar to 'zebra', but additional dimming of uninteresting parts
266264
of moved code is performed. The bordering lines of two adjacent

diff.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,38 @@ static int shrink_potential_moved_blocks(struct moved_entry **pmb,
855855
return rp + 1;
856856
}
857857

858+
/*
859+
* If o->color_moved is COLOR_MOVED_PLAIN, this function does nothing.
860+
*
861+
* Otherwise, if the last block has fewer alphanumeric characters than
862+
* COLOR_MOVED_MIN_ALNUM_COUNT, unset DIFF_SYMBOL_MOVED_LINE on all lines in
863+
* that block.
864+
*
865+
* The last block consists of the (n - block_length)'th line up to but not
866+
* including the nth line.
867+
*
868+
* NEEDSWORK: This uses the same heuristic as blame_entry_score() in blame.c.
869+
* Think of a way to unify them.
870+
*/
871+
static void adjust_last_block(struct diff_options *o, int n, int block_length)
872+
{
873+
int i, alnum_count = 0;
874+
if (o->color_moved == COLOR_MOVED_PLAIN)
875+
return;
876+
for (i = 1; i < block_length + 1; i++) {
877+
const char *c = o->emitted_symbols->buf[n - i].line;
878+
for (; *c; c++) {
879+
if (!isalnum(*c))
880+
continue;
881+
alnum_count++;
882+
if (alnum_count >= COLOR_MOVED_MIN_ALNUM_COUNT)
883+
return;
884+
}
885+
}
886+
for (i = 1; i < block_length + 1; i++)
887+
o->emitted_symbols->buf[n - i].flags &= ~DIFF_SYMBOL_MOVED_LINE;
888+
}
889+
858890
/* Find blocks of moved code, delegate actual coloring decision to helper */
859891
static void mark_color_as_moved(struct diff_options *o,
860892
struct hashmap *add_lines,
@@ -890,20 +922,13 @@ static void mark_color_as_moved(struct diff_options *o,
890922
}
891923

892924
if (!match) {
893-
if (block_length < COLOR_MOVED_MIN_BLOCK_LENGTH &&
894-
o->color_moved != COLOR_MOVED_PLAIN) {
895-
for (i = 0; i < block_length + 1; i++) {
896-
l = &o->emitted_symbols->buf[n - i];
897-
l->flags &= ~DIFF_SYMBOL_MOVED_LINE;
898-
}
899-
}
925+
adjust_last_block(o, n, block_length);
900926
pmb_nr = 0;
901927
block_length = 0;
902928
continue;
903929
}
904930

905931
l->flags |= DIFF_SYMBOL_MOVED_LINE;
906-
block_length++;
907932

908933
if (o->color_moved == COLOR_MOVED_PLAIN)
909934
continue;
@@ -933,11 +958,17 @@ static void mark_color_as_moved(struct diff_options *o,
933958
}
934959

935960
flipped_block = (flipped_block + 1) % 2;
961+
962+
adjust_last_block(o, n, block_length);
963+
block_length = 0;
936964
}
937965

966+
block_length++;
967+
938968
if (flipped_block)
939969
l->flags |= DIFF_SYMBOL_MOVED_LINE_ALT;
940970
}
971+
adjust_last_block(o, n, block_length);
941972

942973
free(pmb);
943974
}

diff.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ struct diff_options {
195195
COLOR_MOVED_ZEBRA_DIM = 3,
196196
} color_moved;
197197
#define COLOR_MOVED_DEFAULT COLOR_MOVED_ZEBRA
198-
#define COLOR_MOVED_MIN_BLOCK_LENGTH 3
198+
#define COLOR_MOVED_MIN_ALNUM_COUNT 20
199199
};
200200

201201
void diff_emit_submodule_del(struct diff_options *o, const char *line);

0 commit comments

Comments
 (0)