diff --git a/.gitignore b/.gitignore index 766e80e65a..6b80c6e442 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,7 @@ /git-interpret-trailers /git-instaweb /git-legacy-rebase +/git-legacy-rebase--interactive /git-legacy-stash /git-log /git-ls-files diff --git a/Makefile b/Makefile index 29120fbfaf..a551152289 100644 --- a/Makefile +++ b/Makefile @@ -639,6 +639,7 @@ SCRIPT_SH += git-request-pull.sh SCRIPT_SH += git-submodule.sh SCRIPT_SH += git-web--browse.sh +SCRIPT_LIB += git-legacy-rebase--interactive SCRIPT_LIB += git-mergetool--lib SCRIPT_LIB += git-parse-remote SCRIPT_LIB += git-rebase--am diff --git a/builtin/rebase--interactive.c b/builtin/rebase--interactive.c index 888390f911..4a44dc286b 100644 --- a/builtin/rebase--interactive.c +++ b/builtin/rebase--interactive.c @@ -143,7 +143,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix) char *raw_strategies = NULL; enum { NONE = 0, CONTINUE, SKIP, EDIT_TODO, SHOW_CURRENT_PATCH, - SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, REARRANGE_SQUASH, ADD_EXEC + SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, REARRANGE_SQUASH, ADD_EXEC, + MAKE_SCRIPT, SKIP_UNNECESSARY_PICKS, } command = 0; struct option options[] = { OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")), @@ -196,6 +197,10 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix) OPT_RERERE_AUTOUPDATE(&opts.allow_rerere_auto), OPT_BOOL(0, "reschedule-failed-exec", &opts.reschedule_failed_exec, N_("automatically re-schedule any `exec` that fails")), + OPT_CMDMODE(0, "make-script", &command, + N_("make rebase script"), MAKE_SCRIPT), + OPT_CMDMODE(0, "skip-unnecessary-picks", &command, + N_("skip unnecessary picks"), SKIP_UNNECESSARY_PICKS), OPT_END() }; @@ -267,6 +272,18 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix) case ADD_EXEC: ret = sequencer_add_exec_commands(the_repository, cmd); break; + case MAKE_SCRIPT: + ret = sequencer_make_script(the_repository, + stdout, argc, argv, flags); + break; + case SKIP_UNNECESSARY_PICKS: { + struct object_id oid; + + ret = skip_unnecessary_picks(the_repository, &oid); + if (!ret) + printf("%s\n", oid_to_hex(&oid)); + break; + } default: BUG("invalid command '%d'", command); } diff --git a/git-legacy-rebase--interactive.sh b/git-legacy-rebase--interactive.sh new file mode 100644 index 0000000000..9740875ad5 --- /dev/null +++ b/git-legacy-rebase--interactive.sh @@ -0,0 +1,283 @@ +# This shell script fragment is sourced by git-rebase to implement +# its interactive mode. "git rebase --interactive" makes it easy +# to fix up commits in the middle of a series and rearrange commits. +# +# Copyright (c) 2006 Johannes E. Schindelin +# +# The original idea comes from Eric W. Biederman, in +# https://public-inbox.org/git/m1odwkyuf5.fsf_-_@ebiederm.dsl.xmission.com/ +# +# The file containing rebase commands, comments, and empty lines. +# This file is created by "git rebase -i" then edited by the user. As +# the lines are processed, they are removed from the front of this +# file and written to the tail of $done. +todo="$state_dir"/git-rebase-todo + +GIT_CHERRY_PICK_HELP="$resolvemsg" +export GIT_CHERRY_PICK_HELP + +comment_char=$(git config --get core.commentchar 2>/dev/null) +case "$comment_char" in +'' | auto) + comment_char="#" + ;; +?) + ;; +*) + comment_char=$(echo "$comment_char" | cut -c1) + ;; +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 +} + +append_todo_help () { + gettext " +Commands: +p, pick = use commit +r, reword = use commit, but edit the commit message +e, edit = use commit, but stop for amending +s, squash = use commit, but meld into previous commit +f, fixup = like \"squash\", but discard this commit's log message +x, exec = run command (the rest of the line) using shell +d, drop = remove commit +l, label