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

[PATCH 5/8] diff.c: add a blocks mode for moved code detection

From
Stefan Beller <sbeller@google.com>
Date
May 17, 2018, 19:46 UTC
Message-ID
<20180517194653.48928-6-sbeller@google.com>
In-Reply-To
<20180517194653.48928-1-sbeller@google.com>

The new "blocks" mode provides a middle ground between plain and zebra. It is as intuitive (few colors) as plain, but still has the requirement for a minimum of lines/characters to count a block as moved.

Suggested-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
 (https://public-inbox.org/git/87o9j0uljo.fsf@evledraar.gmail.com/)
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/diff-options.txt |  8 ++++--
 diff.c                         |  6 +++--
 diff.h                         |  5 ++--
 t/t4015-diff-whitespace.sh     | 48 +++++++++++++++++++++++++++++++++-
 4 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index e3a44f03cdc..bb9f1b7cd82 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -276,10 +276,14 @@ plain::
 	that are added somewhere else in the diff. This mode picks up any
 	moved line, but it is not very useful in a review to determine
 	if a block of code was moved without permutation.
-zebra::
+blocks:
 	Blocks of moved text of at least 20 alphanumeric characters
 	are detected greedily. The detected blocks are
-	painted using either the 'color.diff.{old,new}Moved' color or
+	painted using either the 'color.diff.{old,new}Moved' color.
+	Adjacent blocks cannot be told apart.
+zebra::
+	Blocks of moved text are detected as in 'blocks' mode. The blocks
+	are painted using either the 'color.diff.{old,new}Moved' color or
 	'color.diff.{old,new}MovedAlternative'. The change between
 	the two colors indicates that a new block was detected.
 dimmed_zebra::
diff --git a/diff.c b/diff.c
index d1bae900cdc..95c51c0b7df 100644
--- a/diff.c
+++ b/diff.c
@@ -271,6 +271,8 @@ static int parse_color_moved(const char *arg)
 		return COLOR_MOVED_NO;
 	else if (!strcmp(arg, "plain"))
 		return COLOR_MOVED_PLAIN;
+	else if (!strcmp(arg, "blocks"))
+		return COLOR_MOVED_BLOCKS;
 	else if (!strcmp(arg, "zebra"))
 		return COLOR_MOVED_ZEBRA;
 	else if (!strcmp(arg, "default"))
@@ -278,7 +280,7 @@ static int parse_color_moved(const char *arg)
 	else if (!strcmp(arg, "dimmed_zebra"))
 		return COLOR_MOVED_ZEBRA_DIM;
 	else
-		return error(_("color moved setting must be one of 'no', 'default', 'zebra', 'dimmed_zebra', 'plain'"));
+		return error(_("color moved setting must be one of 'no', 'default', 'blocks', 'zebra', 'dimmed_zebra', 'plain'"));
 }
 
 int git_diff_ui_config(const char *var, const char *value, void *cb)
@@ -903,7 +905,7 @@ static void mark_color_as_moved(struct diff_options *o,
 
 		block_length++;
 
-		if (flipped_block)
+		if (flipped_block && o->color_moved != COLOR_MOVED_BLOCKS)
 			l->flags |= DIFF_SYMBOL_MOVED_LINE_ALT;
 	}
 	adjust_last_block(o, n, block_length);
diff --git a/diff.h b/diff.h
index d29560f822c..7bd4f182c33 100644
--- a/diff.h
+++ b/diff.h
@@ -208,8 +208,9 @@ struct diff_options {
 	enum {
 		COLOR_MOVED_NO = 0,
 		COLOR_MOVED_PLAIN = 1,
-		COLOR_MOVED_ZEBRA = 2,
-		COLOR_MOVED_ZEBRA_DIM = 3,
+		COLOR_MOVED_BLOCKS = 2,
+		COLOR_MOVED_ZEBRA = 3,
+		COLOR_MOVED_ZEBRA_DIM = 4,
 	} color_moved;
 	#define COLOR_MOVED_DEFAULT COLOR_MOVED_ZEBRA
 	#define COLOR_MOVED_MIN_ALNUM_COUNT 20
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 17df491a3ab..45091abb192 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -1223,7 +1223,7 @@ test_expect_success 'plain moved code, inside file' '
 	test_cmp expected actual
 '
 
-test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
+test_expect_success 'detect blocks of moved code' '
 	git reset --hard &&
 	cat <<-\EOF >lines.txt &&
 		long line 1
@@ -1271,6 +1271,52 @@ test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
 	test_config color.diff.newMovedDimmed "normal cyan" &&
 	test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
 	test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
+
+	git diff HEAD --no-renames --color-moved=blocks --color |
+		grep -v "index" |
+		test_decode_color >actual &&
+	cat <<-\EOF >expected &&
+	<BOLD>diff --git a/lines.txt b/lines.txt<RESET>
+	<BOLD>--- a/lines.txt<RESET>
+	<BOLD>+++ b/lines.txt<RESET>
+	<CYAN>@@ -1,16 +1,16 @@<RESET>
+	<MAGENTA>-long line 1<RESET>
+	<MAGENTA>-long line 2<RESET>
+	<MAGENTA>-long line 3<RESET>
+	 line 4<RESET>
+	 line 5<RESET>
+	 line 6<RESET>
+	 line 7<RESET>
+	 line 8<RESET>
+	 line 9<RESET>
+	<CYAN>+<RESET><CYAN>long line 1<RESET>
+	<CYAN>+<RESET><CYAN>long line 2<RESET>
+	<CYAN>+<RESET><CYAN>long line 3<RESET>
+	<CYAN>+<RESET><CYAN>long line 14<RESET>
+	<CYAN>+<RESET><CYAN>long line 15<RESET>
+	<CYAN>+<RESET><CYAN>long line 16<RESET>
+	 line 10<RESET>
+	 line 11<RESET>
+	 line 12<RESET>
+	 line 13<RESET>
+	<MAGENTA>-long line 14<RESET>
+	<MAGENTA>-long line 15<RESET>
+	<MAGENTA>-long line 16<RESET>
+	EOF
+	test_cmp expected actual
+
+'
+
+test_expect_success 'detect permutations inside moved code -- dimmed_zebra' '
+	# reuse setup from test before!
+	test_config color.diff.oldMoved "magenta" &&
+	test_config color.diff.newMoved "cyan" &&
+	test_config color.diff.oldMovedAlternative "blue" &&
+	test_config color.diff.newMovedAlternative "yellow" &&
+	test_config color.diff.oldMovedDimmed "normal magenta" &&
+	test_config color.diff.newMovedDimmed "normal cyan" &&
+	test_config color.diff.oldMovedAlternativeDimmed "normal blue" &&
+	test_config color.diff.newMovedAlternativeDimmed "normal yellow" &&
 	git diff HEAD --no-renames --color-moved=dimmed_zebra --color |
 		grep -v "index" |
 		test_decode_color >actual &&
-- 
2.17.0.582.gccdcbd54c44.dirty
Previous: Stefan BellerNext: Stefan Beller
Message 69 of 95 in “What's cooking in git.git (May 2018, #02; Thu, 17)”
  1. Junio C HamanoMay 17, 2018
  2. jk/branch-l-0-deprecation (was Re: What's cooking in git.git (May 2018, #02; Thu, 17))Kaartic Sivaraam, May 17, 2018
  3. Ævar Arnfjörð BjarmasonMay 17, 2018
  4. Kaartic SivaraamMay 17, 2018
  5. Ævar Arnfjörð BjarmasonMay 17, 2018
  6. Jeff KingMay 17, 2018
  7. jk/branch-l-0-deprecation (was Re: What's cooking in git.git (May 2018, #02; Thu, 17))Kaartic Sivaraam, May 24, 2018
  8. Jeff KingMay 24, 2018
  9. branch: issue "-l" deprecation warning after pager startsJeff King, May 24, 2018
  10. Junio C HamanoMay 25, 2018
  11. Jeff KingMay 25, 2018
  12. Junio C HamanoMay 25, 2018
  13. Junio C HamanoMay 25, 2018
  14. Jeff KingMay 25, 2018
  15. Junio C HamanoMay 26, 2018
  16. 0/3 usage: prefix all lines in `vreportf()`, not just the firstMartin Ågren, May 25, 2018
  17. 1/3 usage: extract `prefix_suffix_lines()` from `advise()`Martin Ågren, May 25, 2018
  18. Junio C HamanoMay 28, 2018
  19. Duy NguyenMay 28, 2018
  20. Jeff KingMay 29, 2018
  21. Jeff KingMay 29, 2018
  22. Junio C HamanoMay 30, 2018
  23. Junio C HamanoMay 30, 2018
  24. Martin ÅgrenMay 30, 2018
  25. Jeff KingMay 31, 2018
  26. 2/3 usage: prefix all lines in `vreportf()`, not just the firstMartin Ågren, May 25, 2018
  27. Junio C HamanoMay 28, 2018
  28. Duy NguyenMay 28, 2018
  29. Junio C HamanoMay 28, 2018
  30. Martin ÅgrenMay 29, 2018
  31. Junio C HamanoMay 29, 2018
  32. Martin ÅgrenMay 29, 2018
  33. Junio C HamanoMay 29, 2018
  34. Duy NguyenMay 29, 2018
  35. Martin ÅgrenMay 30, 2018
  36. Jeff KingMay 29, 2018
  37. Martin ÅgrenMay 30, 2018
  38. 3/3 usage: translate the "error: "-prefix and othersMartin Ågren, May 25, 2018
  39. Junio C HamanoMay 26, 2018
  40. Junio C HamanoMay 26, 2018
  41. Jeff KingMay 29, 2018
  42. Jeff KingMay 29, 2018
  43. Junio C HamanoMay 30, 2018
  44. Jeff KingMay 31, 2018
  45. Kaartic SivaraamMay 26, 2018
  46. Duy NguyenJun 2, 2018
  47. Jeff KingJun 2, 2018
  48. Kaartic SivaraamMay 26, 2018
  49. Jeff KingMay 29, 2018
  50. Junio C HamanoMay 30, 2018
  51. Jeff KingMay 31, 2018
  52. Junio C HamanoJun 1, 2018
  53. Kaartic.SivaraamMay 31, 2018
  54. Derrick StoleeMay 17, 2018
  55. Stefan BellerMay 17, 2018
  56. 0/2 Reroll 2 last commits of sb/object-store-replaceStefan Beller, May 17, 2018
  57. 1/2 object.c: free replace map in raw_object_store_clearStefan Beller, May 17, 2018
  58. 2/2 replace-object.c: remove the_repository from prepare_replace_objectStefan Beller, May 17, 2018
  59. merge-recursive: give notice when submodule commit gets fast-forwardedStefan Beller, May 17, 2018
  60. 0/1 rebased: inform about auto submodule ffLeif Middelschulte, May 18, 2018
  61. 0/1 rebased: inform about auto submodule ffLeif Middelschulte, May 18, 2018
  62. 1/1 Inform about fast-forwarding of submodules during mergeLeif Middelschulte, May 18, 2018
  63. Elijah NewrenMay 18, 2018
  64. Junio C HamanoMay 21, 2018
  65. 0/8 Reroll of sb/diff-color-move-moreStefan Beller, May 17, 2018
  66. 1/8 xdiff/xdiff.h: remove unused flagsStefan Beller, May 17, 2018
  67. 2/8 xdiff/xdiffi.c: remove unneeded function declarationsStefan Beller, May 17, 2018
  68. 4/8 diff.c: adjust hash function signature to match hashmap expectationStefan Beller, May 17, 2018
  69. 5/8 diff.c: add a blocks mode for moved code detectionStefan Beller, May 17, 2018
  70. 7/8 diff.c: add --color-moved-ignore-space-delta optionStefan Beller, May 17, 2018
  71. 8/8 diff: color-moved white space handling options imply color-movedStefan Beller, May 17, 2018
  72. 3/8 diff.c: do not pass diff options as keydata to hashmapStefan Beller, May 17, 2018
  73. 6/8 diff.c: decouple white space treatment from move detection algorithmStefan Beller, May 17, 2018
  74. Simon RuderichMay 18, 2018
  75. Stefan BellerMay 18, 2018
  76. Jonathan TanMay 17, 2018
  77. Jacob KellerJun 7, 2018
  78. Junio C HamanoMay 17, 2018
  79. Stefan BellerMay 17, 2018
  80. Junio C HamanoMay 17, 2018
  81. Stefan BellerMay 17, 2018
  82. brian m. carlsonMay 21, 2018
  83. Stefan BellerMay 21, 2018
  84. sb/submodule-move-nested breaks t7411 under GIT_FSMONITOR_TESTÆvar Arnfjörð Bjarmason, May 25, 2018
  85. Stefan BellerMay 25, 2018
  86. Stefan BellerMay 25, 2018
  87. Ævar Arnfjörð BjarmasonSep 6, 2018
  88. Stefan BellerSep 6, 2018
  89. Ben PeartSep 6, 2018
  90. Stefan BellerSep 6, 2018
  91. git-mv: allow submodules and fsmonitor to work togetherStefan Beller, Sep 6, 2018
  92. Ben PeartSep 10, 2018
  93. git-mv: allow submodules and fsmonitor to work togetherBen Peart, Sep 10, 2018
  94. Stefan BellerSep 10, 2018
  95. Ben PeartSep 10, 2018

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.