@@ -524,14 +524,16 @@ static int run_specific_rebase(struct rebase_options *opts)
524
524
#define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
525
525
526
526
#define RESET_HEAD_DETACH (1<<0)
527
+ #define RESET_HEAD_HARD (1<<1)
527
528
528
529
static int reset_head (struct object_id * oid , const char * action ,
529
530
const char * switch_to_branch , unsigned flags ,
530
531
const char * reflog_orig_head , const char * reflog_head )
531
532
{
532
533
unsigned detach_head = flags & RESET_HEAD_DETACH ;
534
+ unsigned reset_hard = flags & RESET_HEAD_HARD ;
533
535
struct object_id head_oid ;
534
- struct tree_desc desc ;
536
+ struct tree_desc desc [ 2 ] = { { NULL }, { NULL } } ;
535
537
struct lock_file lock = LOCK_INIT ;
536
538
struct unpack_trees_options unpack_tree_opts ;
537
539
struct tree * tree ;
@@ -540,7 +542,7 @@ static int reset_head(struct object_id *oid, const char *action,
540
542
size_t prefix_len ;
541
543
struct object_id * orig = NULL , oid_orig ,
542
544
* old_orig = NULL , oid_old_orig ;
543
- int ret = 0 ;
545
+ int ret = 0 , nr = 0 ;
544
546
545
547
if (switch_to_branch && !starts_with (switch_to_branch , "refs/" ))
546
548
BUG ("Not a fully qualified branch: '%s'" , switch_to_branch );
@@ -550,20 +552,20 @@ static int reset_head(struct object_id *oid, const char *action,
550
552
goto leave_reset_head ;
551
553
}
552
554
553
- if (!oid ) {
554
- if (get_oid ("HEAD" , & head_oid )) {
555
- ret = error (_ ("could not determine HEAD revision" ));
556
- goto leave_reset_head ;
557
- }
558
- oid = & head_oid ;
555
+ if ((!oid || !reset_hard ) && get_oid ("HEAD" , & head_oid )) {
556
+ ret = error (_ ("could not determine HEAD revision" ));
557
+ goto leave_reset_head ;
559
558
}
560
559
560
+ if (!oid )
561
+ oid = & head_oid ;
562
+
561
563
memset (& unpack_tree_opts , 0 , sizeof (unpack_tree_opts ));
562
564
setup_unpack_trees_porcelain (& unpack_tree_opts , action );
563
565
unpack_tree_opts .head_idx = 1 ;
564
566
unpack_tree_opts .src_index = the_repository -> index ;
565
567
unpack_tree_opts .dst_index = the_repository -> index ;
566
- unpack_tree_opts .fn = oneway_merge ;
568
+ unpack_tree_opts .fn = reset_hard ? oneway_merge : twoway_merge ;
567
569
unpack_tree_opts .update = 1 ;
568
570
unpack_tree_opts .merge = 1 ;
569
571
if (!detach_head )
@@ -574,12 +576,17 @@ static int reset_head(struct object_id *oid, const char *action,
574
576
goto leave_reset_head ;
575
577
}
576
578
577
- if (!fill_tree_descriptor (& desc , oid )) {
579
+ if (!reset_hard && !fill_tree_descriptor (& desc [nr ++ ], & head_oid )) {
580
+ ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
581
+ goto leave_reset_head ;
582
+ }
583
+
584
+ if (!fill_tree_descriptor (& desc [nr ++ ], oid )) {
578
585
ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
579
586
goto leave_reset_head ;
580
587
}
581
588
582
- if (unpack_trees (1 , & desc , & unpack_tree_opts )) {
589
+ if (unpack_trees (nr , desc , & unpack_tree_opts )) {
583
590
ret = -1 ;
584
591
goto leave_reset_head ;
585
592
}
@@ -627,7 +634,8 @@ static int reset_head(struct object_id *oid, const char *action,
627
634
leave_reset_head :
628
635
strbuf_release (& msg );
629
636
rollback_lock_file (& lock );
630
- free ((void * )desc .buffer );
637
+ while (nr )
638
+ free ((void * )desc [-- nr ].buffer );
631
639
return ret ;
632
640
}
633
641
@@ -1005,7 +1013,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1005
1013
rerere_clear (& merge_rr );
1006
1014
string_list_clear (& merge_rr , 1 );
1007
1015
1008
- if (reset_head (NULL , "reset" , NULL , 0 , NULL , NULL ) < 0 )
1016
+ if (reset_head (NULL , "reset" , NULL , RESET_HEAD_HARD ,
1017
+ NULL , NULL ) < 0 )
1009
1018
die (_ ("could not discard worktree changes" ));
1010
1019
if (read_basic_state (& options ))
1011
1020
exit (1 );
@@ -1021,7 +1030,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1021
1030
if (read_basic_state (& options ))
1022
1031
exit (1 );
1023
1032
if (reset_head (& options .orig_head , "reset" ,
1024
- options .head_name , 0 , NULL , NULL ) < 0 )
1033
+ options .head_name , RESET_HEAD_HARD ,
1034
+ NULL , NULL ) < 0 )
1025
1035
die (_ ("could not move back to %s" ),
1026
1036
oid_to_hex (& options .orig_head ));
1027
1037
ret = finish_rebase (& options );
@@ -1385,7 +1395,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1385
1395
write_file (autostash , "%s" , oid_to_hex (& oid ));
1386
1396
printf (_ ("Created autostash: %s\n" ), buf .buf );
1387
1397
if (reset_head (& head -> object .oid , "reset --hard" ,
1388
- NULL , 0 , NULL , NULL ) < 0 )
1398
+ NULL , RESET_HEAD_HARD , NULL , NULL ) < 0 )
1389
1399
die (_ ("could not reset --hard" ));
1390
1400
printf (_ ("HEAD is now at %s" ),
1391
1401
find_unique_abbrev (& head -> object .oid ,
0 commit comments