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