| 
57 | 57 |  *  | 
58 | 58 |  */  | 
59 | 59 | 
 
  | 
 | 60 | +struct clone_opts {  | 
 | 61 | +	int wants_head;  | 
 | 62 | +};  | 
 | 63 | +#define CLONE_OPTS_INIT { \  | 
 | 64 | +	.wants_head = 1 /* default enabled */ \  | 
 | 65 | +}  | 
 | 66 | + | 
60 | 67 | static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;  | 
61 | 68 | static int option_local = -1, option_no_hardlinks, option_shared;  | 
62 | 69 | static int option_tags = 1; /* default enabled */  | 
@@ -429,23 +436,24 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch  | 
429 | 436 | 	return ref;  | 
430 | 437 | }  | 
431 | 438 | 
 
  | 
432 |  | -static struct ref *wanted_peer_refs(const struct ref *refs,  | 
433 |  | -		struct refspec *refspec)  | 
 | 439 | +static struct ref *wanted_peer_refs(struct clone_opts *opts,  | 
 | 440 | +				    const struct ref *refs,  | 
 | 441 | +				    struct refspec *refspec)  | 
434 | 442 | {  | 
435 |  | -	struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));  | 
436 |  | -	struct ref *local_refs = head;  | 
437 |  | -	struct ref **tail = local_refs ? &local_refs->next : &local_refs;  | 
 | 443 | +	struct ref *local_refs = NULL;  | 
 | 444 | +	struct ref **tail = &local_refs;  | 
438 | 445 | 	struct ref *to_free = NULL;  | 
439 | 446 | 
 
  | 
440 |  | -	if (option_single_branch) {  | 
441 |  | -		if (!option_branch)  | 
 | 447 | +	if (opts->wants_head) {  | 
 | 448 | +		struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));  | 
 | 449 | +		if (head)  | 
 | 450 | +			tail_link_ref(head, &tail);  | 
 | 451 | +		if (option_single_branch)  | 
442 | 452 | 			refs = to_free = guess_remote_head(head, refs, 0);  | 
443 |  | -		else {  | 
444 |  | -			free_one_ref(head);  | 
445 |  | -			local_refs = head = NULL;  | 
446 |  | -			tail = &local_refs;  | 
447 |  | -			refs = to_free = copy_ref(find_remote_branch(refs, option_branch));  | 
448 |  | -		}  | 
 | 453 | +	} else if (option_single_branch) {  | 
 | 454 | +		local_refs = NULL;  | 
 | 455 | +		tail = &local_refs;  | 
 | 456 | +		refs = to_free = copy_ref(find_remote_branch(refs, option_branch));  | 
449 | 457 | 	}  | 
450 | 458 | 
 
  | 
451 | 459 | 	for (size_t i = 0; i < refspec->nr; i++)  | 
@@ -893,6 +901,8 @@ int cmd_clone(int argc,  | 
893 | 901 | 	struct string_list server_options = STRING_LIST_INIT_NODUP;  | 
894 | 902 | 	const char *bundle_uri = NULL;  | 
895 | 903 | 
 
  | 
 | 904 | +	struct clone_opts opts = CLONE_OPTS_INIT;  | 
 | 905 | + | 
896 | 906 | 	struct transport_ls_refs_options transport_ls_refs_options =  | 
897 | 907 | 		TRANSPORT_LS_REFS_OPTIONS_INIT;  | 
898 | 908 | 
 
  | 
@@ -1343,9 +1353,13 @@ int cmd_clone(int argc,  | 
1343 | 1353 | 	if (option_not.nr)  | 
1344 | 1354 | 		transport_set_option(transport, TRANS_OPT_DEEPEN_NOT,  | 
1345 | 1355 | 				     (const char *)&option_not);  | 
1346 |  | -	if (option_single_branch)  | 
 | 1356 | +	if (option_single_branch) {  | 
1347 | 1357 | 		transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");  | 
1348 | 1358 | 
 
  | 
 | 1359 | +		if (option_branch)  | 
 | 1360 | +			opts.wants_head = 0;  | 
 | 1361 | +	}  | 
 | 1362 | + | 
1349 | 1363 | 	if (option_upload_pack)  | 
1350 | 1364 | 		transport_set_option(transport, TRANS_OPT_UPLOADPACK,  | 
1351 | 1365 | 				     option_upload_pack);  | 
@@ -1454,7 +1468,7 @@ int cmd_clone(int argc,  | 
1454 | 1468 | 	}  | 
1455 | 1469 | 
 
  | 
1456 | 1470 | 	if (refs)  | 
1457 |  | -		mapped_refs = wanted_peer_refs(refs, &remote->fetch);  | 
 | 1471 | +		mapped_refs = wanted_peer_refs(&opts, refs, &remote->fetch);  | 
1458 | 1472 | 
 
  | 
1459 | 1473 | 	if (mapped_refs) {  | 
1460 | 1474 | 		/*  | 
 | 
0 commit comments