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