@@ -524,12 +524,17 @@ static int run_specific_rebase(struct rebase_options *opts)
524
524
525
525
#define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
526
526
527
+ #define RESET_HEAD_DETACH (1<<0)
528
+ #define RESET_HEAD_HARD (1<<1)
529
+
527
530
static int reset_head (struct object_id * oid , const char * action ,
528
- const char * switch_to_branch , int detach_head ,
531
+ const char * switch_to_branch , unsigned flags ,
529
532
const char * reflog_orig_head , const char * reflog_head )
530
533
{
534
+ unsigned detach_head = flags & RESET_HEAD_DETACH ;
535
+ unsigned reset_hard = flags & RESET_HEAD_HARD ;
531
536
struct object_id head_oid ;
532
- struct tree_desc desc ;
537
+ struct tree_desc desc [ 2 ] = { { NULL }, { NULL } } ;
533
538
struct lock_file lock = LOCK_INIT ;
534
539
struct unpack_trees_options unpack_tree_opts ;
535
540
struct tree * tree ;
@@ -538,60 +543,62 @@ static int reset_head(struct object_id *oid, const char *action,
538
543
size_t prefix_len ;
539
544
struct object_id * orig = NULL , oid_orig ,
540
545
* old_orig = NULL , oid_old_orig ;
541
- int ret = 0 ;
546
+ int ret = 0 , nr = 0 ;
542
547
543
548
if (switch_to_branch && !starts_with (switch_to_branch , "refs/" ))
544
549
BUG ("Not a fully qualified branch: '%s'" , switch_to_branch );
545
550
546
- if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 )
547
- return -1 ;
551
+ if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 ) {
552
+ ret = -1 ;
553
+ goto leave_reset_head ;
554
+ }
548
555
549
- if (!oid ) {
550
- if (get_oid ("HEAD" , & head_oid )) {
551
- rollback_lock_file (& lock );
552
- return error (_ ("could not determine HEAD revision" ));
553
- }
554
- oid = & head_oid ;
556
+ if ((!oid || !reset_hard ) && get_oid ("HEAD" , & head_oid )) {
557
+ ret = error (_ ("could not determine HEAD revision" ));
558
+ goto leave_reset_head ;
555
559
}
556
560
561
+ if (!oid )
562
+ oid = & head_oid ;
563
+
557
564
memset (& unpack_tree_opts , 0 , sizeof (unpack_tree_opts ));
558
565
setup_unpack_trees_porcelain (& unpack_tree_opts , action );
559
566
unpack_tree_opts .head_idx = 1 ;
560
567
unpack_tree_opts .src_index = the_repository -> index ;
561
568
unpack_tree_opts .dst_index = the_repository -> index ;
562
- unpack_tree_opts .fn = oneway_merge ;
569
+ unpack_tree_opts .fn = reset_hard ? oneway_merge : twoway_merge ;
563
570
unpack_tree_opts .update = 1 ;
564
571
unpack_tree_opts .merge = 1 ;
565
572
if (!detach_head )
566
573
unpack_tree_opts .reset = 1 ;
567
574
568
575
if (read_index_unmerged (the_repository -> index ) < 0 ) {
569
- rollback_lock_file ( & lock );
570
- return error ( _ ( "could not read index" )) ;
576
+ ret = error ( _ ( "could not read index" ) );
577
+ goto leave_reset_head ;
571
578
}
572
579
573
- if (!fill_tree_descriptor (& desc , oid )) {
574
- error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
575
- rollback_lock_file (& lock );
576
- free ((void * )desc .buffer );
577
- return -1 ;
580
+ if (!reset_hard && !fill_tree_descriptor (& desc [nr ++ ], & head_oid )) {
581
+ ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
582
+ goto leave_reset_head ;
578
583
}
579
584
580
- if (unpack_trees (1 , & desc , & unpack_tree_opts )) {
581
- rollback_lock_file (& lock );
582
- free ((void * )desc .buffer );
583
- return -1 ;
585
+ if (!fill_tree_descriptor (& desc [nr ++ ], oid )) {
586
+ ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
587
+ goto leave_reset_head ;
588
+ }
589
+
590
+ if (unpack_trees (nr , desc , & unpack_tree_opts )) {
591
+ ret = -1 ;
592
+ goto leave_reset_head ;
584
593
}
585
594
586
595
tree = parse_tree_indirect (oid );
587
596
prime_cache_tree (the_repository -> index , tree );
588
597
589
- if (write_locked_index (the_repository -> index , & lock , COMMIT_LOCK ) < 0 )
598
+ if (write_locked_index (the_repository -> index , & lock , COMMIT_LOCK ) < 0 ) {
590
599
ret = error (_ ("could not write index" ));
591
- free ((void * )desc .buffer );
592
-
593
- if (ret )
594
- return ret ;
600
+ goto leave_reset_head ;
601
+ }
595
602
596
603
reflog_action = getenv (GIT_REFLOG_ACTION_ENVIRONMENT );
597
604
strbuf_addf (& msg , "%s: " , reflog_action ? reflog_action : "rebase" );
@@ -625,7 +632,11 @@ static int reset_head(struct object_id *oid, const char *action,
625
632
UPDATE_REFS_MSG_ON_ERR );
626
633
}
627
634
635
+ leave_reset_head :
628
636
strbuf_release (& msg );
637
+ rollback_lock_file (& lock );
638
+ while (nr )
639
+ free ((void * )desc [-- nr ].buffer );
629
640
return ret ;
630
641
}
631
642
@@ -1003,7 +1014,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1003
1014
rerere_clear (& merge_rr );
1004
1015
string_list_clear (& merge_rr , 1 );
1005
1016
1006
- if (reset_head (NULL , "reset" , NULL , 0 , NULL , NULL ) < 0 )
1017
+ if (reset_head (NULL , "reset" , NULL , RESET_HEAD_HARD ,
1018
+ NULL , NULL ) < 0 )
1007
1019
die (_ ("could not discard worktree changes" ));
1008
1020
remove_branch_state ();
1009
1021
if (read_basic_state (& options ))
@@ -1020,7 +1032,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1020
1032
if (read_basic_state (& options ))
1021
1033
exit (1 );
1022
1034
if (reset_head (& options .orig_head , "reset" ,
1023
- options .head_name , 0 , NULL , NULL ) < 0 )
1035
+ options .head_name , RESET_HEAD_HARD ,
1036
+ NULL , NULL ) < 0 )
1024
1037
die (_ ("could not move back to %s" ),
1025
1038
oid_to_hex (& options .orig_head ));
1026
1039
remove_branch_state ();
@@ -1385,7 +1398,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1385
1398
write_file (autostash , "%s" , oid_to_hex (& oid ));
1386
1399
printf (_ ("Created autostash: %s\n" ), buf .buf );
1387
1400
if (reset_head (& head -> object .oid , "reset --hard" ,
1388
- NULL , 0 , NULL , NULL ) < 0 )
1401
+ NULL , RESET_HEAD_HARD , NULL , NULL ) < 0 )
1389
1402
die (_ ("could not reset --hard" ));
1390
1403
printf (_ ("HEAD is now at %s" ),
1391
1404
find_unique_abbrev (& head -> object .oid ,
@@ -1505,8 +1518,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1505
1518
"it...\n" ));
1506
1519
1507
1520
strbuf_addf (& msg , "rebase: checkout %s" , options .onto_name );
1508
- if (reset_head (& options .onto -> object .oid , "checkout" , NULL , 1 ,
1509
- NULL , msg .buf ))
1521
+ if (reset_head (& options .onto -> object .oid , "checkout" , NULL ,
1522
+ RESET_HEAD_DETACH , NULL , msg .buf ))
1510
1523
die (_ ("Could not detach HEAD" ));
1511
1524
strbuf_release (& msg );
1512
1525
0 commit comments