@@ -79,6 +79,7 @@ struct rebase_options {
79
79
struct commit * onto ;
80
80
const char * onto_name ;
81
81
const char * revisions ;
82
+ const char * switch_to ;
82
83
int root ;
83
84
struct commit * restrict_revision ;
84
85
int dont_finish_rebase ;
@@ -186,6 +187,8 @@ static int run_specific_rebase(struct rebase_options *opts)
186
187
opts -> flags & REBASE_DIFFSTAT ? "t" : "" );
187
188
add_var (& script_snippet , "force_rebase" ,
188
189
opts -> flags & REBASE_FORCE ? "t" : "" );
190
+ if (opts -> switch_to )
191
+ add_var (& script_snippet , "switch_to" , opts -> switch_to );
189
192
190
193
switch (opts -> type ) {
191
194
case REBASE_AM :
@@ -564,9 +567,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
564
567
* orig_head -- commit object name of tip of the branch before rebasing
565
568
* head_name -- refs/heads/<that-branch> or NULL (detached HEAD)
566
569
*/
567
- if (argc > 0 )
568
- die ("TODO: handle switch_to" );
569
- else {
570
+ if (argc == 1 ) {
571
+ /* Is it "rebase other branchname" or "rebase other commit"? */
572
+ branch_name = argv [0 ];
573
+ options .switch_to = argv [0 ];
574
+
575
+ /* Is it a local branch? */
576
+ strbuf_reset (& buf );
577
+ strbuf_addf (& buf , "refs/heads/%s" , branch_name );
578
+ if (!read_ref (buf .buf , & options .orig_head ))
579
+ options .head_name = xstrdup (buf .buf );
580
+ /* If not is it a valid ref (branch or commit)? */
581
+ else if (!get_oid (branch_name , & options .orig_head ))
582
+ options .head_name = NULL ;
583
+ else
584
+ die (_ ("fatal: no such branch/commit '%s'" ),
585
+ branch_name );
586
+ } else if (argc == 0 ) {
570
587
/* Do not need to switch branches, we are already on it. */
571
588
options .head_name =
572
589
xstrdup_or_null (resolve_ref_unsafe ("HEAD" , 0 , NULL ,
@@ -585,7 +602,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
585
602
}
586
603
if (get_oid ("HEAD" , & options .orig_head ))
587
604
die (_ ("Could not resolve HEAD to a revision" ));
588
- }
605
+ } else
606
+ BUG ("unexpected number of arguments left to parse" );
589
607
590
608
if (read_index (the_repository -> index ) < 0 )
591
609
die (_ ("could not read index" ));
@@ -612,6 +630,28 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
612
630
int flag ;
613
631
614
632
if (!(options .flags & REBASE_FORCE )) {
633
+ /* Lazily switch to the target branch if needed... */
634
+ if (options .switch_to ) {
635
+ struct object_id oid ;
636
+
637
+ if (get_oid (options .switch_to , & oid ) < 0 ) {
638
+ ret = !!error (_ ("could not parse '%s'" ),
639
+ options .switch_to );
640
+ goto cleanup ;
641
+ }
642
+
643
+ strbuf_reset (& buf );
644
+ strbuf_addf (& buf , "rebase: checkout %s" ,
645
+ options .switch_to );
646
+ if (reset_head (& oid , "checkout" ,
647
+ options .head_name , 0 ) < 0 ) {
648
+ ret = !!error (_ ("could not switch to "
649
+ "%s" ),
650
+ options .switch_to );
651
+ goto cleanup ;
652
+ }
653
+ }
654
+
615
655
if (!(options .flags & REBASE_NO_QUIET ))
616
656
; /* be quiet */
617
657
else if (!strcmp (branch_name , "HEAD" ) &&
0 commit comments