Skip to content

Commit 0cd51e9

Browse files
phillipwoodgitster
authored andcommitted
diff --color-moved-ws: handle blank lines
When using --color-moved-ws=allow-indentation-change allow lines with the same indentation change to be grouped across blank lines. For now this only works if the blank lines have been moved as well, not for blocks that have just had their indentation changed. This completes the changes to the implementation of --color-moved=allow-indentation-change. Running git diff --color-moved=allow-indentation-change v2.18.0 v2.19.0 now takes 5.0s. This is a saving of 41% from 8.5s for the optimized version of the previous implementation and 66% from the original which took 14.6s. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Reviewed-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 21536d0 commit 0cd51e9

File tree

2 files changed

+68
-7
lines changed

2 files changed

+68
-7
lines changed

diff.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,9 +794,11 @@ static void moved_block_clear(struct moved_block *b)
794794
memset(b, 0, sizeof(*b));
795795
}
796796

797+
#define INDENT_BLANKLINE INT_MIN
798+
797799
static void fill_es_indent_data(struct emitted_diff_symbol *es)
798800
{
799-
unsigned int off = 0;
801+
unsigned int off = 0, i;
800802
int width = 0, tab_width = es->flags & WS_TAB_WIDTH_MASK;
801803
const char *s = es->line;
802804
const int len = es->len;
@@ -820,8 +822,18 @@ static void fill_es_indent_data(struct emitted_diff_symbol *es)
820822
}
821823
}
822824

823-
es->indent_off = off;
824-
es->indent_width = width;
825+
/* check if this line is blank */
826+
for (i = off; i < len; i++)
827+
if (!isspace(s[i]))
828+
break;
829+
830+
if (i == len) {
831+
es->indent_width = INDENT_BLANKLINE;
832+
es->indent_off = len;
833+
} else {
834+
es->indent_off = off;
835+
es->indent_width = width;
836+
}
825837
}
826838

827839
static int compute_ws_delta(const struct emitted_diff_symbol *a,
@@ -836,6 +848,11 @@ static int compute_ws_delta(const struct emitted_diff_symbol *a,
836848
b_width = b->indent_width;
837849
int delta;
838850

851+
if (a_width == INDENT_BLANKLINE && b_width == INDENT_BLANKLINE) {
852+
*out = INDENT_BLANKLINE;
853+
return 1;
854+
}
855+
839856
if (a->s == DIFF_SYMBOL_PLUS)
840857
delta = a_width - b_width;
841858
else
@@ -879,6 +896,10 @@ static int cmp_in_block_with_wsd(const struct diff_options *o,
879896
if (al != bl)
880897
return 1;
881898

899+
/* If 'l' and 'cur' are both blank then they match. */
900+
if (a_width == INDENT_BLANKLINE && c_width == INDENT_BLANKLINE)
901+
return 0;
902+
882903
/*
883904
* The indent changes of the block are known and stored in pmb->wsd;
884905
* however we need to check if the indent changes of the current line
@@ -890,6 +911,13 @@ static int cmp_in_block_with_wsd(const struct diff_options *o,
890911
else
891912
delta = c_width - a_width;
892913

914+
/*
915+
* If the previous lines of this block were all blank then set its
916+
* whitespace delta.
917+
*/
918+
if (pmb->wsd == INDENT_BLANKLINE)
919+
pmb->wsd = delta;
920+
893921
return !(delta == pmb->wsd && al - a_off == cl - c_off &&
894922
!memcmp(a, b, al) && !
895923
memcmp(a + a_off, c + c_off, al - a_off));

t/t4015-diff-whitespace.sh

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,10 +1901,20 @@ test_expect_success 'compare whitespace delta incompatible with other space opti
19011901
test_i18ngrep allow-indentation-change err
19021902
'
19031903

1904+
EMPTY=''
19041905
test_expect_success 'compare mixed whitespace delta across moved blocks' '
19051906
19061907
git reset --hard &&
19071908
tr Q_ "\t " <<-EOF >text.txt &&
1909+
${EMPTY}
1910+
____too short without
1911+
${EMPTY}
1912+
___being grouped across blank line
1913+
${EMPTY}
1914+
context
1915+
lines
1916+
to
1917+
anchor
19081918
____Indented text to
19091919
_Q____be further indented by four spaces across
19101920
____Qseveral lines
@@ -1918,9 +1928,18 @@ test_expect_success 'compare mixed whitespace delta across moved blocks' '
19181928
git commit -m "add text.txt" &&
19191929
19201930
tr Q_ "\t " <<-EOF >text.txt &&
1931+
context
1932+
lines
1933+
to
1934+
anchor
19211935
QIndented text to
19221936
QQbe further indented by four spaces across
19231937
Q____several lines
1938+
${EMPTY}
1939+
QQtoo short without
1940+
${EMPTY}
1941+
Q_______being grouped across blank line
1942+
${EMPTY}
19241943
Q_QThese two lines have had their
19251944
indentation reduced by four spaces
19261945
QQdifferent indentation change
@@ -1937,7 +1956,16 @@ test_expect_success 'compare mixed whitespace delta across moved blocks' '
19371956
<BOLD>diff --git a/text.txt b/text.txt<RESET>
19381957
<BOLD>--- a/text.txt<RESET>
19391958
<BOLD>+++ b/text.txt<RESET>
1940-
<CYAN>@@ -1,7 +1,7 @@<RESET>
1959+
<CYAN>@@ -1,16 +1,16 @@<RESET>
1960+
<BOLD;MAGENTA>-<RESET>
1961+
<BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> too short without<RESET>
1962+
<BOLD;MAGENTA>-<RESET>
1963+
<BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> being grouped across blank line<RESET>
1964+
<BOLD;MAGENTA>-<RESET>
1965+
<RESET>context<RESET>
1966+
<RESET>lines<RESET>
1967+
<RESET>to<RESET>
1968+
<RESET>anchor<RESET>
19411969
<BOLD;MAGENTA>-<RESET><BOLD;MAGENTA> Indented text to<RESET>
19421970
<BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA> be further indented by four spaces across<RESET>
19431971
<BOLD;MAGENTA>-<RESET><BRED> <RESET> <BOLD;MAGENTA>several lines<RESET>
@@ -1948,9 +1976,14 @@ test_expect_success 'compare mixed whitespace delta across moved blocks' '
19481976
<BOLD;CYAN>+<RESET> <BOLD;CYAN>Indented text to<RESET>
19491977
<BOLD;CYAN>+<RESET> <BOLD;CYAN>be further indented by four spaces across<RESET>
19501978
<BOLD;CYAN>+<RESET> <BOLD;CYAN> several lines<RESET>
1951-
<BOLD;YELLOW>+<RESET> <BRED> <RESET> <BOLD;YELLOW>These two lines have had their<RESET>
1952-
<BOLD;YELLOW>+<RESET><BOLD;YELLOW>indentation reduced by four spaces<RESET>
1953-
<BOLD;CYAN>+<RESET> <BOLD;CYAN>different indentation change<RESET>
1979+
<BOLD;YELLOW>+<RESET>
1980+
<BOLD;YELLOW>+<RESET> <BOLD;YELLOW>too short without<RESET>
1981+
<BOLD;YELLOW>+<RESET>
1982+
<BOLD;YELLOW>+<RESET> <BOLD;YELLOW> being grouped across blank line<RESET>
1983+
<BOLD;YELLOW>+<RESET>
1984+
<BOLD;CYAN>+<RESET> <BRED> <RESET> <BOLD;CYAN>These two lines have had their<RESET>
1985+
<BOLD;CYAN>+<RESET><BOLD;CYAN>indentation reduced by four spaces<RESET>
1986+
<BOLD;YELLOW>+<RESET> <BOLD;YELLOW>different indentation change<RESET>
19541987
<GREEN>+<RESET><BRED> <RESET> <GREEN>too short<RESET>
19551988
EOF
19561989

0 commit comments

Comments
 (0)