On Sat, Mar 23, 2019 at 08:25:28AM -0700, Denton Liu wrote:
> A common scenario is if a user is working on a topic branch and they
> wish to make some changes to intermediate commits or autosquashing, they

Sorry, small typo here:

s/autosquashing/autosquash/

-Denton

> 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.den...@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
> 

Reply via email to