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