@@ -37,7 +37,7 @@ static const char * const builtin_clone_usage[] = {
3737 NULL
3838};
3939
40- static int option_no_checkout , option_bare , option_mirror ;
40+ static int option_no_checkout , option_bare , option_mirror , option_single_branch = -1 ;
4141static int option_local , option_no_hardlinks , option_shared , option_recursive ;
4242static char * option_template , * option_depth ;
4343static char * option_origin = NULL ;
@@ -48,6 +48,7 @@ static int option_verbosity;
4848static int option_progress ;
4949static struct string_list option_config ;
5050static struct string_list option_reference ;
51+ static const char * src_ref_prefix = "refs/heads/" ;
5152
5253static int opt_parse_reference (const struct option * opt , const char * arg , int unset )
5354{
@@ -92,6 +93,8 @@ static struct option builtin_clone_options[] = {
9293 "path to git-upload-pack on the remote" ),
9394 OPT_STRING (0 , "depth" , & option_depth , "depth" ,
9495 "create a shallow clone of that depth" ),
96+ OPT_BOOL (0 , "single-branch" , & option_single_branch ,
97+ "clone only one branch, HEAD or --branch" ),
9598 OPT_STRING (0 , "separate-git-dir" , & real_git_dir , "gitdir" ,
9699 "separate git dir from working tree" ),
97100 OPT_STRING_LIST ('c' , "config" , & option_config , "key=value" ,
@@ -427,8 +430,28 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
427430 struct ref * local_refs = head ;
428431 struct ref * * tail = head ? & head -> next : & local_refs ;
429432
430- get_fetch_map (refs , refspec , & tail , 0 );
431- if (!option_mirror )
433+ if (option_single_branch ) {
434+ struct ref * remote_head = NULL ;
435+
436+ if (!option_branch )
437+ remote_head = guess_remote_head (head , refs , 0 );
438+ else {
439+ struct strbuf sb = STRBUF_INIT ;
440+ strbuf_addstr (& sb , src_ref_prefix );
441+ strbuf_addstr (& sb , option_branch );
442+ remote_head = find_ref_by_name (refs , sb .buf );
443+ strbuf_release (& sb );
444+ }
445+
446+ if (!remote_head && option_branch )
447+ warning (_ ("Could not find remote branch %s to clone." ),
448+ option_branch );
449+ else
450+ get_fetch_map (remote_head , refspec , & tail , 0 );
451+ } else
452+ get_fetch_map (refs , refspec , & tail , 0 );
453+
454+ if (!option_mirror && !option_single_branch )
432455 get_fetch_map (refs , tag_refspec , & tail , 0 );
433456
434457 return local_refs ;
@@ -448,6 +471,21 @@ static void write_remote_refs(const struct ref *local_refs)
448471 clear_extra_refs ();
449472}
450473
474+ static void write_followtags (const struct ref * refs , const char * msg )
475+ {
476+ const struct ref * ref ;
477+ for (ref = refs ; ref ; ref = ref -> next ) {
478+ if (prefixcmp (ref -> name , "refs/tags/" ))
479+ continue ;
480+ if (!suffixcmp (ref -> name , "^{}" ))
481+ continue ;
482+ if (!has_sha1_file (ref -> old_sha1 ))
483+ continue ;
484+ update_ref (msg , ref -> name , ref -> old_sha1 ,
485+ NULL , 0 , DIE_ON_ERR );
486+ }
487+ }
488+
451489static int write_one_config (const char * key , const char * value , void * data )
452490{
453491 return git_config_set_multivar (key , value ? value : "true" , "^$" , 0 );
@@ -478,7 +516,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
478516 struct strbuf key = STRBUF_INIT , value = STRBUF_INIT ;
479517 struct strbuf branch_top = STRBUF_INIT , reflog_msg = STRBUF_INIT ;
480518 struct transport * transport = NULL ;
481- char * src_ref_prefix = "refs/heads/" ;
482519 int err = 0 ;
483520
484521 struct refspec * refspec ;
@@ -498,6 +535,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
498535 usage_msg_opt (_ ("You must specify a repository to clone." ),
499536 builtin_clone_usage , builtin_clone_options );
500537
538+ if (option_single_branch == -1 )
539+ option_single_branch = option_depth ? 1 : 0 ;
540+
501541 if (option_mirror )
502542 option_bare = 1 ;
503543
@@ -645,6 +685,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
645685 if (option_depth )
646686 transport_set_option (transport , TRANS_OPT_DEPTH ,
647687 option_depth );
688+ if (option_single_branch )
689+ transport_set_option (transport , TRANS_OPT_FOLLOWTAGS , "1" );
648690
649691 transport_set_verbosity (transport , option_verbosity , option_progress );
650692
@@ -663,6 +705,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
663705 clear_extra_refs ();
664706
665707 write_remote_refs (mapped_refs );
708+ if (option_single_branch )
709+ write_followtags (refs , reflog_msg .buf );
666710
667711 remote_head = find_ref_by_name (refs , "HEAD" );
668712 remote_head_points_at =
0 commit comments