@@ -41,6 +41,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
4141static int option_local , option_no_hardlinks , option_shared , option_recursive ;
4242static char * option_template , * option_reference , * option_depth ;
4343static char * option_origin = NULL ;
44+ static char * option_branch = NULL ;
4445static char * option_upload_pack = "git-upload-pack" ;
4546static int option_verbose ;
4647
@@ -67,6 +68,8 @@ static struct option builtin_clone_options[] = {
6768 "reference repository" ),
6869 OPT_STRING ('o' , "origin" , & option_origin , "branch" ,
6970 "use <branch> instead of 'origin' to track upstream" ),
71+ OPT_STRING ('b' , "branch" , & option_branch , "branch" ,
72+ "checkout <branch> instead of the remote's HEAD" ),
7073 OPT_STRING ('u' , "upload-pack" , & option_upload_pack , "path" ,
7174 "path to git-upload-pack on the remote" ),
7275 OPT_STRING (0 , "depth" , & option_depth , "depth" ,
@@ -353,7 +356,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
353356 const char * repo_name , * repo , * work_tree , * git_dir ;
354357 char * path , * dir ;
355358 int dest_exists ;
356- const struct ref * refs , * head_points_at , * remote_head , * mapped_refs ;
359+ const struct ref * refs , * remote_head , * mapped_refs ;
360+ const struct ref * remote_head_points_at ;
361+ const struct ref * our_head_points_at ;
357362 struct strbuf key = STRBUF_INIT , value = STRBUF_INIT ;
358363 struct strbuf branch_top = STRBUF_INIT , reflog_msg = STRBUF_INIT ;
359364 struct transport * transport = NULL ;
@@ -525,53 +530,67 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
525530 mapped_refs = write_remote_refs (refs , refspec , reflog_msg .buf );
526531
527532 remote_head = find_ref_by_name (refs , "HEAD" );
528- head_points_at = guess_remote_head (remote_head , mapped_refs , 0 );
533+ remote_head_points_at =
534+ guess_remote_head (remote_head , mapped_refs , 0 );
535+
536+ if (option_branch ) {
537+ struct strbuf head = STRBUF_INIT ;
538+ strbuf_addstr (& head , src_ref_prefix );
539+ strbuf_addstr (& head , option_branch );
540+ our_head_points_at =
541+ find_ref_by_name (mapped_refs , head .buf );
542+ strbuf_release (& head );
543+
544+ if (!our_head_points_at ) {
545+ warning ("Remote branch %s not found in "
546+ "upstream %s, using HEAD instead" ,
547+ option_branch , option_origin );
548+ our_head_points_at = remote_head_points_at ;
549+ }
550+ }
551+ else
552+ our_head_points_at = remote_head_points_at ;
529553 }
530554 else {
531555 warning ("You appear to have cloned an empty repository." );
532- head_points_at = NULL ;
556+ our_head_points_at = NULL ;
557+ remote_head_points_at = NULL ;
533558 remote_head = NULL ;
534559 option_no_checkout = 1 ;
535560 if (!option_bare )
536561 install_branch_config (0 , "master" , option_origin ,
537562 "refs/heads/master" );
538563 }
539564
540- if (head_points_at ) {
541- /* Local default branch link */
542- create_symref ("HEAD" , head_points_at -> name , NULL );
565+ if (remote_head_points_at && !option_bare ) {
566+ struct strbuf head_ref = STRBUF_INIT ;
567+ strbuf_addstr (& head_ref , branch_top .buf );
568+ strbuf_addstr (& head_ref , "HEAD" );
569+ create_symref (head_ref .buf ,
570+ remote_head_points_at -> peer_ref -> name ,
571+ reflog_msg .buf );
572+ }
543573
574+ if (our_head_points_at ) {
575+ /* Local default branch link */
576+ create_symref ("HEAD" , our_head_points_at -> name , NULL );
544577 if (!option_bare ) {
545- struct strbuf head_ref = STRBUF_INIT ;
546- const char * head = head_points_at -> name ;
547-
548- if (!prefixcmp (head , "refs/heads/" ))
549- head += 11 ;
550-
551- /* Set up the initial local branch */
552-
553- /* Local branch initial value */
578+ const char * head = skip_prefix (our_head_points_at -> name ,
579+ "refs/heads/" );
554580 update_ref (reflog_msg .buf , "HEAD" ,
555- head_points_at -> old_sha1 ,
581+ our_head_points_at -> old_sha1 ,
556582 NULL , 0 , DIE_ON_ERR );
557-
558- strbuf_addstr (& head_ref , branch_top .buf );
559- strbuf_addstr (& head_ref , "HEAD" );
560-
561- /* Remote branch link */
562- create_symref (head_ref .buf ,
563- head_points_at -> peer_ref -> name ,
564- reflog_msg .buf );
565-
566583 install_branch_config (0 , head , option_origin ,
567- head_points_at -> name );
584+ our_head_points_at -> name );
568585 }
569586 } else if (remote_head ) {
570587 /* Source had detached HEAD pointing somewhere. */
571- if (!option_bare )
588+ if (!option_bare ) {
572589 update_ref (reflog_msg .buf , "HEAD" ,
573590 remote_head -> old_sha1 ,
574591 NULL , REF_NODEREF , DIE_ON_ERR );
592+ our_head_points_at = remote_head ;
593+ }
575594 } else {
576595 /* Nothing to checkout out */
577596 if (!option_no_checkout )
@@ -605,7 +624,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
605624 opts .src_index = & the_index ;
606625 opts .dst_index = & the_index ;
607626
608- tree = parse_tree_indirect (remote_head -> old_sha1 );
627+ tree = parse_tree_indirect (our_head_points_at -> old_sha1 );
609628 parse_tree (tree );
610629 init_tree_desc (& t , tree -> buffer , tree -> size );
611630 unpack_trees (1 , & t , & opts );
0 commit comments