builtin rebase: support `git rebase --onto A...B`
authorPratik Karki <predatoramigo@gmail.com>
Tue, 4 Sep 2018 21:27:09 +0000 (14:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Sep 2018 18:55:42 +0000 (11:55 -0700)
This commit implements support for an --onto argument that is actually a
"symmetric range" i.e. `<rev1>...<rev2>`.

The equivalent shell script version of the code offers two different
error messages for the cases where there is no merge base vs more than
one merge base.

Though it would be nice to retain this distinction, dropping it makes it
possible to simply use the `get_oid_mb()` function. Besides, it happens
rarely in real-world scenarios.

Therefore, in the interest of keeping the code less complex, let's just
use that function, and live with an error message that does not
distinguish between those two error conditions.

Signed-off-by: Pratik Karki <predatoramigo@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rebase.c
index 742ed3149824b8b6e2b6080ad9c9a2a60339cf0d..38c496dd10baeab8545a4c2a5475d89aec512546 100644 (file)
@@ -17,6 +17,7 @@
 #include "unpack-trees.h"
 #include "lockfile.h"
 #include "parse-options.h"
+#include "commit.h"
 
 static char const * const builtin_rebase_usage[] = {
        N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
@@ -311,6 +312,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
        int ret, flags;
        struct strbuf msg = STRBUF_INIT;
        struct strbuf revisions = STRBUF_INIT;
+       struct object_id merge_base;
        struct option builtin_rebase_options[] = {
                OPT_STRING(0, "onto", &options.onto_name,
                           N_("revision"),
@@ -387,7 +389,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
        if (!options.onto_name)
                options.onto_name = options.upstream_name;
        if (strstr(options.onto_name, "...")) {
-               die("TODO");
+               if (get_oid_mb(options.onto_name, &merge_base) < 0)
+                       die(_("'%s': need exactly one merge base"),
+                           options.onto_name);
+               options.onto = lookup_commit_or_die(&merge_base,
+                                                   options.onto_name);
        } else {
                options.onto = peel_committish(options.onto_name);
                if (!options.onto)