From: Phillip Wood Date: Mon, 18 Jun 2018 16:09:03 GMT Subject: Re: [GSoC][PATCH 3/3] rebase -i: rewrite checkout_onto() in C Message-ID: <290d8b7c-3d82-e914-0399-e8dd5a6e1513@talktalk.net> In-Reply-To: <20180618131844.13408-4-alban.gruin@gmail.com> Hi Alban On 18/06/18 14:18, Alban Gruin wrote: > This rewrites checkout_onto() from shell to C. > > A new command (“checkout-onto”) is added to rebase--helper.c. The shell > version is then stripped. > > Signed-off-by: Alban Gruin > --- > builtin/rebase--helper.c | 7 ++++++- > git-rebase--interactive.sh | 25 ++++--------------------- > sequencer.c | 19 +++++++++++++++++++ > sequencer.h | 3 +++ > 4 files changed, 32 insertions(+), 22 deletions(-) > > diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c > index d677fb663..f9fffba96 100644 > --- a/builtin/rebase--helper.c > +++ b/builtin/rebase--helper.c > @@ -17,7 +17,8 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) > enum { > CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS, > CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH, > - ADD_EXEC, APPEND_TODO_HELP, EDIT_TODO, SETUP_REFLOG > + ADD_EXEC, APPEND_TODO_HELP, EDIT_TODO, SETUP_REFLOG, > + CHECKOUT_ONTO > } command = 0; > struct option options[] = { > OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")), > @@ -53,6 +54,8 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) > EDIT_TODO), > OPT_CMDMODE(0, "setup-reflog", &command, > N_("setup the reflog action"), SETUP_REFLOG), > + OPT_CMDMODE(0, "checkout-onto", &command, > + N_("checkout a commit"), CHECKOUT_ONTO), > OPT_END() > }; > > @@ -98,5 +101,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) > return !!edit_todo_list(flags); > if (command == SETUP_REFLOG && argc == 2) > return !!setup_reflog_action(&opts, argv[1], verbose); > + if (command == CHECKOUT_ONTO && argc == 4) > + return !!checkout_onto(&opts, argv[1], argv[2], argv[3], verbose); > usage_with_options(builtin_rebase_helper_usage, options); > } > diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh > index 048bbf041..0ae053291 100644 > --- a/git-rebase--interactive.sh > +++ b/git-rebase--interactive.sh > @@ -28,17 +28,6 @@ case "$comment_char" in > ;; > esac > > -orig_reflog_action="$GIT_REFLOG_ACTION" > - > -comment_for_reflog () { > - case "$orig_reflog_action" in > - ''|rebase*) > - GIT_REFLOG_ACTION="rebase -i ($1)" > - export GIT_REFLOG_ACTION > - ;; > - esac > -} > - > die_abort () { > apply_autostash > rm -rf "$state_dir" > @@ -70,14 +59,6 @@ collapse_todo_ids() { > git rebase--helper --shorten-ids > } > > -# Switch to the branch in $into and notify it in the reflog > -checkout_onto () { > - comment_for_reflog start > - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" > - output git checkout $onto || die_abort "$(gettext "could not detach HEAD")" > - git update-ref ORIG_HEAD $orig_head > -} > - > get_missing_commit_check_level () { > check_level=$(git config --get rebase.missingCommitsCheck) > check_level=${check_level:-ignore} > @@ -176,7 +157,8 @@ EOF > > git rebase--helper --check-todo-list || { > ret=$? > - checkout_onto > + git rebase--helper --checkout-onto "$onto_name" "$onto" \ > + "$orig_head" ${verbose:+--verbose} > exit $ret > } > > @@ -186,7 +168,8 @@ EOF > onto="$(git rebase--helper --skip-unnecessary-picks)" || > die "Could not skip unnecessary pick commands" > > - checkout_onto > + git rebase--helper --checkout-onto "$onto_name" "$onto" "$orig_head" \ > + ${verbose:+--verbose} > require_clean_work_tree "rebase" > exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ > --continue > diff --git a/sequencer.c b/sequencer.c > index 4bfe29c7b..d149cbf92 100644 > --- a/sequencer.c > +++ b/sequencer.c > @@ -3162,6 +3162,25 @@ int setup_reflog_action(struct replay_opts *opts, const char *commit, > return 0; > } > > +int checkout_onto(struct replay_opts *opts, > + const char *onto_name, const char *onto, > + const char *orig_head, unsigned verbose) > +{ > + struct object_id oid; > + const char *action = reflog_message(opts, "start", "checkout %s", onto_name); > + > + if (get_oid(orig_head, &oid)) > + die(_("%s: not a valid OID"), orig_head); If this code is going to live long-term in sequencer.c then it would be better not to die, but return an error instead as it's part of libgit. Best Wishes Phillip > + > + if (checkout_base_commit(opts, onto, verbose, action)) { > + apply_autostash(opts); > + sequencer_remove_state(opts); > + die(_("could not detach HEAD")); > + } > + > + return update_ref(NULL, "ORIG_HEAD", &oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR); > +} > + > static const char rescheduled_advice[] = > N_("Could not execute the todo command\n" > "\n" > diff --git a/sequencer.h b/sequencer.h > index 55e4057d8..9899d90fc 100644 > --- a/sequencer.h > +++ b/sequencer.h > @@ -102,6 +102,9 @@ void commit_post_rewrite(const struct commit *current_head, > > int setup_reflog_action(struct replay_opts *opts, const char *commit, > int verbose); > +int checkout_onto(struct replay_opts *opts, > + const char *onto_name, const char *onto, > + const char *orig_head, unsigned verbose); > > #define SUMMARY_INITIAL_COMMIT (1 << 0) > #define SUMMARY_SHOW_AUTHOR_DATE (1 << 1) >