rebase--interactive2: rewrite the submodes of interactive rebase in C

This rewrites the submodes of interactive rebase (`--continue`, `--skip`, `--edit-todo`, and `--show-current-patch`) in C. git-rebase.sh is then modified to call directly git-rebase--interactive2 instead of git-rebase--interactive.sh. Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Alban Gruin committed Sep 27, 2018 at 23:56 UTC 0af129b2ed4a5c73484c4d3e816df104d5438947
2 files changed +86 -10
builtin/rebase--interactive2.c
+45 -6
@@ -134,11 +134,14 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
134 {
135 struct replay_opts opts = REPLAY_OPTS_INIT;
136 unsigned flags = 0, keep_empty = 0, rebase_merges = 0, autosquash = 0;
137 - int abbreviate_commands = 0, rebase_cousins = -1;
137 + int abbreviate_commands = 0, rebase_cousins = -1, ret = 0;
138 const char *onto = NULL, *onto_name = NULL, *restrict_revision = NULL,
139 *squash_onto = NULL, *upstream = NULL, *head_name = NULL,
140 *switch_to = NULL, *cmd = NULL;
141 char *raw_strategies = NULL;
142 + enum {
143 + NONE = 0, CONTINUE, SKIP, EDIT_TODO, SHOW_CURRENT_PATCH
144 + } command = 0;
145 struct option options[] = {
146 OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
147 OPT_BOOL(0, "keep-empty", &keep_empty, N_("keep empty commits")),
@@ -151,6 +154,13 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
154 N_("move commits that begin with squash!/fixup!")),
155 OPT_BOOL(0, "signoff", &opts.signoff, N_("sign commits")),
156 OPT__VERBOSE(&opts.verbose, N_("be verbose")),
157 + OPT_CMDMODE(0, "continue", &command, N_("continue rebase"),
158 + CONTINUE),
159 + OPT_CMDMODE(0, "skip", &command, N_("skip commit"), SKIP),
160 + OPT_CMDMODE(0, "edit-todo", &command, N_("edit the todo list"),
161 + EDIT_TODO),
162 + OPT_CMDMODE(0, "show-current-patch", &command, N_("show the current patch"),
163 + SHOW_CURRENT_PATCH),
164 OPT_STRING(0, "onto", &onto, N_("onto"), N_("onto")),
165 OPT_STRING(0, "restrict-revision", &restrict_revision,
166 N_("restrict-revision"), N_("restrict revision")),
@@ -198,10 +208,39 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
208 warning(_("--[no-]rebase-cousins has no effect without "
209 "--rebase-merges"));
210
201 - if (!onto && !upstream)
202 - die(_("a base commit must be provided with --upstream or --onto"));
211 + switch (command) {
212 + case NONE:
213 + if (!onto && !upstream)
214 + die(_("a base commit must be provided with --upstream or --onto"));
215 +
216 + ret = do_interactive_rebase(&opts, flags, switch_to, upstream, onto,
217 + onto_name, squash_onto, head_name, restrict_revision,
218 + raw_strategies, cmd, autosquash);
219 + break;
220 + case SKIP: {
221 + struct string_list merge_rr = STRING_LIST_INIT_DUP;
222 +
223 + rerere_clear(&merge_rr);
224 + /* fallthrough */
225 + case CONTINUE:
226 + ret = sequencer_continue(&opts);
227 + break;
228 + }
229 + case EDIT_TODO:
230 + ret = edit_todo_list(flags);
231 + break;
232 + case SHOW_CURRENT_PATCH: {
233 + struct child_process cmd = CHILD_PROCESS_INIT;
234 +
235 + cmd.git_cmd = 1;
236 + argv_array_pushl(&cmd.args, "show", "REBASE_HEAD", "--", NULL);
237 + ret = run_command(&cmd);
238 +
239 + break;
240 + }
241 + default:
242 + BUG("invalid command '%d'", command);
243 + }
244
204 - return !!do_interactive_rebase(&opts, flags, switch_to, upstream, onto,
205 - onto_name, squash_onto, head_name, restrict_revision,
206 - raw_strategies, cmd, autosquash);
245 + return !!ret;
246 }
git-rebase.sh
+41 -4
@@ -200,19 +200,56 @@ finish_rebase () {
200 rm -rf "$state_dir"
201 }
202
203 +run_interactive () {
204 + GIT_CHERRY_PICK_HELP="$resolvemsg"
205 + export GIT_CHERRY_PICK_HELP
206 +
207 + test -n "$keep_empty" && keep_empty="--keep-empty"
208 + test -n "$rebase_merges" && rebase_merges="--rebase-merges"
209 + test -n "$rebase_cousins" && rebase_cousins="--rebase-cousins"
210 + test -n "$autosquash" && autosquash="--autosquash"
211 + test -n "$verbose" && verbose="--verbose"
212 + test -n "$force_rebase" && force_rebase="--no-ff"
213 + test -n "$restrict_revision" && \
214 + restrict_revision="--restrict-revision=^$restrict_revision"
215 + test -n "$upstream" && upstream="--upstream=$upstream"
216 + test -n "$onto" && onto="--onto=$onto"
217 + test -n "$squash_onto" && squash_onto="--squash-onto=$squash_onto"
218 + test -n "$onto_name" && onto_name="--onto-name=$onto_name"
219 + test -n "$head_name" && head_name="--head-name=$head_name"
220 + test -n "$strategy" && strategy="--strategy=$strategy"
221 + test -n "$strategy_opts" && strategy_opts="--strategy-opts=$strategy_opts"
222 + test -n "$switch_to" && switch_to="--switch-to=$switch_to"
223 + test -n "$cmd" && cmd="--cmd=$cmd"
224 + test -n "$action" && action="--$action"
225 +
226 + exec git rebase--interactive2 "$action" "$keep_empty" "$rebase_merges" "$rebase_cousins" \
227 + "$upstream" "$onto" "$squash_onto" "$restrict_revision" \
228 + "$allow_empty_message" "$autosquash" "$verbose" \
229 + "$force_rebase" "$onto_name" "$head_name" "$strategy" \
230 + "$strategy_opts" "$cmd" "$switch_to" \
231 + "$allow_rerere_autoupdate" "$gpg_sign_opt" "$signoff"
232 +}
233 +
234 run_specific_rebase () {
235 if [ "$interactive_rebase" = implied ]; then
236 GIT_EDITOR=:
237 export GIT_EDITOR
238 autosquash=
239 fi
209 - . git-rebase--$type
240
211 - if test -z "$preserve_merges"
241 + if test -n "$interactive_rebase" -a -z "$preserve_merges"
242 then
213 - git_rebase__$type
243 + run_interactive
244 else
215 - git_rebase__preserve_merges
245 + . git-rebase--$type
246 +
247 + if test -z "$preserve_merges"
248 + then
249 + git_rebase__$type
250 + else
251 + git_rebase__preserve_merges
252 + fi
253 fi
254
255 ret=$?