@@ -41,6 +41,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
4141static int option_local , option_no_hardlinks , option_shared ;
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
@@ -65,6 +66,8 @@ static struct option builtin_clone_options[] = {
6566 "reference repository" ),
6667 OPT_STRING ('o' , "origin" , & option_origin , "branch" ,
6768 "use <branch> instead of 'origin' to track upstream" ),
69+ OPT_STRING ('b' , "branch" , & option_branch , "branch" ,
70+ "checkout <branch> instead of the remote's HEAD" ),
6871 OPT_STRING ('u' , "upload-pack" , & option_upload_pack , "path" ,
6972 "path to git-upload-pack on the remote" ),
7073 OPT_STRING (0 , "depth" , & option_depth , "depth" ,
@@ -347,7 +350,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
347350 const char * repo_name , * repo , * work_tree , * git_dir ;
348351 char * path , * dir ;
349352 int dest_exists ;
350- const struct ref * refs , * head_points_at , * remote_head , * mapped_refs ;
353+ const struct ref * refs , * remote_head , * mapped_refs ;
354+ const struct ref * remote_head_points_at ;
355+ const struct ref * our_head_points_at ;
351356 struct strbuf key = STRBUF_INIT , value = STRBUF_INIT ;
352357 struct strbuf branch_top = STRBUF_INIT , reflog_msg = STRBUF_INIT ;
353358 struct transport * transport = NULL ;
@@ -519,53 +524,67 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
519524 mapped_refs = write_remote_refs (refs , refspec , reflog_msg .buf );
520525
521526 remote_head = find_ref_by_name (refs , "HEAD" );
522- head_points_at = guess_remote_head (remote_head , mapped_refs , 0 );
527+ remote_head_points_at =
528+ guess_remote_head (remote_head , mapped_refs , 0 );
529+
530+ if (option_branch ) {
531+ struct strbuf head = STRBUF_INIT ;
532+ strbuf_addstr (& head , src_ref_prefix );
533+ strbuf_addstr (& head , option_branch );
534+ our_head_points_at =
535+ find_ref_by_name (mapped_refs , head .buf );
536+ strbuf_release (& head );
537+
538+ if (!our_head_points_at ) {
539+ warning ("Remote branch %s not found in "
540+ "upstream %s, using HEAD instead" ,
541+ option_branch , option_origin );
542+ our_head_points_at = remote_head_points_at ;
543+ }
544+ }
545+ else
546+ our_head_points_at = remote_head_points_at ;
523547 }
524548 else {
525549 warning ("You appear to have cloned an empty repository." );
526- head_points_at = NULL ;
550+ our_head_points_at = NULL ;
551+ remote_head_points_at = NULL ;
527552 remote_head = NULL ;
528553 option_no_checkout = 1 ;
529554 if (!option_bare )
530555 install_branch_config (0 , "master" , option_origin ,
531556 "refs/heads/master" );
532557 }
533558
534- if (head_points_at ) {
535- /* Local default branch link */
536- create_symref ("HEAD" , head_points_at -> name , NULL );
559+ if (remote_head_points_at && !option_bare ) {
560+ struct strbuf head_ref = STRBUF_INIT ;
561+ strbuf_addstr (& head_ref , branch_top .buf );
562+ strbuf_addstr (& head_ref , "HEAD" );
563+ create_symref (head_ref .buf ,
564+ remote_head_points_at -> peer_ref -> name ,
565+ reflog_msg .buf );
566+ }
537567
568+ if (our_head_points_at ) {
569+ /* Local default branch link */
570+ create_symref ("HEAD" , our_head_points_at -> name , NULL );
538571 if (!option_bare ) {
539- struct strbuf head_ref = STRBUF_INIT ;
540- const char * head = head_points_at -> name ;
541-
542- if (!prefixcmp (head , "refs/heads/" ))
543- head += 11 ;
544-
545- /* Set up the initial local branch */
546-
547- /* Local branch initial value */
572+ const char * head = skip_prefix (our_head_points_at -> name ,
573+ "refs/heads/" );
548574 update_ref (reflog_msg .buf , "HEAD" ,
549- head_points_at -> old_sha1 ,
575+ our_head_points_at -> old_sha1 ,
550576 NULL , 0 , DIE_ON_ERR );
551-
552- strbuf_addstr (& head_ref , branch_top .buf );
553- strbuf_addstr (& head_ref , "HEAD" );
554-
555- /* Remote branch link */
556- create_symref (head_ref .buf ,
557- head_points_at -> peer_ref -> name ,
558- reflog_msg .buf );
559-
560577 install_branch_config (0 , head , option_origin ,
561- head_points_at -> name );
578+ our_head_points_at -> name );
562579 }
563580 } else if (remote_head ) {
564581 /* Source had detached HEAD pointing somewhere. */
565- if (!option_bare )
582+ if (!option_bare ) {
566583 update_ref (reflog_msg .buf , "HEAD" ,
567584 remote_head -> old_sha1 ,
568585 NULL , REF_NODEREF , DIE_ON_ERR );
586+ our_head_points_at = remote_head ;
587+ }
569588 } else {
570589 /* Nothing to checkout out */
571590 if (!option_no_checkout )
@@ -597,7 +616,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
597616 opts .src_index = & the_index ;
598617 opts .dst_index = & the_index ;
599618
600- tree = parse_tree_indirect (remote_head -> old_sha1 );
619+ tree = parse_tree_indirect (our_head_points_at -> old_sha1 );
601620 parse_tree (tree );
602621 init_tree_desc (& t , tree -> buffer , tree -> size );
603622 unpack_trees (1 , & t , & opts );
0 commit comments