Git fork

clone: introduce struct clone_opts in builtin/clone.c

There is a lot of state stored in global variables in builtin/clone.c.
In the long run we'd like to remove many of those.

Introduce `struct clone_opts` in this file. This struct will be used to
contain all details needed to perform the clone. The struct object can
be thrown around to all the functions that need these details.

The first field we're adding is `wants_head`. In some scenarios
(specifically when both `--single-branch` and `--branch` are given) we
are not interested in `HEAD` on the remote. The field `wants_head` in
`struct clone_opts` will hold this information. We could have put
`option_branch` and `option_single_branch` into that struct instead, but
in a following commit we'll be using `wants_head` as well.

Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Toon Claes and committed by
Junio C Hamano
7a52a8c7 2ca67c6f

+35 -16
+29 -15
builtin/clone.c
··· 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 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++) ··· 892 900 int option_filter_submodules = -1; /* unspecified */ 893 901 struct string_list server_options = STRING_LIST_INIT_NODUP; 894 902 const char *bundle_uri = NULL; 903 + 904 + struct clone_opts opts = CLONE_OPTS_INIT; 895 905 896 906 struct transport_ls_refs_options transport_ls_refs_options = 897 907 TRANSPORT_LS_REFS_OPTIONS_INIT; ··· 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 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 /*
+1 -1
remote.c
··· 1234 1234 } 1235 1235 } 1236 1236 1237 - static void tail_link_ref(struct ref *ref, struct ref ***tail) 1237 + void tail_link_ref(struct ref *ref, struct ref ***tail) 1238 1238 { 1239 1239 **tail = ref; 1240 1240 while (ref->next)
+5
remote.h
··· 219 219 struct ref *copy_ref(const struct ref *ref); 220 220 struct ref *copy_ref_list(const struct ref *ref); 221 221 int count_refspec_match(const char *, struct ref *refs, struct ref **matched_ref); 222 + /* 223 + * Put a ref in the tail and prepare tail for adding another one. 224 + * *tail is the pointer to the tail of the list of refs. 225 + */ 226 + void tail_link_ref(struct ref *ref, struct ref ***tail); 222 227 223 228 int check_ref_type(const struct ref *ref, int flags); 224 229