From: Brian Henderson <hidden> Date: 2016-08-30 14:07:44
On Mon, Aug 29, 2016 at 02:37:46PM -0700, Junio C Hamano wrote:
Brian Henderson [off-list ref] writes:
quoted
How does this look?
Drawing the graph helped me a lot in figuring out what I was
actually testing. thanks!
Yeah, I also am pleased to see the picture of what is being tested
in the test script.
With your sign-off, they would have been almost perfect ;-).
doh. fixed.
I left the subject as v4, probably mostly because I have this weird aversion to
increasing version numbers :) but I justified it by thinking that the actual
patch set isn't changing, I just added the sign-off (and updated the commit
messages per Jeff.) Hope that's ok.
thanks everyone for all your help!
Brian Henderson (3):
diff-highlight: add some tests
diff-highlight: add failing test for handling --graph output
diff-highlight: add support for --graph output
contrib/diff-highlight/Makefile | 5 +
contrib/diff-highlight/diff-highlight | 19 +-
contrib/diff-highlight/t/Makefile | 22 +++
contrib/diff-highlight/t/t9400-diff-highlight.sh | 223 +++++++++++++++++++++++
4 files changed, 263 insertions(+), 6 deletions(-)
create mode 100644 contrib/diff-highlight/Makefile
create mode 100644 contrib/diff-highlight/t/Makefile
create mode 100755 contrib/diff-highlight/t/t9400-diff-highlight.sh
--
2.9.3
@@ -0,0 +1,163 @@+#!/bin/sh++test_description='Test diff-highlight'++CURR_DIR=$(pwd)+TEST_OUTPUT_DIRECTORY=$(pwd)+TEST_DIRECTORY="$CURR_DIR"/../../../t+DIFF_HIGHLIGHT="$CURR_DIR"/../diff-highlight++CW="$(printf"\033[7m")"# white+CR="$(printf"\033[27m")"# reset++."$TEST_DIRECTORY"/test-lib.sh++if!test_have_prereqPERL+then+skip_all='skipping diff-highlight tests; perl not available'+test_done+fi++# dh_test is a test helper function which takes 3 file names as parameters. The+# first 2 files are used to generate diff and commit output, which is then+# piped through diff-highlight. The 3rd file should contain the expected output+# of diff-highlight (minus the diff/commit header, ie. everything after and+# including the first @@ line).+dh_test(){+a="$1"b="$2"&&++cat>patch.exp&&++{+cat"$a">file&&+gitaddfile&&+gitcommit-m"Add a file"&&++cat"$b">file&&+gitdifffile>diff.raw&&+gitcommit-am"Update a file"&&+gitshow>commit.raw+}>/dev/null&&++"$DIFF_HIGHLIGHT"<diff.raw|test_strip_patch_header>diff.act&&+"$DIFF_HIGHLIGHT"<commit.raw|test_strip_patch_header>commit.act&&+test_cmppatch.expdiff.act&&+test_cmppatch.expcommit.act+}++test_strip_patch_header(){+sed-n'/^@@/,$p'$*+}++test_expect_success'diff-highlight highlights the beginning of a line''+cat>a<<-\EOF&&+aaa+bbb+ccc+EOF++cat>b<<-\EOF&&+aaa+0bb+ccc+EOF++dh_testab<<-EOF+@@-1,3+1,3@@+aaa+-${CW}b${CR}bb++${CW}0${CR}bb+ccc+EOF+'++test_expect_success'diff-highlight highlights the end of a line''+cat>a<<-\EOF&&+aaa+bbb+ccc+EOF++cat>b<<-\EOF&&+aaa+bb0+ccc+EOF++dh_testab<<-EOF+@@-1,3+1,3@@+aaa+-bb${CW}b${CR}++bb${CW}0${CR}+ccc+EOF+'++test_expect_success'diff-highlight highlights the middle of a line''+cat>a<<-\EOF&&+aaa+bbb+ccc+EOF++cat>b<<-\EOF&&+aaa+b0b+ccc+EOF++dh_testab<<-EOF+@@-1,3+1,3@@+aaa+-b${CW}b${CR}b++b${CW}0${CR}b+ccc+EOF+'++test_expect_success'diff-highlight does not highlight whole line''+cat>a<<-\EOF&&+aaa+bbb+ccc+EOF++cat>b<<-\EOF&&+aaa+000+ccc+EOF++dh_testab<<-EOF+@@-1,3+1,3@@+aaa+-bbb++000+ccc+EOF+'++test_expect_failure'diff-highlight highlights mismatched hunk size''+cat>a<<-\EOF&&+aaa+bbb+EOF++cat>b<<-\EOF&&+aaa+b0b+ccc+EOF++dh_testab<<-EOF+@@-1,3+1,3@@+aaa+-b${CW}b${CR}b++b${CW}0${CR}b++ccc+EOF+'++# TODO add multi-byte test++test_done
@@ -21,6 +21,10 @@ my $RESET = "\x1b[m"; my $COLOR = qr/\x1b\[[0-9;]*m/; my $BORING = qr/$COLOR|\s/;+# The patch portion of git log -p --graph should only ever have preceding | and+# not / or \ as merge history only shows up on the commit line.+my $GRAPH = qr/$COLOR?\|$COLOR?\s+/;+ my @removed; my @added; my $in_hunk;
@@ -46,7 +50,7 @@ while (<>) { @added = (); print;- $in_hunk = /^$COLOR*[\@ ]/;+ $in_hunk = /^$GRAPH*$COLOR*[\@ ]/; } # Most of the time there is enough output to keep things streaming,
@@ -163,6 +167,9 @@ sub highlight_pair { } }+# we split either by $COLOR or by character. This has the side effect of+# leaving in graph cruft. It works because the graph cruft does not contain "-"+# or "+" sub split_line { local $_ = shift; return utf8::decode($_) ?
@@ -209,7 +209,7 @@ test_expect_failure 'diff-highlight highlights mismatched hunk size' '# TODO add multi-byte test-test_expect_failure'diff-highlight works with the --graph option''+test_expect_success'diff-highlight works with the --graph option''dh_test_setup_history&&# topo-order so that the order of the commits is the same as with --graph
@@ -49,6 +49,55 @@ test_strip_patch_header () {sed-n'/^@@/,$p'$*}+# dh_test_setup_history generates a contrived graph such that we have at least+# 1 nesting (E) and 2 nestings (F).+#+# A branch+# /+# D---E---F master+#+# git log --all --graph+# * commit+# | A+# | * commit+# | | F+# | * commit+# |/+# | E+# * commit+# D+#+dh_test_setup_history(){+echo"file1">file1&&+echo"file2">file2&&+echo"file3">file3&&++catfile1>file&&+gitaddfile&&+gitcommit-m"D"&&++gitcheckout-bbranch&&+catfile2>file&&+gitcommit-am"A"&&++gitcheckoutmaster&&+catfile2>file&&+gitcommit-am"E"&&++catfile3>file&&+gitcommit-am"F"+}++left_trim(){+"$PERL_PATH"-pe's/^\s+//'+}++trim_graph(){+# graphs start with * or |+# followed by a space or / or \+"$PERL_PATH"-pe's@^((\*|\|)( |/|\\))+@@'+}+ test_expect_success'diff-highlight highlights the beginning of a line''cat>a<<-\EOF&&aaa
@@ -160,4 +209,15 @@ test_expect_failure 'diff-highlight highlights mismatched hunk size' '# TODO add multi-byte test+test_expect_failure'diff-highlight works with the --graph option''+dh_test_setup_history&&++# topo-order so that the order of the commits is the same as with --graph+# trim graph elements so we can do a diff+# trim leading space because our trim_graph is not perfect+gitlog--branches-p--topo-order|"$DIFF_HIGHLIGHT"|left_trim>graph.exp&&+gitlog--branches-p--graph|"$DIFF_HIGHLIGHT"|trim_graph|left_trim>graph.act&&+test_cmpgraph.expgraph.act+'+ test_done
From: Jeff King <hidden> Date: 2016-08-31 05:02:40
On Tue, Aug 30, 2016 at 07:07:11AM -0700, Brian Henderson wrote:
On Mon, Aug 29, 2016 at 02:37:46PM -0700, Junio C Hamano wrote:
quoted
Brian Henderson [off-list ref] writes:
quoted
How does this look?
Drawing the graph helped me a lot in figuring out what I was
actually testing. thanks!
Yeah, I also am pleased to see the picture of what is being tested
in the test script.
With your sign-off, they would have been almost perfect ;-).
doh. fixed.
I left the subject as v4, probably mostly because I have this weird aversion to
increasing version numbers :) but I justified it by thinking that the actual
patch set isn't changing, I just added the sign-off (and updated the commit
messages per Jeff.) Hope that's ok.
Thanks. Here are a few patches to go on top. The first one could
arguably be squashed into your first patch (and I don't mind if Junio
wants to do so while applying, but I don't think it's worth you
re-sending).
The second one fleshes out the test scripts a bit, now that we have them
(yay!).
And the third fixes a bug that was reported to me off-list. I held back
because it touches the same lines as your topic (and as a bonus, I was
now able to write a test for it). It could be its own topic branch that
graduates separately, but seeing as it's contrib, I don't mind one big
diff-highlight potpourri topic if it makes things simpler.
[1/3]: diff-highlight: ignore test cruft
[2/3]: diff-highlight: add multi-byte tests
[3/3]: diff-highlight: avoid highlighting combined diffs
-Peff
From: Jeff King <hidden> Date: 2016-08-31 05:03:07
These are the same as in the normal t/.gitignore, with the
exception of ".prove", as our Makefile does not support it.
Signed-off-by: Jeff King <redacted>
---
contrib/diff-highlight/t/.gitignore | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 contrib/diff-highlight/t/.gitignore
From: Jeff King <hidden> Date: 2016-08-31 05:03:18
Now that we have a test suite for diff highlight, we can
show off the improvements from 8d00662 (diff-highlight: do
not split multibyte characters, 2015-04-03).
While we're at it, we can also add another case that
_doesn't_ work: combining code points are treated as their
own unit, which means that we may stick colors between them
and the character they are modifying (with the result that
the color is not shown in an xterm, though it's possible
that other terminals err the other way, and show the color
but not the accent). There's no fix here, but let's
document it as a failure.
Signed-off-by: Jeff King <redacted>
---
contrib/diff-highlight/t/t9400-diff-highlight.sh | 36 +++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
@@ -207,7 +207,41 @@ test_expect_failure 'diff-highlight highlights mismatched hunk size' 'EOF'-# TODO add multi-byte test+# These two code points share the same leading byte in UTF-8 representation;+# a naive byte-wise diff would highlight only the second byte.+#+# - U+00f3 ("o" with acute)+o_accent=$(printf'\303\263')+# - U+00f8 ("o" with stroke)+o_stroke=$(printf'\303\270')++test_expect_success'diff-highlight treats multibyte utf-8 as a unit''+echo"unic${o_accent}de">a&&+echo"unic${o_stroke}de">b&&+dh_testab<<-EOF+@@-1+1@@+-unic${CW}${o_accent}${CR}de++unic${CW}${o_stroke}${CR}de+EOF+'++# Unlike the UTF-8 above, these are combining code points which are meant+# to modify the character preceding them:+#+# - U+0301 (combining acute accent)+combine_accent=$(printf'\314\201')+# - U+0302 (combining circumflex)+combine_circum=$(printf'\314\202')++test_expect_failure'diff-highlight treats combining code points as a unit''+echo"unico${combine_accent}de">a&&+echo"unico${combine_circum}de">b&&+dh_testab<<-EOF+@@-1+1@@+-unic${CW}o${combine_accent}${CR}de++unic${CW}o${combine_circum}${CR}de+EOF+' test_expect_success'diff-highlight works with the --graph option''dh_test_setup_history&&
From: Jeff King <hidden> Date: 2016-08-31 05:05:47
The algorithm in diff-highlight only understands how to look
at two sides of a diff; it cannot correctly handle combined
diffs with multiple preimages. Often highlighting does not
trigger at all for these diffs because the line counts do
not match up. E.g., if we see:
- ours
-theirs
++resolved
we would not bother highlighting; it naively looks like a
single line went away, and then a separate hunk added
another single line.
But of course there are exceptions. E.g., if the other side
deleted the line, we might see:
- ours
++resolved
which looks like we dropped " ours" and added "+resolved".
This is only a small highlighting glitch (we highlight the
space and the "+" along with the content), but it's also the
tip of the iceberg. Even if we learned to find the true
content here (by noticing we are in a 3-way combined diff
and marking _two_ characters from the front of the line as
uninteresting), there are other more complicated cases where
we really do need to handle a 3-way hunk.
Let's just punt for now; we can recognize combined diffs by
the presence of extra "@" symbols in the hunk header, and
treat them as non-diff content.
Signed-off-by: Jeff King <redacted>
---
contrib/diff-highlight/diff-highlight | 2 +-
contrib/diff-highlight/t/t9400-diff-highlight.sh | 37 ++++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
@@ -254,4 +254,41 @@ test_expect_success 'diff-highlight works with the --graph option' 'test_cmpgraph.expgraph.act'+# Most combined diffs won't meet diff-highlight's line-number filter. So we+# create one here where one side drops a line and the other modifies it. That+# should result in a diff like:+#+# - modified content+# ++resolved content+#+# which naively looks like one side added "+resolved".+test_expect_success'diff-highlight ignores combined diffs''+echo"content">file&&+gitaddfile&&+gitcommit-mbase&&++>file&&+gitcommit-ammaster&&++gitcheckout-botherHEAD^&&+echo"modified content">file&&+gitcommit-amother&&++test_must_failgitmergemaster&&+echo"resolved content">file&&+gitcommit-amresolved&&++cat>expect<<-\EOF&&+---a/file++++b/file+@@@-1,1-1,0+1,1@@@+-modifiedcontent+++resolvedcontent+EOF++gitshow-c|"$DIFF_HIGHLIGHT">actual.raw&&+sed-n"/^---/,\$p"<actual.raw>actual&&+test_cmpexpectactual+'+ test_done