@@ -123,6 +123,12 @@ static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")
123123static GIT_PATH_FUNC (rebase_path_rewritten_pending ,
124124 "rebase-merge/rewritten-pending" )
125125
126+ /*
127+ * The path of the file containig the OID of the "squash onto" commit, i.e.
128+ * the dummy commit used for `reset [new root]`.
129+ */
130+ static GIT_PATH_FUNC (rebase_path_squash_onto , "rebase-merge/squash-onto" )
131+
126132/*
127133 * The path of the file listing refs that need to be deleted after the rebase
128134 * finishes. This is used by the `label` command to record the need for cleanup.
@@ -469,7 +475,8 @@ static int fast_forward_to(const struct object_id *to, const struct object_id *f
469475 transaction = ref_transaction_begin (& err );
470476 if (!transaction ||
471477 ref_transaction_update (transaction , "HEAD" ,
472- to , unborn ? & null_oid : from ,
478+ to , unborn && !is_rebase_i (opts ) ?
479+ & null_oid : from ,
473480 0 , sb .buf , & err ) ||
474481 ref_transaction_commit (transaction , & err )) {
475482 ref_transaction_free (transaction );
@@ -561,9 +568,23 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
561568 return !clean ;
562569}
563570
571+ static struct object_id * get_cache_tree_oid (void )
572+ {
573+ if (!active_cache_tree )
574+ active_cache_tree = cache_tree ();
575+
576+ if (!cache_tree_fully_valid (active_cache_tree ))
577+ if (cache_tree_update (& the_index , 0 )) {
578+ error (_ ("unable to update cache tree" ));
579+ return NULL ;
580+ }
581+
582+ return & active_cache_tree -> oid ;
583+ }
584+
564585static int is_index_unchanged (void )
565586{
566- struct object_id head_oid ;
587+ struct object_id head_oid , * cache_tree_oid ;
567588 struct commit * head_commit ;
568589
569590 if (!resolve_ref_unsafe ("HEAD" , RESOLVE_REF_READING , & head_oid , NULL ))
@@ -582,15 +603,10 @@ static int is_index_unchanged(void)
582603 if (parse_commit (head_commit ))
583604 return -1 ;
584605
585- if (!active_cache_tree )
586- active_cache_tree = cache_tree ();
587-
588- if (!cache_tree_fully_valid (active_cache_tree ))
589- if (cache_tree_update (& the_index , 0 ))
590- return error (_ ("unable to update cache tree" ));
606+ if (!(cache_tree_oid = get_cache_tree_oid ()))
607+ return -1 ;
591608
592- return !oidcmp (& active_cache_tree -> oid ,
593- get_commit_tree_oid (head_commit ));
609+ return !oidcmp (cache_tree_oid , get_commit_tree_oid (head_commit ));
594610}
595611
596612static int write_author_script (const char * message )
@@ -682,6 +698,52 @@ static char *get_author(const char *message)
682698 return NULL ;
683699}
684700
701+ /* Read author-script and return an ident line (author <email> timestamp) */
702+ static const char * read_author_ident (struct strbuf * buf )
703+ {
704+ const char * keys [] = {
705+ "GIT_AUTHOR_NAME=" , "GIT_AUTHOR_EMAIL=" , "GIT_AUTHOR_DATE="
706+ };
707+ char * in , * out , * eol ;
708+ int i = 0 , len ;
709+
710+ if (strbuf_read_file (buf , rebase_path_author_script (), 256 ) <= 0 )
711+ return NULL ;
712+
713+ /* dequote values and construct ident line in-place */
714+ for (in = out = buf -> buf ; i < 3 && in - buf -> buf < buf -> len ; i ++ ) {
715+ if (!skip_prefix (in , keys [i ], (const char * * )& in )) {
716+ warning ("could not parse '%s' (looking for '%s'" ,
717+ rebase_path_author_script (), keys [i ]);
718+ return NULL ;
719+ }
720+
721+ eol = strchrnul (in , '\n' );
722+ * eol = '\0' ;
723+ sq_dequote (in );
724+ len = strlen (in );
725+
726+ if (i > 0 ) /* separate values by spaces */
727+ * (out ++ ) = ' ' ;
728+ if (i == 1 ) /* email needs to be surrounded by <...> */
729+ * (out ++ ) = '<' ;
730+ memmove (out , in , len );
731+ out += len ;
732+ if (i == 1 ) /* email needs to be surrounded by <...> */
733+ * (out ++ ) = '>' ;
734+ in = eol + 1 ;
735+ }
736+
737+ if (i < 3 ) {
738+ warning ("could not parse '%s' (looking for '%s')" ,
739+ rebase_path_author_script (), keys [i ]);
740+ return NULL ;
741+ }
742+
743+ buf -> len = out - buf -> buf ;
744+ return buf -> buf ;
745+ }
746+
685747static const char staged_changes_advice [] =
686748N_ ("you have staged changes in your working tree\n"
687749"If these changes are meant to be squashed into the previous commit, run:\n"
@@ -701,6 +763,7 @@ N_("you have staged changes in your working tree\n"
701763#define AMEND_MSG (1<<2)
702764#define CLEANUP_MSG (1<<3)
703765#define VERIFY_MSG (1<<4)
766+ #define CREATE_ROOT_COMMIT (1<<5)
704767
705768/*
706769 * If we are cherry-pick, and if the merge did not result in
@@ -720,6 +783,40 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
720783 struct child_process cmd = CHILD_PROCESS_INIT ;
721784 const char * value ;
722785
786+ if (flags & CREATE_ROOT_COMMIT ) {
787+ struct strbuf msg = STRBUF_INIT , script = STRBUF_INIT ;
788+ const char * author = is_rebase_i (opts ) ?
789+ read_author_ident (& script ) : NULL ;
790+ struct object_id root_commit , * cache_tree_oid ;
791+ int res = 0 ;
792+
793+ if (!defmsg )
794+ BUG ("root commit without message" );
795+
796+ if (!(cache_tree_oid = get_cache_tree_oid ()))
797+ res = -1 ;
798+
799+ if (!res )
800+ res = strbuf_read_file (& msg , defmsg , 0 );
801+
802+ if (res <= 0 )
803+ res = error_errno (_ ("could not read '%s'" ), defmsg );
804+ else
805+ res = commit_tree (msg .buf , msg .len , cache_tree_oid ,
806+ NULL , & root_commit , author ,
807+ opts -> gpg_sign );
808+
809+ strbuf_release (& msg );
810+ strbuf_release (& script );
811+ if (!res ) {
812+ update_ref (NULL , "CHERRY_PICK_HEAD" , & root_commit , NULL ,
813+ REF_NO_DEREF , UPDATE_REFS_MSG_ON_ERR );
814+ res = update_ref (NULL , "HEAD" , & root_commit , NULL , 0 ,
815+ UPDATE_REFS_MSG_ON_ERR );
816+ }
817+ return res < 0 ? error (_ ("writing root commit" )) : 0 ;
818+ }
819+
723820 cmd .git_cmd = 1 ;
724821
725822 if (is_rebase_i (opts )) {
@@ -1210,7 +1307,8 @@ static int do_commit(const char *msg_file, const char *author,
12101307{
12111308 int res = 1 ;
12121309
1213- if (!(flags & EDIT_MSG ) && !(flags & VERIFY_MSG )) {
1310+ if (!(flags & EDIT_MSG ) && !(flags & VERIFY_MSG ) &&
1311+ !(flags & CREATE_ROOT_COMMIT )) {
12141312 struct object_id oid ;
12151313 struct strbuf sb = STRBUF_INIT ;
12161314
@@ -1363,6 +1461,22 @@ static int is_fixup(enum todo_command command)
13631461 return command == TODO_FIXUP || command == TODO_SQUASH ;
13641462}
13651463
1464+ /* Does this command create a (non-merge) commit? */
1465+ static int is_pick_or_similar (enum todo_command command )
1466+ {
1467+ switch (command ) {
1468+ case TODO_PICK :
1469+ case TODO_REVERT :
1470+ case TODO_EDIT :
1471+ case TODO_REWORD :
1472+ case TODO_FIXUP :
1473+ case TODO_SQUASH :
1474+ return 1 ;
1475+ default :
1476+ return 0 ;
1477+ }
1478+ }
1479+
13661480static int update_squash_messages (enum todo_command command ,
13671481 struct commit * commit , struct replay_opts * opts )
13681482{
@@ -1516,7 +1630,14 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
15161630 return error (_ ("your index file is unmerged." ));
15171631 } else {
15181632 unborn = get_oid ("HEAD" , & head );
1519- if (unborn )
1633+ /* Do we want to generate a root commit? */
1634+ if (is_pick_or_similar (command ) && opts -> have_squash_onto &&
1635+ !oidcmp (& head , & opts -> squash_onto )) {
1636+ if (is_fixup (command ))
1637+ return error (_ ("cannot fixup root commit" ));
1638+ flags |= CREATE_ROOT_COMMIT ;
1639+ unborn = 1 ;
1640+ } else if (unborn )
15201641 oidcpy (& head , the_hash_algo -> empty_tree );
15211642 if (index_differs_from (unborn ? EMPTY_TREE_SHA1_HEX : "HEAD" ,
15221643 NULL , 0 ))
@@ -2142,6 +2263,12 @@ static int read_populate_opts(struct replay_opts *opts)
21422263 }
21432264 }
21442265
2266+ if (read_oneliner (& buf , rebase_path_squash_onto (), 0 )) {
2267+ if (get_oid_hex (buf .buf , & opts -> squash_onto ) < 0 )
2268+ return error (_ ("unusable squash-onto" ));
2269+ opts -> have_squash_onto = 1 ;
2270+ }
2271+
21452272 return 0 ;
21462273 }
21472274
@@ -2634,18 +2761,34 @@ static int do_reset(const char *name, int len, struct replay_opts *opts)
26342761 if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 )
26352762 return -1 ;
26362763
2637- /* Determine the length of the label */
2638- for (i = 0 ; i < len ; i ++ )
2639- if (isspace (name [i ]))
2640- len = i ;
2641-
2642- strbuf_addf (& ref_name , "refs/rewritten/%.*s" , len , name );
2643- if (get_oid (ref_name .buf , & oid ) &&
2644- get_oid (ref_name .buf + strlen ("refs/rewritten/" ), & oid )) {
2645- error (_ ("could not read '%s'" ), ref_name .buf );
2646- rollback_lock_file (& lock );
2647- strbuf_release (& ref_name );
2648- return -1 ;
2764+ if (len == 10 && !strncmp ("[new root]" , name , len )) {
2765+ if (!opts -> have_squash_onto ) {
2766+ const char * hex ;
2767+ if (commit_tree ("" , 0 , the_hash_algo -> empty_tree ,
2768+ NULL , & opts -> squash_onto ,
2769+ NULL , NULL ))
2770+ return error (_ ("writing fake root commit" ));
2771+ opts -> have_squash_onto = 1 ;
2772+ hex = oid_to_hex (& opts -> squash_onto );
2773+ if (write_message (hex , strlen (hex ),
2774+ rebase_path_squash_onto (), 0 ))
2775+ return error (_ ("writing squash-onto" ));
2776+ }
2777+ oidcpy (& oid , & opts -> squash_onto );
2778+ } else {
2779+ /* Determine the length of the label */
2780+ for (i = 0 ; i < len ; i ++ )
2781+ if (isspace (name [i ]))
2782+ len = i ;
2783+
2784+ strbuf_addf (& ref_name , "refs/rewritten/%.*s" , len , name );
2785+ if (get_oid (ref_name .buf , & oid ) &&
2786+ get_oid (ref_name .buf + strlen ("refs/rewritten/" ), & oid )) {
2787+ error (_ ("could not read '%s'" ), ref_name .buf );
2788+ rollback_lock_file (& lock );
2789+ strbuf_release (& ref_name );
2790+ return -1 ;
2791+ }
26492792 }
26502793
26512794 memset (& unpack_tree_opts , 0 , sizeof (unpack_tree_opts ));
@@ -2741,6 +2884,18 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
27412884 goto leave_merge ;
27422885 }
27432886
2887+ if (opts -> have_squash_onto &&
2888+ !oidcmp (& head_commit -> object .oid , & opts -> squash_onto )) {
2889+ /*
2890+ * When the user tells us to "merge" something into a
2891+ * "[new root]", let's simply fast-forward to the merge head.
2892+ */
2893+ rollback_lock_file (& lock );
2894+ ret = fast_forward_to (& merge_commit -> object .oid ,
2895+ & head_commit -> object .oid , 0 , opts );
2896+ goto leave_merge ;
2897+ }
2898+
27442899 if (commit ) {
27452900 const char * message = get_commit_buffer (commit , NULL );
27462901 const char * body ;
@@ -3850,7 +4005,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,
38504005 }
38514006
38524007 if (!commit )
3853- fprintf (out , "%s onto\n" , cmd_reset );
4008+ fprintf (out , "%s %s\n" , cmd_reset ,
4009+ rebase_cousins ? "onto" : "[new root]" );
38544010 else {
38554011 const char * to = NULL ;
38564012
0 commit comments