All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Tan <pyokagan@gmail.com>
To: Git List <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>,
	Johannes Schindelin <johannes.schindelin@gmx.de>,
	Duy Nguyen <pclouds@gmail.com>,
	Stefan Beller <sbeller@google.com>,
	sam.halliday@gmail.com, Paul Tan <pyokagan@gmail.com>
Subject: [PATCH/RFC/GSoC 12/17] rebase-todo: introduce rebase_todo_item
Date: Sat, 12 Mar 2016 18:46:32 +0800	[thread overview]
Message-ID: <1457779597-6918-13-git-send-email-pyokagan@gmail.com> (raw)
In-Reply-To: <1457779597-6918-1-git-send-email-pyokagan@gmail.com>

In an interactive rebase, commands are read and executed from a todo
list (.git/rebase-merge/git-rebase-todo) to perform the rebase.

In the upcoming re-implementation of git-rebase -i in C, it is useful to
be able to parse each command into a data structure which can then be
operated on. Implement rebase_todo_item for this.

Signed-off-by: Paul Tan <pyokagan@gmail.com>
---
 Makefile      |   1 +
 rebase-todo.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rebase-todo.h |  28 ++++++++++++
 3 files changed, 173 insertions(+)
 create mode 100644 rebase-todo.c
 create mode 100644 rebase-todo.h

diff --git a/Makefile b/Makefile
index d43e068..8b928e4 100644
--- a/Makefile
+++ b/Makefile
@@ -782,6 +782,7 @@ LIB_OBJS += read-cache.o
 LIB_OBJS += rebase-am.o
 LIB_OBJS += rebase-common.o
 LIB_OBJS += rebase-merge.o
+LIB_OBJS += rebase-todo.o
 LIB_OBJS += reflog-walk.o
 LIB_OBJS += refs.o
 LIB_OBJS += refs/files-backend.o
diff --git a/rebase-todo.c b/rebase-todo.c
new file mode 100644
index 0000000..ac6b222
--- /dev/null
+++ b/rebase-todo.c
@@ -0,0 +1,144 @@
+#include "cache.h"
+#include "rebase-todo.h"
+
+/*
+ * Used as the default `rest` value, so that users can always assume `rest` is
+ * non NULL and `rest` is NUL terminated even for a freshly initialized
+ * rebase_todo_item.
+ */
+static char rebase_todo_item_slopbuf[1];
+
+void rebase_todo_item_init(struct rebase_todo_item *item)
+{
+	item->action = REBASE_TODO_NONE;
+	oidclr(&item->oid);
+	item->rest = rebase_todo_item_slopbuf;
+}
+
+void rebase_todo_item_release(struct rebase_todo_item *item)
+{
+	if (item->rest != rebase_todo_item_slopbuf)
+		free(item->rest);
+	rebase_todo_item_init(item);
+}
+
+void rebase_todo_item_copy(struct rebase_todo_item *dst, const struct rebase_todo_item *src)
+{
+	if (dst->rest != rebase_todo_item_slopbuf)
+		free(dst->rest);
+	*dst = *src;
+	dst->rest = xstrdup(src->rest);
+}
+
+static const char *next_word(struct strbuf *sb, const char *str)
+{
+	const char *end;
+
+	while (*str && isspace(*str))
+		str++;
+
+	end = str;
+	while (*end && !isspace(*end))
+		end++;
+
+	strbuf_reset(sb);
+	strbuf_add(sb, str, end - str);
+	return end;
+}
+
+int rebase_todo_item_parse(struct rebase_todo_item *item, const char *line, int abbrev)
+{
+	struct strbuf word = STRBUF_INIT;
+	const char *str = line;
+	int has_oid = 1, ret = 0;
+
+	while (*str && isspace(*str))
+		str++;
+
+	if (!*str || *str == comment_line_char) {
+		item->action = REBASE_TODO_NONE;
+		oidclr(&item->oid);
+		if (item->rest != rebase_todo_item_slopbuf)
+			free(item->rest);
+		item->rest = *str ? xstrdup(str) : rebase_todo_item_slopbuf;
+		return 0;
+	}
+
+	str = next_word(&word, str);
+	if (!strcmp(word.buf, "noop")) {
+		item->action = REBASE_TODO_NOOP;
+		has_oid = 0;
+	} else if (!strcmp(word.buf, "pick") || !strcmp(word.buf, "p")) {
+		item->action = REBASE_TODO_PICK;
+	} else {
+		ret = error(_("Unknown command: %s"), word.buf);
+		goto finish;
+	}
+
+	if (has_oid) {
+		str = next_word(&word, str);
+		if (abbrev) {
+			/* accept abbreviated object ids */
+			if (get_oid_commit(word.buf, &item->oid)) {
+				ret = error(_("Not a commit: %s"), word.buf);
+				goto finish;
+			}
+		} else {
+			if (word.len != GIT_SHA1_HEXSZ || get_oid_hex(word.buf, &item->oid)) {
+				ret = error(_("Invalid line: %s"), line);
+				goto finish;
+			}
+		}
+	} else {
+		oidclr(&item->oid);
+	}
+
+	if (*str && isspace(*str))
+		str++;
+	if (*str) {
+		if (item->rest != rebase_todo_item_slopbuf)
+			free(item->rest);
+		item->rest = xstrdup(str);
+	}
+
+finish:
+	strbuf_release(&word);
+	return ret;
+}
+
+void strbuf_add_rebase_todo_item(struct strbuf *sb,
+				 const struct rebase_todo_item *item, int abbrev)
+{
+	int has_oid = 1;
+
+	switch (item->action) {
+	case REBASE_TODO_NONE:
+		has_oid = 0;
+		break;
+	case REBASE_TODO_NOOP:
+		strbuf_addstr(sb, "noop");
+		has_oid = 0;
+		break;
+	case REBASE_TODO_PICK:
+		strbuf_addstr(sb, "pick");
+		break;
+	default:
+		die("BUG: invalid rebase_todo_item action %d", item->action);
+	}
+
+	if (has_oid) {
+		strbuf_addch(sb, ' ');
+		if (abbrev)
+			strbuf_addstr(sb, find_unique_abbrev((unsigned char *)&item->oid.hash, DEFAULT_ABBREV));
+		else
+			strbuf_addstr(sb, oid_to_hex(&item->oid));
+	}
+
+	if (*item->rest) {
+		if (item->action != REBASE_TODO_NONE)
+			strbuf_addch(sb, ' ');
+		strbuf_addstr(sb, item->rest);
+	}
+
+	strbuf_addch(sb, '\n');
+}
diff --git a/rebase-todo.h b/rebase-todo.h
new file mode 100644
index 0000000..2eedbb0
--- /dev/null
+++ b/rebase-todo.h
@@ -0,0 +1,28 @@
+#ifndef REBASE_TODO_H
+#define REBASE_TODO_H
+
+struct strbuf;
+
+enum rebase_todo_action {
+	REBASE_TODO_NONE = 0,
+	REBASE_TODO_NOOP,
+	REBASE_TODO_PICK
+};
+
+struct rebase_todo_item {
+	enum rebase_todo_action action;
+	struct object_id oid;
+	char *rest;
+};
+
+void rebase_todo_item_init(struct rebase_todo_item *);
+
+void rebase_todo_item_release(struct rebase_todo_item *);
+
+void rebase_todo_item_copy(struct rebase_todo_item *, const struct rebase_todo_item *);
+
+int rebase_todo_item_parse(struct rebase_todo_item *, const char *line, int abbrev);
+
+void strbuf_add_rebase_todo_item(struct strbuf *, const struct rebase_todo_item *, int abbrev);
+
+#endif /* REBASE_TODO_H */
-- 
2.7.0

  parent reply	other threads:[~2016-03-12 10:47 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-12 10:46 [PATCH/RFC/GSoC 00/17] A barebones git-rebase in C Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 01/17] perf: introduce performance tests for git-rebase Paul Tan
2016-03-16  7:58   ` Johannes Schindelin
2016-03-16 11:51     ` Paul Tan
2016-03-16 15:59       ` Johannes Schindelin
2016-03-18 11:01         ` Thomas Gummerer
2016-03-18 16:00           ` Johannes Schindelin
2016-03-20 14:00             ` Thomas Gummerer
2016-03-21  7:54               ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 02/17] sha1_name: implement get_oid() and friends Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 03/17] builtin-rebase: implement skeletal builtin rebase Paul Tan
2016-03-14 18:31   ` Stefan Beller
2016-03-15  8:01     ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 04/17] builtin-rebase: parse rebase arguments into a common rebase_options struct Paul Tan
2016-03-14 20:05   ` Stefan Beller
2016-03-15 10:54   ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 05/17] rebase-options: implement rebase_options_load() and rebase_options_save() Paul Tan
2016-03-14 20:30   ` Stefan Beller
2016-03-16  8:04     ` Johannes Schindelin
2016-03-16 12:28       ` Paul Tan
2016-03-16 17:11         ` Johannes Schindelin
2016-03-21 14:55           ` Paul Tan
2016-03-16 12:04     ` Paul Tan
2016-03-16 17:10       ` Stefan Beller
2016-03-12 10:46 ` [PATCH/RFC/GSoC 06/17] rebase-am: introduce am backend for builtin rebase Paul Tan
2016-03-16 13:21   ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 07/17] rebase-common: implement refresh_and_write_cache() Paul Tan
2016-03-14 21:10   ` Junio C Hamano
2016-03-16 12:56     ` Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 08/17] rebase-common: let refresh_and_write_cache() take a flags argument Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 09/17] rebase-common: implement cache_has_unstaged_changes() Paul Tan
2016-03-14 20:54   ` Johannes Schindelin
2016-03-14 21:52     ` Junio C Hamano
2016-03-15 11:51       ` Johannes Schindelin
2016-03-15 11:07     ` Duy Nguyen
2016-03-15 14:15       ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 10/17] rebase-common: implement cache_has_uncommitted_changes() Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 11/17] rebase-merge: introduce merge backend for builtin rebase Paul Tan
2016-03-12 10:46 ` Paul Tan [this message]
2016-03-14 13:43   ` [PATCH/RFC/GSoC 12/17] rebase-todo: introduce rebase_todo_item Christian Couder
2016-03-14 20:33     ` Johannes Schindelin
2016-03-16 12:54     ` Paul Tan
2016-03-16 15:55       ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 13/17] rebase-todo: introduce rebase_todo_list Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 14/17] status: use rebase_todo_list Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 15/17] wrapper: implement append_file() Paul Tan
2016-03-12 10:46 ` [PATCH/RFC/GSoC 16/17] editor: implement git_sequence_editor() and launch_sequence_editor() Paul Tan
2016-03-15  7:00   ` Johannes Schindelin
2016-03-16 13:06     ` Paul Tan
2016-03-16 18:21       ` Johannes Schindelin
2016-03-12 10:46 ` [PATCH/RFC/GSoC 17/17] rebase-interactive: introduce interactive backend for builtin rebase Paul Tan
2016-03-15  7:57   ` Johannes Schindelin
2016-03-15 16:48     ` Paul Tan
2016-03-15 19:45       ` Johannes Schindelin
2016-03-14 12:15 ` [PATCH/RFC/GSoC 00/17] A barebones git-rebase in C Duy Nguyen
2016-03-14 17:32   ` Stefan Beller
2016-03-14 18:43   ` Junio C Hamano
2016-03-16 12:46     ` Paul Tan
2016-03-14 20:44   ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457779597-6918-13-git-send-email-pyokagan@gmail.com \
    --to=pyokagan@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johannes.schindelin@gmx.de \
    --cc=pclouds@gmail.com \
    --cc=sam.halliday@gmail.com \
    --cc=sbeller@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.