summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
authorPhillip Wood <phillip.wood@dunelm.org.uk>2018-11-23 11:16:58 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-01-10 18:38:29 (GMT)
commit0cd51e9d05e65608126c30fbb65a0cdd197cd570 (patch)
tree1a0d842134bc7dfc2a866614b69af2c419ba9568 /diff.c
parent21536d077f4b7b8a249f1fc894dafc38f06cef0f (diff)
downloadgit-0cd51e9d05e65608126c30fbb65a0cdd197cd570.zip
git-0cd51e9d05e65608126c30fbb65a0cdd197cd570.tar.gz
git-0cd51e9d05e65608126c30fbb65a0cdd197cd570.tar.bz2
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>
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/diff.c b/diff.c
index 941956d..03ffe46 100644
--- a/diff.c
+++ b/diff.c
@@ -794,9 +794,11 @@ static void moved_block_clear(struct moved_block *b)
memset(b, 0, sizeof(*b));
}
+#define INDENT_BLANKLINE INT_MIN
+
static void fill_es_indent_data(struct emitted_diff_symbol *es)
{
- unsigned int off = 0;
+ unsigned int off = 0, i;
int width = 0, tab_width = es->flags & WS_TAB_WIDTH_MASK;
const char *s = es->line;
const int len = es->len;
@@ -820,8 +822,18 @@ static void fill_es_indent_data(struct emitted_diff_symbol *es)
}
}
- es->indent_off = off;
- es->indent_width = width;
+ /* check if this line is blank */
+ for (i = off; i < len; i++)
+ if (!isspace(s[i]))
+ break;
+
+ if (i == len) {
+ es->indent_width = INDENT_BLANKLINE;
+ es->indent_off = len;
+ } else {
+ es->indent_off = off;
+ es->indent_width = width;
+ }
}
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,
b_width = b->indent_width;
int delta;
+ if (a_width == INDENT_BLANKLINE && b_width == INDENT_BLANKLINE) {
+ *out = INDENT_BLANKLINE;
+ return 1;
+ }
+
if (a->s == DIFF_SYMBOL_PLUS)
delta = a_width - b_width;
else
@@ -879,6 +896,10 @@ static int cmp_in_block_with_wsd(const struct diff_options *o,
if (al != bl)
return 1;
+ /* If 'l' and 'cur' are both blank then they match. */
+ if (a_width == INDENT_BLANKLINE && c_width == INDENT_BLANKLINE)
+ return 0;
+
/*
* The indent changes of the block are known and stored in pmb->wsd;
* 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,
else
delta = c_width - a_width;
+ /*
+ * If the previous lines of this block were all blank then set its
+ * whitespace delta.
+ */
+ if (pmb->wsd == INDENT_BLANKLINE)
+ pmb->wsd = delta;
+
return !(delta == pmb->wsd && al - a_off == cl - c_off &&
!memcmp(a, b, al) && !
memcmp(a + a_off, c + c_off, al - a_off));