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

[PATCHv2 23/25] diff.c: color moved lines differently, plain mode

From
Stefan Beller <sbeller@google.com>
Date
Jun 30, 2017, 20:53 UTC
Message-ID
<20170630205310.7380-24-sbeller@google.com>
In-Reply-To
<20170630205310.7380-1-sbeller@google.com>

Add the 'plain' mode for move detection of code. This omits the checking for adjacent blocks, so it is not as useful. If you have a lot of the same blocks moved in the same patch, the 'Zebra' would end up slow as it is O(n^2) (n is number of same blocks). So this may be useful there and is generally easy to add. Instead be very literal at the move detection, do not skip over short blocks here.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 diff.c                     | 10 +++++++--
 diff.h                     |  1 +
 t/t4015-diff-whitespace.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/diff.c b/diff.c
index 084ecc5678..79ea592388 100644
--- a/diff.c
+++ b/diff.c
@@ -256,12 +256,14 @@ static int parse_color_moved(const char *arg)
 
 	if (!strcmp(arg, "no"))
 		return COLOR_MOVED_NO;
+	else if (!strcmp(arg, "plain"))
+		return COLOR_MOVED_PLAIN;
 	else if (!strcmp(arg, "zebra"))
 		return COLOR_MOVED_ZEBRA;
 	else if (!strcmp(arg, "default"))
 		return COLOR_MOVED_DEFAULT;
 	else
-		return error(_("color moved setting must be one of 'no', 'default', 'zebra'"));
+		return error(_("color moved setting must be one of 'no', 'default', 'zebra', 'plain'"));
 }
 
 int git_diff_ui_config(const char *var, const char *value, void *cb)
@@ -879,7 +881,8 @@ static void mark_color_as_moved(struct diff_options *o,
 		}
 
 		if (!match) {
-			if (block_length < COLOR_MOVED_MIN_BLOCK_LENGTH) {
+			if (block_length < COLOR_MOVED_MIN_BLOCK_LENGTH &&
+			    o->color_moved != COLOR_MOVED_PLAIN) {
 				for (i = 0; i < block_length + 1; i++) {
 					l = &o->emitted_symbols->buf[n - i];
 					l->flags &= ~DIFF_SYMBOL_MOVED_LINE;
@@ -893,6 +896,9 @@ static void mark_color_as_moved(struct diff_options *o,
 		l->flags |= DIFF_SYMBOL_MOVED_LINE;
 		block_length++;
 
+		if (o->color_moved == COLOR_MOVED_PLAIN)
+			continue;
+
 		/* Check any potential block runs, advance each or nullify */
 		for (i = 0; i < pmb_nr; i++) {
 			struct moved_entry *p = pmb[i];
diff --git a/diff.h b/diff.h
index 3196802673..4cfd609c54 100644
--- a/diff.h
+++ b/diff.h
@@ -190,6 +190,7 @@ struct diff_options {
 	struct emitted_diff_symbols *emitted_symbols;
 	enum {
 		COLOR_MOVED_NO = 0,
+		COLOR_MOVED_PLAIN = 1,
 		COLOR_MOVED_ZEBRA = 2,
 	} color_moved;
 	#define COLOR_MOVED_DEFAULT COLOR_MOVED_ZEBRA
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 29704ae14e..d1d7b99990 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -986,7 +986,7 @@ test_expect_success 'detect moved code, complete file' '
 	git mv test.c main.c &&
 	test_config color.diff.oldMoved "normal red" &&
 	test_config color.diff.newMoved "normal green" &&
-	git diff HEAD --color-moved --no-renames | test_decode_color >actual &&
+	git diff HEAD --color-moved=zebra --no-renames | test_decode_color >actual &&
 	cat >expected <<-\EOF &&
 	<BOLD>diff --git a/main.c b/main.c<RESET>
 	<BOLD>new file mode 100644<RESET>
@@ -1130,6 +1130,55 @@ test_expect_success 'detect malicious moved code, inside file' '
 	test_cmp expected actual
 '
 
+test_expect_success 'plain moved code, inside file' '
+	test_config color.diff.oldMoved "normal red" &&
+	test_config color.diff.newMoved "normal green" &&
+	test_config color.diff.oldMovedAlternative "blue" &&
+	test_config color.diff.newMovedAlternative "yellow" &&
+	# needs previous test as setup
+	git diff HEAD --no-renames --color-moved=plain| test_decode_color >actual &&
+	cat <<-\EOF >expected &&
+	<BOLD>diff --git a/main.c b/main.c<RESET>
+	<BOLD>index 27a619c..7cf9336 100644<RESET>
+	<BOLD>--- a/main.c<RESET>
+	<BOLD>+++ b/main.c<RESET>
+	<CYAN>@@ -5,13 +5,6 @@<RESET> <RESET>printf("Hello ");<RESET>
+	 printf("World\n");<RESET>
+	 }<RESET>
+	 <RESET>
+	<BRED>-int secure_foo(struct user *u)<RESET>
+	<BRED>-{<RESET>
+	<BRED>-if (!u->is_allowed_foo)<RESET>
+	<BRED>-return;<RESET>
+	<BRED>-foo(u);<RESET>
+	<BRED>-}<RESET>
+	<BRED>-<RESET>
+	 int main()<RESET>
+	 {<RESET>
+	 foo();<RESET>
+	<BOLD>diff --git a/test.c b/test.c<RESET>
+	<BOLD>index 1dc1d85..2bedec9 100644<RESET>
+	<BOLD>--- a/test.c<RESET>
+	<BOLD>+++ b/test.c<RESET>
+	<CYAN>@@ -4,6 +4,13 @@<RESET> <RESET>int bar()<RESET>
+	 printf("Hello World, but different\n");<RESET>
+	 }<RESET>
+	 <RESET>
+	<BGREEN>+<RESET><BGREEN>int secure_foo(struct user *u)<RESET>
+	<BGREEN>+<RESET><BGREEN>{<RESET>
+	<BGREEN>+<RESET><BGREEN>foo(u);<RESET>
+	<BGREEN>+<RESET><BGREEN>if (!u->is_allowed_foo)<RESET>
+	<BGREEN>+<RESET><BGREEN>return;<RESET>
+	<BGREEN>+<RESET><BGREEN>}<RESET>
+	<BGREEN>+<RESET>
+	 int another_function()<RESET>
+	 {<RESET>
+	 bar();<RESET>
+	EOF
+
+	test_cmp expected actual
+'
+
 test_expect_success 'no effect from --color-moved with --word-diff' '
 	cat <<-\EOF >text.txt &&
 	Lorem Ipsum is simply dummy text of the printing and typesetting industry.
-- 
2.13.0.31.g9b732c453e
Previous: Stefan BellerNext: Stefan Beller
Message 50 of 63 in “Reroll of sb/diff-color-moved.”
  1. 00/25 Reroll of sb/diff-color-moved.Stefan Beller, Jun 30, 2017
  2. 02/25 diff.c: move line ending check into emit_hunk_headerStefan Beller, Jun 30, 2017
  3. 12/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_HEADERStefan Beller, Jun 30, 2017
  4. 04/25 diff.c: introduce emit_diff_symbolStefan Beller, Jun 30, 2017
  5. 06/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_CONTEXT_FRAGINFOStefan Beller, Jun 30, 2017
  6. 01/25 diff.c: readability fixStefan Beller, Jun 30, 2017
  7. 05/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_CONTEXT_MARKERStefan Beller, Jun 30, 2017
  8. 03/25 diff.c: factor out diff_flush_patch_all_file_pairsStefan Beller, Jun 30, 2017
  9. 07/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_NO_LF_EOFStefan Beller, Jun 30, 2017
  10. 18/25 diff.c: convert word diffing to use emit_diff_symbolStefan Beller, Jun 30, 2017
  11. 13/25 diff.c: emit_diff_symbol learns about DIFF_SYMBOL_BINARY_FILESStefan Beller, Jun 30, 2017
  12. 21/25 diff.c: buffer all output if asked toStefan Beller, Jun 30, 2017
  13. 20/25 diff.c: emit_diff_symbol learns about DIFF_SYMBOL_SUMMARYStefan Beller, Jun 30, 2017
  14. 22/25 diff.c: color moved lines differentlyStefan Beller, Jun 30, 2017
  15. Junio C HamanoJun 30, 2017
  16. Stefan BellerJun 30, 2017
  17. Junio C HamanoJun 30, 2017
  18. 24/25 diff.c: add dimming to moved line detectionStefan Beller, Jun 30, 2017
  19. 25/25 diff: document the new --color-moved settingStefan Beller, Jun 30, 2017
  20. Simon RuderichJun 30, 2017
  21. Stefan BellerJun 30, 2017
  22. Simon RuderichJun 30, 2017
  23. Stefan BellerJun 30, 2017
  24. 19/25 diff.c: emit_diff_symbol learns about DIFF_SYMBOL_STAT_SEPStefan Beller, Jun 30, 2017
  25. 11/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_FILEPAIR_{PLUS, MINUS}Stefan Beller, Jun 30, 2017
  26. 23/25 diff.c: color moved lines differently, plain modeStefan Beller, Jun 30, 2017
  27. 15/25 submodule.c: migrate diff output to use emit_diff_symbolStefan Beller, Jun 30, 2017
  28. 14/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_REWRITE_DIFFStefan Beller, Jun 30, 2017
  29. 16/25 diff.c: convert emit_binary_diff_body to use emit_diff_symbolStefan Beller, Jun 30, 2017
  30. 10/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_CONTEXT_INCOMPLETEStefan Beller, Jun 30, 2017
  31. 17/25 diff.c: convert show_stats to use emit_diff_symbolStefan Beller, Jun 30, 2017
  32. 09/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_WORDS[_PORCELAIN]Stefan Beller, Jun 30, 2017
  33. 08/25 diff.c: migrate emit_line_checked to use emit_diff_symbolStefan Beller, Jun 30, 2017
  34. 00/25 Reroll of sb/diff-color-moved.Stefan Beller, Jun 30, 2017
  35. 01/25 diff.c: readability fixStefan Beller, Jun 30, 2017
  36. 02/25 diff.c: move line ending check into emit_hunk_headerStefan Beller, Jun 30, 2017
  37. 06/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_CONTEXT_FRAGINFOStefan Beller, Jun 30, 2017
  38. 07/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_NO_LF_EOFStefan Beller, Jun 30, 2017
  39. 05/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_CONTEXT_MARKERStefan Beller, Jun 30, 2017
  40. 12/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_HEADERStefan Beller, Jun 30, 2017
  41. 13/25 diff.c: emit_diff_symbol learns about DIFF_SYMBOL_BINARY_FILESStefan Beller, Jun 30, 2017
  42. 14/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_REWRITE_DIFFStefan Beller, Jun 30, 2017
  43. 09/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_WORDS[_PORCELAIN]Stefan Beller, Jun 30, 2017
  44. 20/25 diff.c: emit_diff_symbol learns about DIFF_SYMBOL_SUMMARYStefan Beller, Jun 30, 2017
  45. 18/25 diff.c: convert word diffing to use emit_diff_symbolStefan Beller, Jun 30, 2017
  46. 17/25 diff.c: convert show_stats to use emit_diff_symbolStefan Beller, Jun 30, 2017
  47. 15/25 submodule.c: migrate diff output to use emit_diff_symbolStefan Beller, Jun 30, 2017
  48. 21/25 diff.c: buffer all output if asked toStefan Beller, Jun 30, 2017
  49. 25/25 diff: document the new --color-moved settingStefan Beller, Jun 30, 2017
  50. 23/25 diff.c: color moved lines differently, plain modeStefan Beller, Jun 30, 2017
  51. 22/25 diff.c: color moved lines differentlyStefan Beller, Jun 30, 2017
  52. Junio C HamanoJun 30, 2017
  53. Stefan BellerJun 30, 2017
  54. Junio C HamanoJun 30, 2017
  55. 24/25 diff.c: add dimming to moved line detectionStefan Beller, Jun 30, 2017
  56. 19/25 diff.c: emit_diff_symbol learns about DIFF_SYMBOL_STAT_SEPStefan Beller, Jun 30, 2017
  57. 16/25 diff.c: convert emit_binary_diff_body to use emit_diff_symbolStefan Beller, Jun 30, 2017
  58. 03/25 diff.c: factor out diff_flush_patch_all_file_pairsStefan Beller, Jun 30, 2017
  59. 11/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_FILEPAIR_{PLUS, MINUS}Stefan Beller, Jun 30, 2017
  60. 10/25 diff.c: emit_diff_symbol learns DIFF_SYMBOL_CONTEXT_INCOMPLETEStefan Beller, Jun 30, 2017
  61. 08/25 diff.c: migrate emit_line_checked to use emit_diff_symbolStefan Beller, Jun 30, 2017
  62. 04/25 diff.c: introduce emit_diff_symbolStefan Beller, Jun 30, 2017
  63. Junio C HamanoJun 30, 2017

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.