rebase -i: rewrite append_todo_help() in C

This rewrites append_todo_help() from shell to C. It also incorporates some parts of initiate_action() and complete_action() that also write help texts to the todo file. This also introduces the source file rebase-interactive.c. This file will contain functions necessary for interactive rebase that are too specific for the sequencer, and is part of libgit.a. Two flags are added to rebase--helper.c: one to call append_todo_help() (`--append-todo-help`), and another one to tell append_todo_help() to write the help text suited for the edit-todo mode (`--write-edit-todo`). Finally, append_todo_help() is removed from git-rebase--interactive.sh to use `rebase--helper --append-todo-help` instead. Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Alban Gruin committed Aug 10, 2018 at 18:51 UTC 145e05ac44b4c574fc22e6d3af7c5a14ad9b7335
5 files changed +86 -52
Makefile
+1
@@ -922,6 +922,7 @@ LIB_OBJS += protocol.o
922 LIB_OBJS += quote.o
923 LIB_OBJS += reachable.o
924 LIB_OBJS += read-cache.o
925 +LIB_OBJS += rebase-interactive.o
926 LIB_OBJS += reflog-walk.o
927 LIB_OBJS += refs.o
928 LIB_OBJS += refs/files-backend.o
builtin/rebase--helper.c
+9 -2
@@ -3,6 +3,7 @@
3 #include "config.h"
4 #include "parse-options.h"
5 #include "sequencer.h"
6 +#include "rebase-interactive.h"
7
8 static const char * const builtin_rebase_helper_usage[] = {
9 N_("git rebase--helper [<options>]"),
@@ -12,12 +13,12 @@ static const char * const builtin_rebase_helper_usage[] = {
13 int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
14 {
15 struct replay_opts opts = REPLAY_OPTS_INIT;
15 - unsigned flags = 0, keep_empty = 0, rebase_merges = 0;
16 + unsigned flags = 0, keep_empty = 0, rebase_merges = 0, write_edit_todo = 0;
17 int abbreviate_commands = 0, rebase_cousins = -1;
18 enum {
19 CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS,
20 CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH,
20 - ADD_EXEC
21 + ADD_EXEC, APPEND_TODO_HELP
22 } command = 0;
23 struct option options[] = {
24 OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
@@ -27,6 +28,8 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
28 OPT_BOOL(0, "rebase-merges", &rebase_merges, N_("rebase merge commits")),
29 OPT_BOOL(0, "rebase-cousins", &rebase_cousins,
30 N_("keep original branch points of cousins")),
31 + OPT_BOOL(0, "write-edit-todo", &write_edit_todo,
32 + N_("append the edit-todo message to the todo-list")),
33 OPT_CMDMODE(0, "continue", &command, N_("continue rebase"),
34 CONTINUE),
35 OPT_CMDMODE(0, "abort", &command, N_("abort rebase"),
@@ -45,6 +48,8 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
48 N_("rearrange fixup/squash lines"), REARRANGE_SQUASH),
49 OPT_CMDMODE(0, "add-exec-commands", &command,
50 N_("insert exec commands in todo list"), ADD_EXEC),
51 + OPT_CMDMODE(0, "append-todo-help", &command,
52 + N_("insert the help in the todo list"), APPEND_TODO_HELP),
53 OPT_END()
54 };
55
@@ -84,5 +89,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
89 return !!rearrange_squash();
90 if (command == ADD_EXEC && argc == 2)
91 return !!sequencer_add_exec_commands(argv[1]);
92 + if (command == APPEND_TODO_HELP && argc == 1)
93 + return !!append_todo_help(write_edit_todo, keep_empty);
94 usage_with_options(builtin_rebase_helper_usage, options);
95 }
git-rebase--interactive.sh
+2 -50
@@ -39,38 +39,6 @@ comment_for_reflog () {
39 esac
40 }
41
42 -append_todo_help () {
43 - gettext "
44 -Commands:
45 -p, pick <commit> = use commit
46 -r, reword <commit> = use commit, but edit the commit message
47 -e, edit <commit> = use commit, but stop for amending
48 -s, squash <commit> = use commit, but meld into previous commit
49 -f, fixup <commit> = like \"squash\", but discard this commit's log message
50 -x, exec <command> = run command (the rest of the line) using shell
51 -d, drop <commit> = remove commit
52 -l, label <label> = label current HEAD with a name
53 -t, reset <label> = reset HEAD to a label
54 -m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
55 -. create a merge commit using the original merge commit's
56 -. message (or the oneline, if no original merge commit was
57 -. specified). Use -c <commit> to reword the commit message.
58 -
59 -These lines can be re-ordered; they are executed from top to bottom.
60 -" | git stripspace --comment-lines >>"$todo"
61 -
62 - if test $(get_missing_commit_check_level) = error
63 - then
64 - gettext "
65 -Do not remove any line. Use 'drop' explicitly to remove a commit.
66 -" | git stripspace --comment-lines >>"$todo"
67 - else
68 - gettext "
69 -If you remove a line here THAT COMMIT WILL BE LOST.
70 -" | git stripspace --comment-lines >>"$todo"
71 - fi
72 -}
73 -
42 die_abort () {
43 apply_autostash
44 rm -rf "$state_dir"
@@ -143,13 +111,7 @@ initiate_action () {
111 git stripspace --strip-comments <"$todo" >"$todo".new
112 mv -f "$todo".new "$todo"
113 collapse_todo_ids
146 - append_todo_help
147 - gettext "
148 -You are editing the todo file of an ongoing interactive rebase.
149 -To continue rebase after editing, run:
150 - git rebase --continue
151 -
152 -" | git stripspace --comment-lines >>"$todo"
114 + git rebase--helper --append-todo-help --write-edit-todo
115
116 git_sequence_editor "$todo" ||
117 die "$(gettext "Could not execute editor")"
@@ -220,17 +182,7 @@ $comment_char $(eval_ngettext \
182 "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
183 "$todocount")
184 EOF
223 - append_todo_help
224 - gettext "
225 - However, if you remove everything, the rebase will be aborted.
226 -
227 - " | git stripspace --comment-lines >>"$todo"
228 -
229 - if test -z "$keep_empty"
230 - then
231 - printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
232 - fi
233 -
185 + git rebase--helper --append-todo-help ${keep_empty:+--keep-empty}
186
187 has_action "$todo" ||
188 return 2
rebase-interactive.c new
+68
@@ -0,0 +1,68 @@
1 +#include "cache.h"
2 +#include "commit.h"
3 +#include "rebase-interactive.h"
4 +#include "sequencer.h"
5 +#include "strbuf.h"
6 +
7 +int append_todo_help(unsigned edit_todo, unsigned keep_empty)
8 +{
9 + struct strbuf buf = STRBUF_INIT;
10 + FILE *todo;
11 + int ret;
12 + const char *msg = _("\nCommands:\n"
13 +"p, pick <commit> = use commit\n"
14 +"r, reword <commit> = use commit, but edit the commit message\n"
15 +"e, edit <commit> = use commit, but stop for amending\n"
16 +"s, squash <commit> = use commit, but meld into previous commit\n"
17 +"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
18 +"x, exec <command> = run command (the rest of the line) using shell\n"
19 +"d, drop <commit> = remove commit\n"
20 +"l, label <label> = label current HEAD with a name\n"
21 +"t, reset <label> = reset HEAD to a label\n"
22 +"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
23 +". create a merge commit using the original merge commit's\n"
24 +". message (or the oneline, if no original merge commit was\n"
25 +". specified). Use -c <commit> to reword the commit message.\n"
26 +"\n"
27 +"These lines can be re-ordered; they are executed from top to bottom.\n");
28 +
29 + todo = fopen_or_warn(rebase_path_todo(), "a");
30 + if (!todo)
31 + return 1;
32 +
33 + strbuf_add_commented_lines(&buf, msg, strlen(msg));
34 +
35 + if (get_missing_commit_check_level() == MISSING_COMMIT_CHECK_ERROR)
36 + msg = _("\nDo not remove any line. Use 'drop' "
37 + "explicitly to remove a commit.\n");
38 + else
39 + msg = _("\nIf you remove a line here "
40 + "THAT COMMIT WILL BE LOST.\n");
41 +
42 + strbuf_add_commented_lines(&buf, msg, strlen(msg));
43 +
44 + if (edit_todo)
45 + msg = _("\nYou are editing the todo file "
46 + "of an ongoing interactive rebase.\n"
47 + "To continue rebase after editing, run:\n"
48 + " git rebase --continue\n\n");
49 + else
50 + msg = _("\nHowever, if you remove everything, "
51 + "the rebase will be aborted.\n\n");
52 +
53 + strbuf_add_commented_lines(&buf, msg, strlen(msg));
54 +
55 + if (!keep_empty) {
56 + msg = _("Note that empty commits are commented out");
57 + strbuf_add_commented_lines(&buf, msg, strlen(msg));
58 + }
59 +
60 + ret = fputs(buf.buf, todo);
61 + if (ret < 0)
62 + error_errno(_("could not append help text to '%s'"), rebase_path_todo());
63 +
64 + fclose(todo);
65 + strbuf_release(&buf);
66 +
67 + return ret;
68 +}
rebase-interactive.h new
+6
@@ -0,0 +1,6 @@
1 +#ifndef REBASE_INTERACTIVE_H
2 +#define REBASE_INTERACTIVE_H
3 +
4 +int append_todo_help(unsigned edit_todo, unsigned keep_empty);
5 +
6 +#endif