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

[PATCH v4 05/45] log-tree: remove dependency from sequencer

From
Felipe Contreras <felipe.contreras@gmail.com>
Date
Jun 9, 2013, 16:40 UTC
Message-ID
<1370796057-25312-6-git-send-email-felipe.contreras@gmail.com>
In-Reply-To
<1370796057-25312-1-git-send-email-felipe.contreras@gmail.com>

Move the relevant code from sequencer to log-tree. This code is not specific to sequencer, and this allows the sequencer to move out of libgit.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 log-tree.c  | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 log-tree.h  |   3 ++
 sequencer.c | 160 ++---------------------------------------------------------
 sequencer.h |   4 --
 4 files changed, 166 insertions(+), 162 deletions(-)
diff --git a/log-tree.c b/log-tree.c
index 2eb69bc..654f5db 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -9,10 +9,13 @@
 #include "string-list.h"
 #include "color.h"
 #include "gpg-interface.h"
-#include "sequencer.h"
 #include "line-log.h"
 
+#define APPEND_SIGNOFF_DEDUP (1u << 0)
+
 struct decoration name_decoration = { "object names" };
+const char sign_off_header[] = "Signed-off-by: ";
+static const char cherry_picked_prefix[] = "(cherry picked from commit ";
 
 enum decoration_type {
 	DECORATION_NONE = 0,
@@ -472,6 +475,162 @@ static void show_mergetag(struct rev_info *opt, struct commit *commit)
 	free_commit_extra_headers(to_free);
 }
 
+static int is_rfc2822_line(const char *buf, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		int ch = buf[i];
+		if (ch == ':')
+			return 1;
+		if (!isalnum(ch) && ch != '-')
+			break;
+	}
+
+	return 0;
+}
+
+static int is_cherry_picked_from_line(const char *buf, int len)
+{
+	/*
+	 * We only care that it looks roughly like (cherry picked from ...)
+	 */
+	return len > strlen(cherry_picked_prefix) + 1 &&
+		!prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')';
+}
+
+/*
+ * Returns 0 for non-conforming footer
+ * Returns 1 for conforming footer
+ * Returns 2 when sob exists within conforming footer
+ * Returns 3 when sob exists within conforming footer as last entry
+ */
+int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
+	int ignore_footer)
+{
+	char prev;
+	int i, k;
+	int len = sb->len - ignore_footer;
+	const char *buf = sb->buf;
+	int found_sob = 0;
+
+	/* footer must end with newline */
+	if (!len || buf[len - 1] != '\n')
+		return 0;
+
+	prev = '\0';
+	for (i = len - 1; i > 0; i--) {
+		char ch = buf[i];
+		if (prev == '\n' && ch == '\n') /* paragraph break */
+			break;
+		prev = ch;
+	}
+
+	/* require at least one blank line */
+	if (prev != '\n' || buf[i] != '\n')
+		return 0;
+
+	/* advance to start of last paragraph */
+	while (i < len - 1 && buf[i] == '\n')
+		i++;
+
+	for (; i < len; i = k) {
+		int found_rfc2822;
+
+		for (k = i; k < len && buf[k] != '\n'; k++)
+			; /* do nothing */
+		k++;
+
+		found_rfc2822 = is_rfc2822_line(buf + i, k - i - 1);
+		if (found_rfc2822 && sob &&
+		    !strncmp(buf + i, sob->buf, sob->len))
+			found_sob = k;
+
+		if (!(found_rfc2822 ||
+		      is_cherry_picked_from_line(buf + i, k - i - 1)))
+			return 0;
+	}
+	if (found_sob == i)
+		return 3;
+	if (found_sob)
+		return 2;
+	return 1;
+}
+
+void append_cherrypick(struct strbuf *msgbuf, struct object *obj)
+{
+	if (!has_conforming_footer(msgbuf, NULL, 0))
+		strbuf_addch(msgbuf, '\n');
+	strbuf_addstr(msgbuf, cherry_picked_prefix);
+	strbuf_addstr(msgbuf, sha1_to_hex(obj->sha1));
+	strbuf_addstr(msgbuf, ")\n");
+}
+
+void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
+{
+	unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
+	struct strbuf sob = STRBUF_INIT;
+	int has_footer;
+
+	strbuf_addstr(&sob, sign_off_header);
+	strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
+				getenv("GIT_COMMITTER_EMAIL")));
+	strbuf_addch(&sob, '\n');
+
+	/*
+	 * If the whole message buffer is equal to the sob, pretend that we
+	 * found a conforming footer with a matching sob
+	 */
+	if (msgbuf->len - ignore_footer == sob.len &&
+	    !strncmp(msgbuf->buf, sob.buf, sob.len))
+		has_footer = 3;
+	else
+		has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);
+
+	if (!has_footer) {
+		const char *append_newlines = NULL;
+		size_t len = msgbuf->len - ignore_footer;
+
+		if (!len) {
+			/*
+			 * The buffer is completely empty.  Leave foom for
+			 * the title and body to be filled in by the user.
+			 */
+			append_newlines = "\n\n";
+		} else if (msgbuf->buf[len - 1] != '\n') {
+			/*
+			 * Incomplete line.  Complete the line and add a
+			 * blank one so that there is an empty line between
+			 * the message body and the sob.
+			 */
+			append_newlines = "\n\n";
+		} else if (len == 1) {
+			/*
+			 * Buffer contains a single newline.  Add another
+			 * so that we leave room for the title and body.
+			 */
+			append_newlines = "\n";
+		} else if (msgbuf->buf[len - 2] != '\n') {
+			/*
+			 * Buffer ends with a single newline.  Add another
+			 * so that there is an empty line between the message
+			 * body and the sob.
+			 */
+			append_newlines = "\n";
+		} /* else, the buffer already ends with two newlines. */
+
+		if (append_newlines)
+			strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
+				append_newlines, strlen(append_newlines));
+	}
+
+	if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
+		strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
+				sob.buf, sob.len);
+
+	strbuf_release(&sob);
+}
+
 void show_log(struct rev_info *opt)
 {
 	struct strbuf msgbuf = STRBUF_INIT;
diff --git a/log-tree.h b/log-tree.h
index d6ecd4d..1039e49 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -25,4 +25,7 @@ void load_ref_decorations(int flags);
 void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *);
 void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *);
 
+void append_cherrypick(struct strbuf *msgbuf, struct object *obj);
+void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
+
 #endif
diff --git a/sequencer.c b/sequencer.c
index ab6f8a7..e92e039 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -14,94 +14,10 @@
 #include "merge-recursive.h"
 #include "refs.h"
 #include "argv-array.h"
+#include "log-tree.h"
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
-const char sign_off_header[] = "Signed-off-by: ";
-static const char cherry_picked_prefix[] = "(cherry picked from commit ";
-
-static int is_rfc2822_line(const char *buf, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++) {
-		int ch = buf[i];
-		if (ch == ':')
-			return 1;
-		if (!isalnum(ch) && ch != '-')
-			break;
-	}
-
-	return 0;
-}
-
-static int is_cherry_picked_from_line(const char *buf, int len)
-{
-	/*
-	 * We only care that it looks roughly like (cherry picked from ...)
-	 */
-	return len > strlen(cherry_picked_prefix) + 1 &&
-		!prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')';
-}
-
-/*
- * Returns 0 for non-conforming footer
- * Returns 1 for conforming footer
- * Returns 2 when sob exists within conforming footer
- * Returns 3 when sob exists within conforming footer as last entry
- */
-static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
-	int ignore_footer)
-{
-	char prev;
-	int i, k;
-	int len = sb->len - ignore_footer;
-	const char *buf = sb->buf;
-	int found_sob = 0;
-
-	/* footer must end with newline */
-	if (!len || buf[len - 1] != '\n')
-		return 0;
-
-	prev = '\0';
-	for (i = len - 1; i > 0; i--) {
-		char ch = buf[i];
-		if (prev == '\n' && ch == '\n') /* paragraph break */
-			break;
-		prev = ch;
-	}
-
-	/* require at least one blank line */
-	if (prev != '\n' || buf[i] != '\n')
-		return 0;
-
-	/* advance to start of last paragraph */
-	while (i < len - 1 && buf[i] == '\n')
-		i++;
-
-	for (; i < len; i = k) {
-		int found_rfc2822;
-
-		for (k = i; k < len && buf[k] != '\n'; k++)
-			; /* do nothing */
-		k++;
-
-		found_rfc2822 = is_rfc2822_line(buf + i, k - i - 1);
-		if (found_rfc2822 && sob &&
-		    !strncmp(buf + i, sob->buf, sob->len))
-			found_sob = k;
-
-		if (!(found_rfc2822 ||
-		      is_cherry_picked_from_line(buf + i, k - i - 1)))
-			return 0;
-	}
-	if (found_sob == i)
-		return 3;
-	if (found_sob)
-		return 2;
-	return 1;
-}
-
 static void remove_sequencer_state(void)
 {
 	struct strbuf seq_dir = STRBUF_INIT;
@@ -578,13 +494,8 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
 			strbuf_addstr(&msgbuf, p);
 		}
 
-		if (opts->record_origin) {
-			if (!has_conforming_footer(&msgbuf, NULL, 0))
-				strbuf_addch(&msgbuf, '\n');
-			strbuf_addstr(&msgbuf, cherry_picked_prefix);
-			strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
-			strbuf_addstr(&msgbuf, ")\n");
-		}
+		if (opts->record_origin)
+			append_cherrypick(&msgbuf, &commit->object);
 	}
 
 	if (!opts->strategy || !strcmp(opts->strategy, "recursive") || opts->action == REPLAY_REVERT) {
@@ -1123,68 +1034,3 @@ int sequencer_pick_revisions(struct replay_opts *opts)
 	save_opts(opts);
 	return pick_commits(todo_list, opts);
 }
-
-void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
-{
-	unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
-	struct strbuf sob = STRBUF_INIT;
-	int has_footer;
-
-	strbuf_addstr(&sob, sign_off_header);
-	strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
-				getenv("GIT_COMMITTER_EMAIL")));
-	strbuf_addch(&sob, '\n');
-
-	/*
-	 * If the whole message buffer is equal to the sob, pretend that we
-	 * found a conforming footer with a matching sob
-	 */
-	if (msgbuf->len - ignore_footer == sob.len &&
-	    !strncmp(msgbuf->buf, sob.buf, sob.len))
-		has_footer = 3;
-	else
-		has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);
-
-	if (!has_footer) {
-		const char *append_newlines = NULL;
-		size_t len = msgbuf->len - ignore_footer;
-
-		if (!len) {
-			/*
-			 * The buffer is completely empty.  Leave foom for
-			 * the title and body to be filled in by the user.
-			 */
-			append_newlines = "\n\n";
-		} else if (msgbuf->buf[len - 1] != '\n') {
-			/*
-			 * Incomplete line.  Complete the line and add a
-			 * blank one so that there is an empty line between
-			 * the message body and the sob.
-			 */
-			append_newlines = "\n\n";
-		} else if (len == 1) {
-			/*
-			 * Buffer contains a single newline.  Add another
-			 * so that we leave room for the title and body.
-			 */
-			append_newlines = "\n";
-		} else if (msgbuf->buf[len - 2] != '\n') {
-			/*
-			 * Buffer ends with a single newline.  Add another
-			 * so that there is an empty line between the message
-			 * body and the sob.
-			 */
-			append_newlines = "\n";
-		} /* else, the buffer already ends with two newlines. */
-
-		if (append_newlines)
-			strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
-				append_newlines, strlen(append_newlines));
-	}
-
-	if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
-		strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
-				sob.buf, sob.len);
-
-	strbuf_release(&sob);
-}
diff --git a/sequencer.h b/sequencer.h
index 1fc22dc..c341918 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -6,8 +6,6 @@
 #define SEQ_TODO_FILE	"sequencer/todo"
 #define SEQ_OPTS_FILE	"sequencer/opts"
 
-#define APPEND_SIGNOFF_DEDUP (1u << 0)
-
 enum replay_action {
 	REPLAY_REVERT,
 	REPLAY_PICK
@@ -50,6 +48,4 @@ int sequencer_pick_revisions(struct replay_opts *opts);
 
 extern const char sign_off_header[];
 
-void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
-
 #endif
-- 
1.8.3.698.g079b096
Previous: Felipe ContrerasNext: Felipe Contreras
Message 7 of 86 in “Massive improvents to rebase and cherry-pick”
  1. 00/45 Massive improvents to rebase and cherry-pickFelipe Contreras, Jun 9, 2013
  2. 01/45 build: generate and clean test scriptsFelipe Contreras, Jun 9, 2013
  3. 02/45 build: do not install git-remote-testgitFelipe Contreras, Jun 9, 2013
  4. 03/45 build: trivial cleanupFelipe Contreras, Jun 9, 2013
  5. SZEDER GáborJun 9, 2013
  6. 04/45 build: add builtin libFelipe Contreras, Jun 9, 2013
  7. 05/45 log-tree: remove dependency from sequencerFelipe Contreras, Jun 9, 2013
  8. 06/45 Move sequencer to builtinFelipe Contreras, Jun 9, 2013
  9. Antoine PelisseJun 9, 2013
  10. Felipe ContrerasJun 9, 2013
  11. Ramkumar RamachandraJun 9, 2013
  12. Antoine PelisseJun 9, 2013
  13. 07/45 unpack-trees: plug a memory leakFelipe Contreras, Jun 9, 2013
  14. 08/45 read-cache: plug a few leaksFelipe Contreras, Jun 9, 2013
  15. 09/45 sequencer: remove useless indentationFelipe Contreras, Jun 9, 2013
  16. Fredrik GustafssonJun 9, 2013
  17. Felipe ContrerasJun 9, 2013
  18. Fredrik GustafssonJun 9, 2013
  19. Felipe ContrerasJun 9, 2013
  20. Fredrik GustafssonJun 9, 2013
  21. 10/45 sequencer: trivial fixFelipe Contreras, Jun 9, 2013
  22. SZEDER GáborJun 9, 2013
  23. Felipe ContrerasJun 9, 2013
  24. SZEDER GáborJun 9, 2013
  25. John KeepingJun 9, 2013
  26. Felipe ContrerasJun 9, 2013
  27. John KeepingJun 9, 2013
  28. Felipe ContrerasJun 9, 2013
  29. SZEDER GáborJun 9, 2013
  30. Felipe ContrerasJun 9, 2013
  31. SZEDER GáborJun 9, 2013
  32. Felipe ContrerasJun 9, 2013
  33. Philip OakleyJun 9, 2013
  34. 11/45 cherry-pick: don't barf when there's nothing to doFelipe Contreras, Jun 9, 2013
  35. Fredrik GustafssonJun 9, 2013
  36. Felipe ContrerasJun 9, 2013
  37. 12/45 cherry-pick: add --skip-empty optionFelipe Contreras, Jun 9, 2013
  38. 13/45 revert/cherry-pick: add --quiet optionFelipe Contreras, Jun 9, 2013
  39. 14/45 revert/cherry-pick: add --skip optionFelipe Contreras, Jun 9, 2013
  40. 15/45 builtin: add rewrite helperFelipe Contreras, Jun 9, 2013
  41. 16/45 cherry-pick: store rewritten commitsFelipe Contreras, Jun 9, 2013
  42. 17/45 cherry-pick: don't store skipped commitFelipe Contreras, Jun 9, 2013
  43. 18/45 builtin: move run_rewrite_hook() to rewrite.cFelipe Contreras, Jun 9, 2013
  44. 19/45 builtin: add copy_rewrite_notes()Felipe Contreras, Jun 9, 2013
  45. 20/45 cherry-pick: copy notes and run hooksFelipe Contreras, Jun 9, 2013
  46. Thomas RastJun 9, 2013
  47. Felipe ContrerasJun 9, 2013
  48. 21/45 cherry-pick: add --action-name optionFelipe Contreras, Jun 9, 2013
  49. 22/45 cherry-pick: remember rerere-autoupdateFelipe Contreras, Jun 9, 2013
  50. 23/45 rebase: split the cherry-pick stuffFelipe Contreras, Jun 9, 2013
  51. 24/45 rebase: cherry-pick: fix mode storageFelipe Contreras, Jun 9, 2013
  52. 25/45 rebase: cherry-pick: fix sequence continuationFelipe Contreras, Jun 9, 2013
  53. 26/45 rebase: cherry-pick: fix abort of cherry modeFelipe Contreras, Jun 9, 2013
  54. 27/45 rebase: cherry-pick: fix command invocationsFelipe Contreras, Jun 9, 2013
  55. 28/45 rebase: cherry-pick: fix status messagesFelipe Contreras, Jun 9, 2013
  56. 29/45 rebase: cherry-pick: automatically commit stageFelipe Contreras, Jun 9, 2013
  57. 30/45 rebase: cherry-pick: set correct action-nameFelipe Contreras, Jun 9, 2013
  58. 31/45 rebase: trivial cleanupFelipe Contreras, Jun 9, 2013
  59. Fredrik GustafssonJun 9, 2013
  60. Junio C HamanoJun 11, 2013
  61. Fredrik GustafssonJun 11, 2013
  62. Felipe ContrerasJun 11, 2013
  63. Fredrik GustafssonJun 11, 2013
  64. Felipe ContrerasJun 11, 2013
  65. Fredrik GustafssonJun 11, 2013
  66. Felipe ContrerasJun 11, 2013
  67. 32/45 rebase: use 'cherrypick' mode instead of 'am'Felipe Contreras, Jun 9, 2013
  68. 33/45 rebase: cherry-pick: fix for shell promptFelipe Contreras, Jun 9, 2013
  69. 34/45 rebase: cherry-pick: add merge optionsFelipe Contreras, Jun 9, 2013
  70. 35/45 rebase: remove merge modeFelipe Contreras, Jun 9, 2013
  71. 36/45 rebase: cherry-pick: add copyrightFelipe Contreras, Jun 9, 2013
  72. 37/45 tests: fix autostashFelipe Contreras, Jun 9, 2013
  73. 38/45 add simple tests of consistency across rebase typesFelipe Contreras, Jun 9, 2013
  74. 39/45 add tests for rebasing with patch-equivalence presentFelipe Contreras, Jun 9, 2013
  75. 40/45 add tests for rebasing of empty commitsFelipe Contreras, Jun 9, 2013
  76. 41/45 add tests for rebasing rootFelipe Contreras, Jun 9, 2013
  77. 42/45 add tests for rebasing merged historyFelipe Contreras, Jun 9, 2013
  78. Thomas RastJun 9, 2013
  79. Felipe ContrerasJun 9, 2013
  80. Thomas RastJun 9, 2013
  81. Felipe ContrerasJun 9, 2013
  82. 43/45 t3406: modernize styleFelipe Contreras, Jun 9, 2013
  83. 44/45 tests: move test for rebase messages from t3400 to t3406Felipe Contreras, Jun 9, 2013
  84. 45/45 tests: update topology testsFelipe Contreras, Jun 9, 2013
  85. Martin von ZweigbergkJun 11, 2013
  86. Felipe ContrerasJun 11, 2013

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.