@@ -88,6 +88,19 @@ struct checkout_opts {
8888 struct tree * source_tree ;
8989};
9090
91+ struct branch_info {
92+ const char * name ; /* The short name used */
93+ const char * path ; /* The full name of a real branch */
94+ struct commit * commit ; /* The named commit */
95+ char * refname ; /* The full name of the ref being checked out. */
96+ struct object_id oid ; /* The object ID of the commit being checked out. */
97+ /*
98+ * if not null the branch is detached because it's already
99+ * checked out in this checkout
100+ */
101+ char * checkout ;
102+ };
103+
91104static int post_checkout_hook (struct commit * old_commit , struct commit * new_commit ,
92105 int changed )
93106{
@@ -337,7 +350,8 @@ static void mark_ce_for_checkout_no_overlay(struct cache_entry *ce,
337350 }
338351}
339352
340- static int checkout_worktree (const struct checkout_opts * opts )
353+ static int checkout_worktree (const struct checkout_opts * opts ,
354+ const struct branch_info * info )
341355{
342356 struct checkout state = CHECKOUT_INIT ;
343357 int nr_checkouts = 0 , nr_unmerged = 0 ;
@@ -348,6 +362,10 @@ static int checkout_worktree(const struct checkout_opts *opts)
348362 state .refresh_cache = 1 ;
349363 state .istate = & the_index ;
350364
365+ init_checkout_metadata (& state .meta , info -> refname ,
366+ info -> commit ? & info -> commit -> object .oid : & info -> oid ,
367+ NULL );
368+
351369 enable_delayed_checkout (& state );
352370 for (pos = 0 ; pos < active_nr ; pos ++ ) {
353371 struct cache_entry * ce = active_cache [pos ];
@@ -396,7 +414,7 @@ static int checkout_worktree(const struct checkout_opts *opts)
396414}
397415
398416static int checkout_paths (const struct checkout_opts * opts ,
399- const char * revision )
417+ const struct branch_info * new_branch_info )
400418{
401419 int pos ;
402420 static char * ps_matched ;
@@ -462,7 +480,7 @@ static int checkout_paths(const struct checkout_opts *opts,
462480 else
463481 BUG ("either flag must have been set, worktree=%d, index=%d" ,
464482 opts -> checkout_worktree , opts -> checkout_index );
465- return run_add_interactive (revision , patch_mode , & opts -> pathspec );
483+ return run_add_interactive (new_branch_info -> name , patch_mode , & opts -> pathspec );
466484 }
467485
468486 repo_hold_locked_index (the_repository , & lock_file , LOCK_DIE_ON_ERROR );
@@ -523,7 +541,7 @@ static int checkout_paths(const struct checkout_opts *opts,
523541
524542 /* Now we are committed to check them out */
525543 if (opts -> checkout_worktree )
526- errs |= checkout_worktree (opts );
544+ errs |= checkout_worktree (opts , new_branch_info );
527545 else
528546 remove_marked_cache_entries (& the_index , 1 );
529547
@@ -586,7 +604,8 @@ static void describe_detached_head(const char *msg, struct commit *commit)
586604}
587605
588606static int reset_tree (struct tree * tree , const struct checkout_opts * o ,
589- int worktree , int * writeout_error )
607+ int worktree , int * writeout_error ,
608+ struct branch_info * info )
590609{
591610 struct unpack_trees_options opts ;
592611 struct tree_desc tree_desc ;
@@ -601,6 +620,11 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
601620 opts .verbose_update = o -> show_progress ;
602621 opts .src_index = & the_index ;
603622 opts .dst_index = & the_index ;
623+ init_checkout_metadata (& opts .meta , info -> refname ,
624+ info -> commit ? & info -> commit -> object .oid :
625+ is_null_oid (& info -> oid ) ? & tree -> object .oid :
626+ & info -> oid ,
627+ NULL );
604628 parse_tree (tree );
605629 init_tree_desc (& tree_desc , tree -> buffer , tree -> size );
606630 switch (unpack_trees (1 , & tree_desc , & opts )) {
@@ -620,21 +644,17 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
620644 }
621645}
622646
623- struct branch_info {
624- const char * name ; /* The short name used */
625- const char * path ; /* The full name of a real branch */
626- struct commit * commit ; /* The named commit */
627- /*
628- * if not null the branch is detached because it's already
629- * checked out in this checkout
630- */
631- char * checkout ;
632- };
633-
634647static void setup_branch_path (struct branch_info * branch )
635648{
636649 struct strbuf buf = STRBUF_INIT ;
637650
651+ /*
652+ * If this is a ref, resolve it; otherwise, look up the OID for our
653+ * expression. Failure here is okay.
654+ */
655+ if (!dwim_ref (branch -> name , strlen (branch -> name ), & branch -> oid , & branch -> refname ))
656+ repo_get_oid_committish (the_repository , branch -> name , & branch -> oid );
657+
638658 strbuf_branchname (& buf , branch -> name , INTERPRET_BRANCH_LOCAL );
639659 if (strcmp (buf .buf , branch -> name ))
640660 branch -> name = xstrdup (buf .buf );
@@ -663,7 +683,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
663683 } else
664684 new_tree = get_commit_tree (new_branch_info -> commit );
665685 if (opts -> discard_changes ) {
666- ret = reset_tree (new_tree , opts , 1 , writeout_error );
686+ ret = reset_tree (new_tree , opts , 1 , writeout_error , new_branch_info );
667687 if (ret )
668688 return ret ;
669689 } else {
@@ -692,6 +712,10 @@ static int merge_working_tree(const struct checkout_opts *opts,
692712 topts .quiet = opts -> merge && old_branch_info -> commit ;
693713 topts .verbose_update = opts -> show_progress ;
694714 topts .fn = twoway_merge ;
715+ init_checkout_metadata (& topts .meta , new_branch_info -> refname ,
716+ new_branch_info -> commit ?
717+ & new_branch_info -> commit -> object .oid :
718+ & new_branch_info -> oid , NULL );
695719 if (opts -> overwrite_ignore ) {
696720 topts .dir = xcalloc (1 , sizeof (* topts .dir ));
697721 topts .dir -> flags |= DIR_SHOW_IGNORED ;
@@ -762,7 +786,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
762786
763787 ret = reset_tree (new_tree ,
764788 opts , 1 ,
765- writeout_error );
789+ writeout_error , new_branch_info );
766790 if (ret )
767791 return ret ;
768792 o .ancestor = old_branch_info -> name ;
@@ -782,7 +806,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
782806 exit (128 );
783807 ret = reset_tree (new_tree ,
784808 opts , 0 ,
785- writeout_error );
809+ writeout_error , new_branch_info );
786810 strbuf_release (& o .obuf );
787811 strbuf_release (& old_commit_shortname );
788812 if (ret )
@@ -1710,7 +1734,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
17101734
17111735 UNLEAK (opts );
17121736 if (opts -> patch_mode || opts -> pathspec .nr )
1713- return checkout_paths (opts , new_branch_info . name );
1737+ return checkout_paths (opts , & new_branch_info );
17141738 else
17151739 return checkout_branch (opts , & new_branch_info );
17161740}
0 commit comments