builtin/clone: skip reading HEAD when retrieving remote

After we have set up the remote configuration in git-clone(1) we'll call `remote_get()` to read the remote from the on-disk configuration. But next to reading the on-disk configuration, `remote_get()` will also cause us to try and read the repository's HEAD reference so that we can figure out the current branch. Besides being pointless in git-clone(1) because we're operating in an empty repository anyway, this will also break once we move creation of the reference database to a later point in time. Refactor the code to introduce a new `remote_get_early()` function that will skip reading the HEAD reference to address this issue. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Dec 12, 2023 at 08:01 UTC 3c8f60c6416bdfcc690ff5d56d80350a89ed92b5
3 files changed +18 -11
builtin/clone.c
+1 -1
@@ -1185,7 +1185,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1185 if (option_required_reference.nr || option_optional_reference.nr)
1186 setup_reference();
1187
1188 - remote = remote_get(remote_name);
1188 + remote = remote_get_early(remote_name);
1189
1190 refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix,
1191 branch_top.buf);
remote.c
+16 -10
@@ -509,7 +509,7 @@ static void alias_all_urls(struct remote_state *remote_state)
509 }
510 }
511
512 -static void read_config(struct repository *repo)
512 +static void read_config(struct repository *repo, int early)
513 {
514 int flag;
515
@@ -518,7 +518,7 @@ static void read_config(struct repository *repo)
518 repo->remote_state->initialized = 1;
519
520 repo->remote_state->current_branch = NULL;
521 - if (startup_info->have_repository) {
521 + if (startup_info->have_repository && !early) {
522 const char *head_ref = refs_resolve_ref_unsafe(
523 get_main_ref_store(repo), "HEAD", 0, NULL, &flag);
524 if (head_ref && (flag & REF_ISSYMREF) &&
@@ -561,7 +561,7 @@ static const char *remotes_remote_for_branch(struct remote_state *remote_state,
561
562 const char *remote_for_branch(struct branch *branch, int *explicit)
563 {
564 - read_config(the_repository);
564 + read_config(the_repository, 0);
565 die_on_missing_branch(the_repository, branch);
566
567 return remotes_remote_for_branch(the_repository->remote_state, branch,
@@ -587,7 +587,7 @@ remotes_pushremote_for_branch(struct remote_state *remote_state,
587
588 const char *pushremote_for_branch(struct branch *branch, int *explicit)
589 {
590 - read_config(the_repository);
590 + read_config(the_repository, 0);
591 die_on_missing_branch(the_repository, branch);
592
593 return remotes_pushremote_for_branch(the_repository->remote_state,
@@ -599,7 +599,7 @@ static struct remote *remotes_remote_get(struct remote_state *remote_state,
599
600 const char *remote_ref_for_branch(struct branch *branch, int for_push)
601 {
602 - read_config(the_repository);
602 + read_config(the_repository, 0);
603 die_on_missing_branch(the_repository, branch);
604
605 if (branch) {
@@ -709,7 +709,13 @@ remotes_remote_get(struct remote_state *remote_state, const char *name)
709
710 struct remote *remote_get(const char *name)
711 {
712 - read_config(the_repository);
712 + read_config(the_repository, 0);
713 + return remotes_remote_get(the_repository->remote_state, name);
714 +}
715 +
716 +struct remote *remote_get_early(const char *name)
717 +{
718 + read_config(the_repository, 1);
719 return remotes_remote_get(the_repository->remote_state, name);
720 }
721
@@ -722,7 +728,7 @@ remotes_pushremote_get(struct remote_state *remote_state, const char *name)
728
729 struct remote *pushremote_get(const char *name)
730 {
725 - read_config(the_repository);
731 + read_config(the_repository, 0);
732 return remotes_pushremote_get(the_repository->remote_state, name);
733 }
734
@@ -738,7 +744,7 @@ int remote_is_configured(struct remote *remote, int in_repo)
744 int for_each_remote(each_remote_fn fn, void *priv)
745 {
746 int i, result = 0;
741 - read_config(the_repository);
747 + read_config(the_repository, 0);
748 for (i = 0; i < the_repository->remote_state->remotes_nr && !result;
749 i++) {
750 struct remote *remote =
@@ -1831,7 +1837,7 @@ struct branch *branch_get(const char *name)
1837 {
1838 struct branch *ret;
1839
1834 - read_config(the_repository);
1840 + read_config(the_repository, 0);
1841 if (!name || !*name || !strcmp(name, "HEAD"))
1842 ret = the_repository->remote_state->current_branch;
1843 else
@@ -1973,7 +1979,7 @@ static const char *branch_get_push_1(struct remote_state *remote_state,
1979
1980 const char *branch_get_push(struct branch *branch, struct strbuf *err)
1981 {
1976 - read_config(the_repository);
1982 + read_config(the_repository, 0);
1983 die_on_missing_branch(the_repository, branch);
1984
1985 if (!branch)
remote.h
+1
@@ -118,6 +118,7 @@ struct remote {
118 * and configuration.
119 */
120 struct remote *remote_get(const char *name);
121 +struct remote *remote_get_early(const char *name);
122
123 struct remote *pushremote_get(const char *name);
124 int remote_is_configured(struct remote *remote, int in_repo);