git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] diff-highlight: avoid highlighting combined diffs

From
Jeff King <peff@peff.net>
Date
Aug 31, 2016, 05:05 UTC
Message-ID
<20160831050538.53fki52cvwlmkd6y@sigill.intra.peff.net>
In-Reply-To
<20160831050229.cabhfzqcpcpvkugl@sigill.intra.peff.net>

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 <peff@peff.net>
---
 contrib/diff-highlight/diff-highlight            |  2 +-
 contrib/diff-highlight/t/t9400-diff-highlight.sh | 37 ++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/contrib/diff-highlight/diff-highlight b/contrib/diff-highlight/diff-highlight
index 9280c88..81bd804 100755
--- a/contrib/diff-highlight/diff-highlight
+++ b/contrib/diff-highlight/diff-highlight
@@ -36,7 +36,7 @@ $SIG{PIPE} = 'DEFAULT';
 while (<>) {
 	if (!$in_hunk) {
 		print;
-		$in_hunk = /^$GRAPH*$COLOR*\@/;
+		$in_hunk = /^$GRAPH*$COLOR*\@\@ /;
 	}
 	elsif (/^$GRAPH*$COLOR*-/) {
 		push @removed, $_;
diff --git a/contrib/diff-highlight/t/t9400-diff-highlight.sh b/contrib/diff-highlight/t/t9400-diff-highlight.sh
index 7d034aa..64dd9f7 100755
--- a/contrib/diff-highlight/t/t9400-diff-highlight.sh
+++ b/contrib/diff-highlight/t/t9400-diff-highlight.sh
@@ -254,4 +254,41 @@ test_expect_success 'diff-highlight works with the --graph option' '
 	test_cmp graph.exp graph.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 &&
+	git add file &&
+	git commit -m base &&
+
+	>file &&
+	git commit -am master &&
+
+	git checkout -b other HEAD^ &&
+	echo "modified content" >file &&
+	git commit -am other &&
+
+	test_must_fail git merge master &&
+	echo "resolved content" >file &&
+	git commit -am resolved &&
+
+	cat >expect <<-\EOF &&
+	--- a/file
+	+++ b/file
+	@@@ -1,1 -1,0 +1,1 @@@
+	- modified content
+	++resolved content
+	EOF
+
+	git show -c | "$DIFF_HIGHLIGHT" >actual.raw &&
+	sed -n "/^---/,\$p" <actual.raw >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
2.10.0.rc2.125.gcfb3d08
Previous: Jeff KingNext: Jeff King
Message 26 of 30 in “diff-highlight: add support for git log --graph output.”
  1. 0/3 diff-highlight: add support for git log --graph output.Brian Henderson, Aug 19, 2016
  2. 2/3 diff-highlight: add failing test for handling --graph output.Brian Henderson, Aug 19, 2016
  3. Junio C HamanoAug 19, 2016
  4. 1/3 diff-highlight: add some tests.Brian Henderson, Aug 19, 2016
  5. Junio C HamanoAug 19, 2016
  6. Brian HendersonAug 19, 2016
  7. Eric WongAug 19, 2016
  8. diff-highlight: add some tests.Brian Henderson, Aug 19, 2016
  9. Junio C HamanoAug 19, 2016
  10. Jeff KingAug 19, 2016
  11. Junio C HamanoAug 19, 2016
  12. diff-highlight: add some tests.Brian Henderson, Aug 22, 2016
  13. Jeff KingAug 23, 2016
  14. 0/3 diff-highlight: add support for --graph optionBrian Henderson, Aug 29, 2016
  15. 2/3 diff-highlight: add failing test for handling --graph output.Brian Henderson, Aug 29, 2016
  16. 1/3 diff-highlight: add some tests.Brian Henderson, Aug 29, 2016
  17. 3/3 diff-highlight: add support for --graph output.Brian Henderson, Aug 29, 2016
  18. Junio C HamanoAug 29, 2016
  19. 0/3 diff-highlight: add support for --graph optionBrian Henderson, Aug 30, 2016
  20. 1/3 diff-highlight: add some testsBrian Henderson, Aug 30, 2016
  21. 3/3 diff-highlight: add support for --graph outputBrian Henderson, Aug 30, 2016
  22. 2/3 diff-highlight: add failing test for handling --graph outputBrian Henderson, Aug 30, 2016
  23. Jeff KingAug 31, 2016
  24. 1/3 diff-highlight: ignore test cruftJeff King, Aug 31, 2016
  25. 2/3 diff-highlight: add multi-byte testsJeff King, Aug 31, 2016
  26. 3/3 diff-highlight: avoid highlighting combined diffsJeff King, Aug 31, 2016
  27. Jeff KingAug 30, 2016
  28. Junio C HamanoAug 19, 2016
  29. 3/3 diff-highlight: add support for --graph output.Brian Henderson, Aug 19, 2016
  30. Junio C HamanoAug 19, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.