@@ -333,6 +333,125 @@ static void add_var(struct strbuf *buf, const char *name, const char *value)
333333 }
334334}
335335
336+ #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
337+
338+ #define RESET_HEAD_DETACH (1<<0)
339+ #define RESET_HEAD_HARD (1<<1)
340+
341+ static int reset_head (struct object_id * oid , const char * action ,
342+ const char * switch_to_branch , unsigned flags ,
343+ const char * reflog_orig_head , const char * reflog_head )
344+ {
345+ unsigned detach_head = flags & RESET_HEAD_DETACH ;
346+ unsigned reset_hard = flags & RESET_HEAD_HARD ;
347+ struct object_id head_oid ;
348+ struct tree_desc desc [2 ] = { { NULL }, { NULL } };
349+ struct lock_file lock = LOCK_INIT ;
350+ struct unpack_trees_options unpack_tree_opts ;
351+ struct tree * tree ;
352+ const char * reflog_action ;
353+ struct strbuf msg = STRBUF_INIT ;
354+ size_t prefix_len ;
355+ struct object_id * orig = NULL , oid_orig ,
356+ * old_orig = NULL , oid_old_orig ;
357+ int ret = 0 , nr = 0 ;
358+
359+ if (switch_to_branch && !starts_with (switch_to_branch , "refs/" ))
360+ BUG ("Not a fully qualified branch: '%s'" , switch_to_branch );
361+
362+ if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 ) {
363+ ret = -1 ;
364+ goto leave_reset_head ;
365+ }
366+
367+ if ((!oid || !reset_hard ) && get_oid ("HEAD" , & head_oid )) {
368+ ret = error (_ ("could not determine HEAD revision" ));
369+ goto leave_reset_head ;
370+ }
371+
372+ if (!oid )
373+ oid = & head_oid ;
374+
375+ memset (& unpack_tree_opts , 0 , sizeof (unpack_tree_opts ));
376+ setup_unpack_trees_porcelain (& unpack_tree_opts , action );
377+ unpack_tree_opts .head_idx = 1 ;
378+ unpack_tree_opts .src_index = the_repository -> index ;
379+ unpack_tree_opts .dst_index = the_repository -> index ;
380+ unpack_tree_opts .fn = reset_hard ? oneway_merge : twoway_merge ;
381+ unpack_tree_opts .update = 1 ;
382+ unpack_tree_opts .merge = 1 ;
383+ if (!detach_head )
384+ unpack_tree_opts .reset = 1 ;
385+
386+ if (read_index_unmerged (the_repository -> index ) < 0 ) {
387+ ret = error (_ ("could not read index" ));
388+ goto leave_reset_head ;
389+ }
390+
391+ if (!reset_hard && !fill_tree_descriptor (& desc [nr ++ ], & head_oid )) {
392+ ret = error (_ ("failed to find tree of %s" ),
393+ oid_to_hex (& head_oid ));
394+ goto leave_reset_head ;
395+ }
396+
397+ if (!fill_tree_descriptor (& desc [nr ++ ], oid )) {
398+ ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
399+ goto leave_reset_head ;
400+ }
401+
402+ if (unpack_trees (nr , desc , & unpack_tree_opts )) {
403+ ret = -1 ;
404+ goto leave_reset_head ;
405+ }
406+
407+ tree = parse_tree_indirect (oid );
408+ prime_cache_tree (the_repository -> index , tree );
409+
410+ if (write_locked_index (the_repository -> index , & lock , COMMIT_LOCK ) < 0 ) {
411+ ret = error (_ ("could not write index" ));
412+ goto leave_reset_head ;
413+ }
414+
415+ reflog_action = getenv (GIT_REFLOG_ACTION_ENVIRONMENT );
416+ strbuf_addf (& msg , "%s: " , reflog_action ? reflog_action : "rebase" );
417+ prefix_len = msg .len ;
418+
419+ if (!get_oid ("ORIG_HEAD" , & oid_old_orig ))
420+ old_orig = & oid_old_orig ;
421+ if (!get_oid ("HEAD" , & oid_orig )) {
422+ orig = & oid_orig ;
423+ if (!reflog_orig_head ) {
424+ strbuf_addstr (& msg , "updating ORIG_HEAD" );
425+ reflog_orig_head = msg .buf ;
426+ }
427+ update_ref (reflog_orig_head , "ORIG_HEAD" , orig , old_orig , 0 ,
428+ UPDATE_REFS_MSG_ON_ERR );
429+ } else if (old_orig )
430+ delete_ref (NULL , "ORIG_HEAD" , old_orig , 0 );
431+ if (!reflog_head ) {
432+ strbuf_setlen (& msg , prefix_len );
433+ strbuf_addstr (& msg , "updating HEAD" );
434+ reflog_head = msg .buf ;
435+ }
436+ if (!switch_to_branch )
437+ ret = update_ref (reflog_head , "HEAD" , oid , orig ,
438+ detach_head ? REF_NO_DEREF : 0 ,
439+ UPDATE_REFS_MSG_ON_ERR );
440+ else {
441+ ret = create_symref ("HEAD" , switch_to_branch , msg .buf );
442+ if (!ret )
443+ ret = update_ref (reflog_head , "HEAD" , oid , NULL , 0 ,
444+ UPDATE_REFS_MSG_ON_ERR );
445+ }
446+
447+ leave_reset_head :
448+ strbuf_release (& msg );
449+ rollback_lock_file (& lock );
450+ while (nr )
451+ free ((void * )desc [-- nr ].buffer );
452+ return ret ;
453+ }
454+
336455static const char * resolvemsg =
337456N_ ("Resolve all conflicts manually, mark them as resolved with\n"
338457"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -526,125 +645,6 @@ static int run_specific_rebase(struct rebase_options *opts)
526645 return status ? -1 : 0 ;
527646}
528647
529- #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
530-
531- #define RESET_HEAD_DETACH (1<<0)
532- #define RESET_HEAD_HARD (1<<1)
533-
534- static int reset_head (struct object_id * oid , const char * action ,
535- const char * switch_to_branch , unsigned flags ,
536- const char * reflog_orig_head , const char * reflog_head )
537- {
538- unsigned detach_head = flags & RESET_HEAD_DETACH ;
539- unsigned reset_hard = flags & RESET_HEAD_HARD ;
540- struct object_id head_oid ;
541- struct tree_desc desc [2 ] = { { NULL }, { NULL } };
542- struct lock_file lock = LOCK_INIT ;
543- struct unpack_trees_options unpack_tree_opts ;
544- struct tree * tree ;
545- const char * reflog_action ;
546- struct strbuf msg = STRBUF_INIT ;
547- size_t prefix_len ;
548- struct object_id * orig = NULL , oid_orig ,
549- * old_orig = NULL , oid_old_orig ;
550- int ret = 0 , nr = 0 ;
551-
552- if (switch_to_branch && !starts_with (switch_to_branch , "refs/" ))
553- BUG ("Not a fully qualified branch: '%s'" , switch_to_branch );
554-
555- if (hold_locked_index (& lock , LOCK_REPORT_ON_ERROR ) < 0 ) {
556- ret = -1 ;
557- goto leave_reset_head ;
558- }
559-
560- if ((!oid || !reset_hard ) && get_oid ("HEAD" , & head_oid )) {
561- ret = error (_ ("could not determine HEAD revision" ));
562- goto leave_reset_head ;
563- }
564-
565- if (!oid )
566- oid = & head_oid ;
567-
568- memset (& unpack_tree_opts , 0 , sizeof (unpack_tree_opts ));
569- setup_unpack_trees_porcelain (& unpack_tree_opts , action );
570- unpack_tree_opts .head_idx = 1 ;
571- unpack_tree_opts .src_index = the_repository -> index ;
572- unpack_tree_opts .dst_index = the_repository -> index ;
573- unpack_tree_opts .fn = reset_hard ? oneway_merge : twoway_merge ;
574- unpack_tree_opts .update = 1 ;
575- unpack_tree_opts .merge = 1 ;
576- if (!detach_head )
577- unpack_tree_opts .reset = 1 ;
578-
579- if (read_index_unmerged (the_repository -> index ) < 0 ) {
580- ret = error (_ ("could not read index" ));
581- goto leave_reset_head ;
582- }
583-
584- if (!reset_hard && !fill_tree_descriptor (& desc [nr ++ ], & head_oid )) {
585- ret = error (_ ("failed to find tree of %s" ),
586- oid_to_hex (& head_oid ));
587- goto leave_reset_head ;
588- }
589-
590- if (!fill_tree_descriptor (& desc [nr ++ ], oid )) {
591- ret = error (_ ("failed to find tree of %s" ), oid_to_hex (oid ));
592- goto leave_reset_head ;
593- }
594-
595- if (unpack_trees (nr , desc , & unpack_tree_opts )) {
596- ret = -1 ;
597- goto leave_reset_head ;
598- }
599-
600- tree = parse_tree_indirect (oid );
601- prime_cache_tree (the_repository -> index , tree );
602-
603- if (write_locked_index (the_repository -> index , & lock , COMMIT_LOCK ) < 0 ) {
604- ret = error (_ ("could not write index" ));
605- goto leave_reset_head ;
606- }
607-
608- reflog_action = getenv (GIT_REFLOG_ACTION_ENVIRONMENT );
609- strbuf_addf (& msg , "%s: " , reflog_action ? reflog_action : "rebase" );
610- prefix_len = msg .len ;
611-
612- if (!get_oid ("ORIG_HEAD" , & oid_old_orig ))
613- old_orig = & oid_old_orig ;
614- if (!get_oid ("HEAD" , & oid_orig )) {
615- orig = & oid_orig ;
616- if (!reflog_orig_head ) {
617- strbuf_addstr (& msg , "updating ORIG_HEAD" );
618- reflog_orig_head = msg .buf ;
619- }
620- update_ref (reflog_orig_head , "ORIG_HEAD" , orig , old_orig , 0 ,
621- UPDATE_REFS_MSG_ON_ERR );
622- } else if (old_orig )
623- delete_ref (NULL , "ORIG_HEAD" , old_orig , 0 );
624- if (!reflog_head ) {
625- strbuf_setlen (& msg , prefix_len );
626- strbuf_addstr (& msg , "updating HEAD" );
627- reflog_head = msg .buf ;
628- }
629- if (!switch_to_branch )
630- ret = update_ref (reflog_head , "HEAD" , oid , orig ,
631- detach_head ? REF_NO_DEREF : 0 ,
632- UPDATE_REFS_MSG_ON_ERR );
633- else {
634- ret = create_symref ("HEAD" , switch_to_branch , msg .buf );
635- if (!ret )
636- ret = update_ref (reflog_head , "HEAD" , oid , NULL , 0 ,
637- UPDATE_REFS_MSG_ON_ERR );
638- }
639-
640- leave_reset_head :
641- strbuf_release (& msg );
642- rollback_lock_file (& lock );
643- while (nr )
644- free ((void * )desc [-- nr ].buffer );
645- return ret ;
646- }
647-
648648static int rebase_config (const char * var , const char * value , void * data )
649649{
650650 struct rebase_options * opts = data ;
0 commit comments