Subject: [PATCH/RFC/GSoC 14/17] status: use rebase_todo_list

From: Paul Tan <[email-masked]>
Date: Sat, 12 Mar 2016 18:46:34 +0800

Since 84e6fb9 (status: give more information during rebase -i,
2015-07-06), git status during an interactive rebase will show the list
of commands that are done and yet to be done. It implemented its own
hand-rolled parser in order to achieve this.

Now that we are able to fully parse interactive rebase's todo lists with
rebase_todo_list_parse(), use it in wt-status.c to reduce the amount of
code needed to implement this feature.

Signed-off-by: Paul Tan <[email-masked]>
---

This patch is just an illustration, and is not quite right as it does not strip
comments and blank lines like the original did.

 wt-status.c | 100 +++++++++++++++---------------------------------------------
 1 file changed, 25 insertions(+), 75 deletions(-)

diff --git a/wt-status.c b/wt-status.c
index ab4f80d..96b82ef 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -15,6 +15,7 @@
 #include "column.h"
 #include "strbuf.h"
 #include "utf8.h"
+#include "rebase-todo.h"
 
 static const char cut_line[] =
 "------------------------ >8 ------------------------\n";
@@ -1026,94 +1027,39 @@ static int split_commit_in_progress(struct wt_status *s)
 	return split_in_progress;
 }
 
-/*
- * Turn
- * "pick d6a2f0303e897ec257dd0e0a39a5ccb709bc2047 some message"
- * into
- * "pick d6a2f03 some message"
- *
- * The function assumes that the line does not contain useless spaces
- * before or after the command.
- */
-static void abbrev_sha1_in_line(struct strbuf *line)
-{
-	struct strbuf **split;
-	int i;
-
-	if (starts_with(line->buf, "exec ") ||
-	    starts_with(line->buf, "x "))
-		return;
-
-	split = strbuf_split_max(line, ' ', 3);
-	if (split[0] && split[1]) {
-		unsigned char sha1[20];
-		const char *abbrev;
-
-		/*
-		 * strbuf_split_max left a space. Trim it and re-add
-		 * it after abbreviation.
-		 */
-		strbuf_trim(split[1]);
-		if (!get_sha1(split[1]->buf, sha1)) {
-			abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
-			strbuf_reset(split[1]);
-			strbuf_addf(split[1], "%s ", abbrev);
-			strbuf_reset(line);
-			for (i = 0; split[i]; i++)
-				strbuf_addf(line, "%s", split[i]->buf);
-		}
-	}
-	for (i = 0; split[i]; i++)
-		strbuf_release(split[i]);
-
-}
-
-static void read_rebase_todolist(const char *fname, struct string_list *lines)
-{
-	struct strbuf line = STRBUF_INIT;
-	FILE *f = fopen(git_path("%s", fname), "r");
-
-	if (!f)
-		die_errno("Could not open file %s for reading",
-			  git_path("%s", fname));
-	while (!strbuf_getline_lf(&line, f)) {
-		if (line.len && line.buf[0] == comment_line_char)
-			continue;
-		strbuf_trim(&line);
-		if (!line.len)
-			continue;
-		abbrev_sha1_in_line(&line);
-		string_list_append(lines, line.buf);
-	}
-}
-
 static void show_rebase_information(struct wt_status *s,
 					struct wt_status_state *state,
 					const char *color)
 {
 	if (state->rebase_interactive_in_progress) {
-		int i;
-		int nr_lines_to_show = 2;
+		unsigned int i;
+		unsigned int nr_lines_to_show = 2;
+		struct strbuf sb = STRBUF_INIT;
 
-		struct string_list have_done = STRING_LIST_INIT_DUP;
-		struct string_list yet_to_do = STRING_LIST_INIT_DUP;
+		struct rebase_todo_list have_done = REBASE_TODO_LIST_INIT;
+		struct rebase_todo_list yet_to_do = REBASE_TODO_LIST_INIT;
 
-		read_rebase_todolist("rebase-merge/done", &have_done);
-		read_rebase_todolist("rebase-merge/git-rebase-todo", &yet_to_do);
+		if (rebase_todo_list_load(&have_done, git_path("rebase-merge/done"), 1) < 0)
+			return;
+		if (rebase_todo_list_load(&yet_to_do, git_path("rebase-merge/git-rebase-todo"), 1) < 0)
+			return;
 
 		if (have_done.nr == 0)
 			status_printf_ln(s, color, _("No commands done."));
 		else {
 			status_printf_ln(s, color,
-				Q_("Last command done (%d command done):",
-					"Last commands done (%d commands done):",
+				Q_("Last command done (%u command done):",
+					"Last commands done (%u commands done):",
 					have_done.nr),
 				have_done.nr);
 			for (i = (have_done.nr > nr_lines_to_show)
 				? have_done.nr - nr_lines_to_show : 0;
 				i < have_done.nr;
-				i++)
-				status_printf_ln(s, color, "   %s", have_done.items[i].string);
+				i++) {
+				strbuf_reset(&sb);
+				strbuf_add_rebase_todo_item(&sb, &have_done.items[i], 1);
+				status_printf(s, color, "   %s", sb.buf);
+			}
 			if (have_done.nr > nr_lines_to_show && s->hints)
 				status_printf_ln(s, color,
 					_("  (see more in file %s)"), git_path("rebase-merge/done"));
@@ -1128,14 +1074,18 @@ static void show_rebase_information(struct wt_status *s,
 					"Next commands to do (%d remaining commands):",
 					yet_to_do.nr),
 				yet_to_do.nr);
-			for (i = 0; i < nr_lines_to_show && i < yet_to_do.nr; i++)
-				status_printf_ln(s, color, "   %s", yet_to_do.items[i].string);
+			for (i = 0; i < nr_lines_to_show && i < yet_to_do.nr; i++) {
+				strbuf_reset(&sb);
+				strbuf_add_rebase_todo_item(&sb, &yet_to_do.items[i], 1);
+				status_printf(s, color, "   %s", sb.buf);
+			}
 			if (s->hints)
 				status_printf_ln(s, color,
 					_("  (use \"git rebase --edit-todo\" to view and edit)"));
 		}
-		string_list_clear(&yet_to_do, 0);
-		string_list_clear(&have_done, 0);
+		rebase_todo_list_clear(&yet_to_do);
+		rebase_todo_list_clear(&have_done);
+		strbuf_release(&sb);
 	}
 }
 
-- 
2.7.0