@@ -37,7 +37,7 @@ static const char * const builtin_clone_usage[] = {
37
37
NULL
38
38
};
39
39
40
- static int option_no_checkout , option_bare , option_mirror ;
40
+ static int option_no_checkout , option_bare , option_mirror , option_single_branch = -1 ;
41
41
static int option_local , option_no_hardlinks , option_shared , option_recursive ;
42
42
static char * option_template , * option_depth ;
43
43
static char * option_origin = NULL ;
@@ -48,6 +48,7 @@ static int option_verbosity;
48
48
static int option_progress ;
49
49
static struct string_list option_config ;
50
50
static struct string_list option_reference ;
51
+ static const char * src_ref_prefix = "refs/heads/" ;
51
52
52
53
static int opt_parse_reference (const struct option * opt , const char * arg , int unset )
53
54
{
@@ -92,6 +93,8 @@ static struct option builtin_clone_options[] = {
92
93
"path to git-upload-pack on the remote" ),
93
94
OPT_STRING (0 , "depth" , & option_depth , "depth" ,
94
95
"create a shallow clone of that depth" ),
96
+ OPT_BOOL (0 , "single-branch" , & option_single_branch ,
97
+ "clone only one branch, HEAD or --branch" ),
95
98
OPT_STRING (0 , "separate-git-dir" , & real_git_dir , "gitdir" ,
96
99
"separate git dir from working tree" ),
97
100
OPT_STRING_LIST ('c' , "config" , & option_config , "key=value" ,
@@ -427,8 +430,28 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
427
430
struct ref * local_refs = head ;
428
431
struct ref * * tail = head ? & head -> next : & local_refs ;
429
432
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 )
432
455
get_fetch_map (refs , tag_refspec , & tail , 0 );
433
456
434
457
return local_refs ;
@@ -448,6 +471,21 @@ static void write_remote_refs(const struct ref *local_refs)
448
471
clear_extra_refs ();
449
472
}
450
473
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
+
451
489
static int write_one_config (const char * key , const char * value , void * data )
452
490
{
453
491
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)
478
516
struct strbuf key = STRBUF_INIT , value = STRBUF_INIT ;
479
517
struct strbuf branch_top = STRBUF_INIT , reflog_msg = STRBUF_INIT ;
480
518
struct transport * transport = NULL ;
481
- char * src_ref_prefix = "refs/heads/" ;
482
519
int err = 0 ;
483
520
484
521
struct refspec * refspec ;
@@ -498,6 +535,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
498
535
usage_msg_opt (_ ("You must specify a repository to clone." ),
499
536
builtin_clone_usage , builtin_clone_options );
500
537
538
+ if (option_single_branch == -1 )
539
+ option_single_branch = option_depth ? 1 : 0 ;
540
+
501
541
if (option_mirror )
502
542
option_bare = 1 ;
503
543
@@ -645,6 +685,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
645
685
if (option_depth )
646
686
transport_set_option (transport , TRANS_OPT_DEPTH ,
647
687
option_depth );
688
+ if (option_single_branch )
689
+ transport_set_option (transport , TRANS_OPT_FOLLOWTAGS , "1" );
648
690
649
691
transport_set_verbosity (transport , option_verbosity , option_progress );
650
692
@@ -663,6 +705,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
663
705
clear_extra_refs ();
664
706
665
707
write_remote_refs (mapped_refs );
708
+ if (option_single_branch )
709
+ write_followtags (refs , reflog_msg .buf );
666
710
667
711
remote_head = find_ref_by_name (refs , "HEAD" );
668
712
remote_head_points_at =
0 commit comments