Show 100 quoted lines
> would run something such as
>
> git rebase -i --onto master... master
>
> in order to preserve the merge base. This prevents unnecessary commit
> churning.
>
> Alternatively, a user wishing to test individual commits in a topic
> branch without changing anything may run
>
> git rebase -x ./test.sh master... master
>
> Since rebasing onto the merge base of the branch and the upstream is
> such a common case, introduce the --keep-base option as a shortcut.
>
> This allows us to rewrite the above as
>
> git rebase -i --keep-base master
>
> and
>
> git rebase -x ./test.sh --keep-base master
>
> respectively.
>
> Signed-off-by: Denton Liu <liu.denton@gmail.com>
> ---
> builtin/rebase.c | 25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index 77deebc65c..fffee89064 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -27,8 +27,8 @@
> #include "branch.h"
>
> static char const * const builtin_rebase_usage[] = {
> - N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
> - "[<upstream>] [<branch>]"),
> + N_("git rebase [-i] [options] [--exec <cmd>] "
> + "[--onto <newbase> | --keep-base] [<upstream> [<branch>]]"),
> N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
> "--root [<branch>]"),
> N_("git rebase --continue | --abort | --skip | --edit-todo"),
> @@ -1018,6 +1018,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
> };
> const char *branch_name;
> int ret, flags, total_argc, in_progress = 0;
> + int keep_base = 0;
> int ok_to_skip_pre_rebase = 0;
> struct strbuf msg = STRBUF_INIT;
> struct strbuf revisions = STRBUF_INIT;
> @@ -1051,6 +1052,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
> OPT_STRING(0, "onto", &options.onto_name,
> N_("revision"),
> N_("rebase onto given branch instead of upstream")),
> + OPT_BOOL(0, "keep-base", &keep_base,
> + N_("use the merge-base of upstream and branch as the current base")),
> OPT_BOOL(0, "no-verify", &ok_to_skip_pre_rebase,
> N_("allow pre-rebase hook to run")),
> OPT_NEGBIT('q', "quiet", &options.flags,
> @@ -1217,6 +1220,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
> usage_with_options(builtin_rebase_usage,
> builtin_rebase_options);
>
> + if (keep_base) {
> + if (options.onto_name)
> + die(_("cannot combine '--keep-base' with '--onto'"));
> + if (options.root)
> + die(_("cannot combine '--keep-base' with '--root'"));
> + }
> +
> if (action != NO_ACTION && !in_progress)
> die(_("No rebase in progress?"));
> setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
> @@ -1541,10 +1551,19 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
> }
>
> /* Make sure the branch to rebase onto is valid. */
> - if (!options.onto_name)
> + if (keep_base) {
> + strbuf_reset(&buf);
> + strbuf_addstr(&buf, options.upstream_name);
> + strbuf_addstr(&buf, "...");
> + options.onto_name = xstrdup(buf.buf);
> + } else if (!options.onto_name)
> options.onto_name = options.upstream_name;
> if (strstr(options.onto_name, "...")) {
> if (get_oid_mb(options.onto_name, &merge_base) < 0)
> + if (keep_base)
> + die(_("'%s': need exactly one merge base with branch"),
> + options.upstream_name);
> + else
> die(_("'%s': need exactly one merge base"),
> options.onto_name);
> options.onto = lookup_commit_or_die(&merge_base,
> --
> 2.21.0.512.g57bf1b23e1
>