@@ -702,12 +702,17 @@ static int run_specific_rebase(struct rebase_options *opts)
702
702
703
703
#define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
704
704
705
+ #define RESET_HEAD_DETACH (1<<0)
706
+ #define RESET_HEAD_HARD (1<<1)
707
+
705
708
static int reset_head (struct object_id * oid , const char * action ,
706
- const char * switch_to_branch , int detach_head ,
709
+ const char * switch_to_branch , unsigned flags ,
707
710
const char * reflog_orig_head , const char * reflog_head )
708
711
{
712
+ unsigned detach_head = flags & RESET_HEAD_DETACH ;
713
+ unsigned reset_hard = flags & RESET_HEAD_HARD ;
709
714
struct object_id head_oid ;
710
- struct tree_desc desc ;
715
+ struct tree_desc desc [ 2 ] = { { NULL }, { NULL } } ;
711
716
struct lock_file lock = LOCK_INIT ;
712
717
struct unpack_trees_options unpack_tree_opts ;
713
718
struct tree * tree ;
@@ -716,60 +721,62 @@ static int reset_head(struct object_id *oid, const char *action,
716
721
size_t prefix_len ;
717
722
struct object_id * orig = NULL , oid_orig ,
718
723
* old_orig = NULL , oid_old_orig ;
719
- int ret = 0 ;
724
+ int ret = 0 , nr = 0 ;
720
725
721
726
if (switch_to_branch && !starts_with (switch_to_branch , "refs/" ))
722
727
BUG ("Not a fully qualified branch: '%s'" , switch_to_branch );
723
728
724
- if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 )
725
- return -1 ;
729
+ if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 ) {
730
+ ret = -1 ;
731
+ goto leave_reset_head ;
732
+ }
726
733
727
- if (!oid ) {
728
- if (get_oid ("HEAD" , & head_oid )) {
729
- rollback_lock_file (& lock );
730
- return error (_ ("could not determine HEAD revision" ));
731
- }
732
- oid = & head_oid ;
734
+ if ((!oid || !reset_hard ) && get_oid ("HEAD" , & head_oid )) {
735
+ ret = error (_ ("could not determine HEAD revision" ));
736
+ goto leave_reset_head ;
733
737
}
734
738
739
+ if (!oid )
740
+ oid = & head_oid ;
741
+
735
742
memset (& unpack_tree_opts , 0 , sizeof (unpack_tree_opts ));
736
743
setup_unpack_trees_porcelain (& unpack_tree_opts , action );
737
744
unpack_tree_opts .head_idx = 1 ;
738
745
unpack_tree_opts .src_index = the_repository -> index ;
739
746
unpack_tree_opts .dst_index = the_repository -> index ;
740
- unpack_tree_opts .fn = oneway_merge ;
747
+ unpack_tree_opts .fn = reset_hard ? oneway_merge : twoway_merge ;
741
748
unpack_tree_opts .update = 1 ;
742
749
unpack_tree_opts .merge = 1 ;
743
750
if (!detach_head )
744
751
unpack_tree_opts .reset = 1 ;
745
752
746
753
if (read_index_unmerged (the_repository -> index ) < 0 ) {
747
- rollback_lock_file ( & lock );
748
- return error ( _ ( "could not read index" )) ;
754
+ ret = error ( _ ( "could not read index" ) );
755
+ goto leave_reset_head ;
749
756
}
750
757
751
- if (!fill_tree_descriptor (& desc , oid )) {
752
- error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
753
- rollback_lock_file (& lock );
754
- free ((void * )desc .buffer );
755
- return -1 ;
758
+ if (!reset_hard && !fill_tree_descriptor (& desc [nr ++ ], & head_oid )) {
759
+ ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
760
+ goto leave_reset_head ;
756
761
}
757
762
758
- if (unpack_trees (1 , & desc , & unpack_tree_opts )) {
759
- rollback_lock_file (& lock );
760
- free ((void * )desc .buffer );
761
- return -1 ;
763
+ if (!fill_tree_descriptor (& desc [nr ++ ], oid )) {
764
+ ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
765
+ goto leave_reset_head ;
766
+ }
767
+
768
+ if (unpack_trees (nr , desc , & unpack_tree_opts )) {
769
+ ret = -1 ;
770
+ goto leave_reset_head ;
762
771
}
763
772
764
773
tree = parse_tree_indirect (oid );
765
774
prime_cache_tree (the_repository -> index , tree );
766
775
767
- if (write_locked_index (the_repository -> index , & lock , COMMIT_LOCK ) < 0 )
776
+ if (write_locked_index (the_repository -> index , & lock , COMMIT_LOCK ) < 0 ) {
768
777
ret = error (_ ("could not write index" ));
769
- free ((void * )desc .buffer );
770
-
771
- if (ret )
772
- return ret ;
778
+ goto leave_reset_head ;
779
+ }
773
780
774
781
reflog_action = getenv (GIT_REFLOG_ACTION_ENVIRONMENT );
775
782
strbuf_addf (& msg , "%s: " , reflog_action ? reflog_action : "rebase" );
@@ -803,7 +810,11 @@ static int reset_head(struct object_id *oid, const char *action,
803
810
UPDATE_REFS_MSG_ON_ERR );
804
811
}
805
812
813
+ leave_reset_head :
806
814
strbuf_release (& msg );
815
+ rollback_lock_file (& lock );
816
+ while (nr )
817
+ free ((void * )desc [-- nr ].buffer );
807
818
return ret ;
808
819
}
809
820
@@ -1181,7 +1192,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1181
1192
rerere_clear (& merge_rr );
1182
1193
string_list_clear (& merge_rr , 1 );
1183
1194
1184
- if (reset_head (NULL , "reset" , NULL , 0 , NULL , NULL ) < 0 )
1195
+ if (reset_head (NULL , "reset" , NULL , RESET_HEAD_HARD ,
1196
+ NULL , NULL ) < 0 )
1185
1197
die (_ ("could not discard worktree changes" ));
1186
1198
remove_branch_state ();
1187
1199
if (read_basic_state (& options ))
@@ -1198,7 +1210,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1198
1210
if (read_basic_state (& options ))
1199
1211
exit (1 );
1200
1212
if (reset_head (& options .orig_head , "reset" ,
1201
- options .head_name , 0 , NULL , NULL ) < 0 )
1213
+ options .head_name , RESET_HEAD_HARD ,
1214
+ NULL , NULL ) < 0 )
1202
1215
die (_ ("could not move back to %s" ),
1203
1216
oid_to_hex (& options .orig_head ));
1204
1217
remove_branch_state ();
@@ -1563,7 +1576,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1563
1576
write_file (autostash , "%s" , oid_to_hex (& oid ));
1564
1577
printf (_ ("Created autostash: %s\n" ), buf .buf );
1565
1578
if (reset_head (& head -> object .oid , "reset --hard" ,
1566
- NULL , 0 , NULL , NULL ) < 0 )
1579
+ NULL , RESET_HEAD_HARD , NULL , NULL ) < 0 )
1567
1580
die (_ ("could not reset --hard" ));
1568
1581
printf (_ ("HEAD is now at %s" ),
1569
1582
find_unique_abbrev (& head -> object .oid ,
@@ -1683,8 +1696,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1683
1696
"it...\n" ));
1684
1697
1685
1698
strbuf_addf (& msg , "rebase: checkout %s" , options .onto_name );
1686
- if (reset_head (& options .onto -> object .oid , "checkout" , NULL , 1 ,
1687
- NULL , msg .buf ))
1699
+ if (reset_head (& options .onto -> object .oid , "checkout" , NULL ,
1700
+ RESET_HEAD_DETACH , NULL , msg .buf ))
1688
1701
die (_ ("Could not detach HEAD" ));
1689
1702
strbuf_release (& msg );
1690
1703
0 commit comments