Skip to content

Commit b106132

Browse files
prertikdscho
authored andcommitted
builtin rebase: support --root
This option allows to rebase entire histories up to, and including, the root commit. The conversion from the shell script is straight-forward, apart from the fact that we do not have to write an empty tree in C. Signed-off-by: Pratik Karki <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f44d9fe commit b106132

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

builtin/rebase.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct rebase_options {
7676
const char *revisions;
7777
const char *switch_to;
7878
int root;
79+
struct object_id *squash_onto;
7980
struct commit *restrict_revision;
8081
int dont_finish_rebase;
8182
enum {
@@ -375,6 +376,9 @@ static int run_specific_rebase(struct rebase_options *opts)
375376
opts->rebase_cousins ? "t" : "");
376377
add_var(&script_snippet, "strategy", opts->strategy);
377378
add_var(&script_snippet, "strategy_opts", opts->strategy_opts);
379+
add_var(&script_snippet, "rebase_root", opts->root ? "t" : "");
380+
add_var(&script_snippet, "squash_onto",
381+
opts->squash_onto ? oid_to_hex(opts->squash_onto) : "");
378382

379383
switch (opts->type) {
380384
case REBASE_AM:
@@ -653,6 +657,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
653657
const char *rebase_merges = NULL;
654658
int fork_point = -1;
655659
struct string_list strategy_options = STRING_LIST_INIT_NODUP;
660+
struct object_id squash_onto;
661+
char *squash_onto_name = NULL;
656662
struct option builtin_rebase_options[] = {
657663
OPT_STRING(0, "onto", &options.onto_name,
658664
N_("revision"),
@@ -744,6 +750,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
744750
N_("option"),
745751
N_("pass the argument through to the merge "
746752
"strategy")),
753+
OPT_BOOL(0, "root", &options.root,
754+
N_("rebase all reachable commits up to the root(s)")),
747755
OPT_END(),
748756
};
749757

@@ -1021,6 +1029,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10211029
}
10221030
}
10231031

1032+
if (options.root && !options.onto_name)
1033+
imply_interactive(&options, "--root without --onto");
1034+
10241035
switch (options.type) {
10251036
case REBASE_MERGE:
10261037
case REBASE_INTERACTIVE:
@@ -1059,8 +1070,22 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10591070
if (!options.upstream)
10601071
die(_("invalid upstream '%s'"), options.upstream_name);
10611072
options.upstream_arg = options.upstream_name;
1062-
} else
1063-
die("TODO: upstream for --root");
1073+
} else {
1074+
if (!options.onto_name) {
1075+
if (commit_tree("", 0, the_hash_algo->empty_tree, NULL,
1076+
&squash_onto, NULL, NULL) < 0)
1077+
die(_("Could not create new root commit"));
1078+
options.squash_onto = &squash_onto;
1079+
options.onto_name = squash_onto_name =
1080+
xstrdup(oid_to_hex(&squash_onto));
1081+
}
1082+
options.upstream_name = NULL;
1083+
options.upstream = NULL;
1084+
if (argc > 1)
1085+
usage_with_options(builtin_rebase_usage,
1086+
builtin_rebase_options);
1087+
options.upstream_arg = "--root";
1088+
}
10641089

10651090
/* Make sure the branch to rebase onto is valid. */
10661091
if (!options.onto_name)
@@ -1208,6 +1233,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12081233
*/
12091234
if (can_fast_forward(options.onto, &options.orig_head, &merge_base) &&
12101235
!is_interactive(&options) && !options.restrict_revision &&
1236+
options.upstream &&
12111237
!oidcmp(&options.upstream->object.oid, &options.onto->object.oid)) {
12121238
int flag;
12131239

@@ -1312,5 +1338,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13121338
free(options.head_name);
13131339
free(options.gpg_sign_opt);
13141340
free(options.cmd);
1341+
free(squash_onto_name);
13151342
return ret;
13161343
}

0 commit comments

Comments
 (0)