git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jonathan Tan <jonathantanmy@google.com>
To: git@vger.kernel.org
Cc: Jonathan Tan <jonathantanmy@google.com>
Subject: [PATCH v3 3/3] clone: respect remote unborn HEAD
Date: Mon, 21 Dec 2020 14:31:01 -0800	[thread overview]
Message-ID: <c2303dc9761493decd7a21a7f1e89d6dd9c646e4.1608587839.git.jonathantanmy@google.com> (raw)
In-Reply-To: <cover.1608587839.git.jonathantanmy@google.com>

Teach Git to use the "unborn" feature introduced in a previous patch as
follows: Git will always send the "unborn" argument if it is supported
by the server. During "git clone", if cloning an empty repository, Git
will use the new information to determine the local branch to create. In
all other cases, Git will ignore it.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---
 Documentation/config/init.txt |  2 +-
 builtin/clone.c               | 19 ++++++++++++++++---
 connect.c                     | 28 ++++++++++++++++++++++++----
 t/t5606-clone-options.sh      |  7 ++++---
 t/t5702-protocol-v2.sh        |  9 +++++++++
 5 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index dc77f8c844..79c79d6617 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -4,4 +4,4 @@ init.templateDir::
 
 init.defaultBranch::
 	Allows overriding the default branch name e.g. when initializing
-	a new repository or when cloning an empty repository.
+	a new repository.
diff --git a/builtin/clone.c b/builtin/clone.c
index 70f9450db4..217c87fddf 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -980,6 +980,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	int submodule_progress;
 
 	struct strvec ref_prefixes = STRVEC_INIT;
+	char *unborn_head_target = NULL;
 
 	packet_trace_identity("clone");
 
@@ -1264,7 +1265,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (!option_no_tags)
 		strvec_push(&ref_prefixes, "refs/tags/");
 
-	refs = transport_get_remote_refs(transport, &ref_prefixes, NULL);
+	refs = transport_get_remote_refs(transport, &ref_prefixes,
+					 &unborn_head_target);
 
 	if (refs) {
 		int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
@@ -1323,10 +1325,20 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare) {
-			const char *branch = git_default_branch_name();
-			char *ref = xstrfmt("refs/heads/%s", branch);
+			const char *branch;
+			char *ref;
+
+			if (unborn_head_target &&
+			    skip_prefix(unborn_head_target, "refs/heads/", &branch)) {
+				ref = unborn_head_target;
+				unborn_head_target = NULL;
+			} else {
+				branch = git_default_branch_name();
+				ref = xstrfmt("refs/heads/%s", branch);
+			}
 
 			install_branch_config(0, branch, remote_name, ref);
+			create_symref("HEAD", ref, "");
 			free(ref);
 		}
 	}
@@ -1373,6 +1385,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	strbuf_release(&key);
 	junk_mode = JUNK_LEAVE_ALL;
 
+	free(unborn_head_target);
 	strvec_clear(&ref_prefixes);
 	return err;
 }
diff --git a/connect.c b/connect.c
index 99d9052365..3c35324b4c 100644
--- a/connect.c
+++ b/connect.c
@@ -376,7 +376,8 @@ struct ref **get_remote_heads(struct packet_reader *reader,
 }
 
 /* Returns 1 when a valid ref has been added to `list`, 0 otherwise */
-static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
+static int process_ref_v2(struct packet_reader *reader, struct ref ***list,
+			  char **unborn_head_target)
 {
 	int ret = 1;
 	int i = 0;
@@ -397,6 +398,25 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
 		goto out;
 	}
 
+	if (!strcmp("unborn", line_sections.items[i].string)) {
+		i++;
+		if (unborn_head_target &&
+		    !strcmp("HEAD", line_sections.items[i++].string)) {
+			/*
+			 * Look for the symref target (if any). If found,
+			 * return it to the caller.
+			 */
+			for (; i < line_sections.nr; i++) {
+				const char *arg = line_sections.items[i].string;
+
+				if (skip_prefix(arg, "symref-target:", &arg)) {
+					*unborn_head_target = xstrdup(arg);
+					break;
+				}
+			}
+		}
+		goto out;
+	}
 	if (parse_oid_hex_algop(line_sections.items[i++].string, &old_oid, &end, reader->hash_algo) ||
 	    *end) {
 		ret = 0;
@@ -489,6 +509,8 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
 	if (!for_push)
 		packet_write_fmt(fd_out, "peel\n");
 	packet_write_fmt(fd_out, "symrefs\n");
+	if (server_supports_feature("ls-refs", "unborn", 0))
+		packet_write_fmt(fd_out, "unborn\n");
 	for (i = 0; ref_prefixes && i < ref_prefixes->nr; i++) {
 		packet_write_fmt(fd_out, "ref-prefix %s\n",
 				 ref_prefixes->v[i]);
@@ -497,9 +519,7 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
 
 	/* Process response from server */
 	while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
-		if (unborn_head_target)
-			BUG("NEEDSWORK: provide unborn HEAD target to caller while reading refs");
-		if (!process_ref_v2(reader, &list))
+		if (!process_ref_v2(reader, &list, unborn_head_target))
 			die(_("invalid ls-refs response: %s"), reader->line);
 	}
 
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 7f082fb23b..67a4c6d05b 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -102,11 +102,12 @@ test_expect_success 'redirected clone -v does show progress' '
 '
 
 test_expect_success 'chooses correct default initial branch name' '
-	git init --bare empty &&
+	git -c init.defaultBranch=foo init --bare empty &&
+	test_config -C empty lsrefs.allowUnborn true &&
 	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \
 	git -c init.defaultBranch=up clone empty whats-up &&
-	test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
-	test refs/heads/up = $(git -C whats-up config branch.up.merge)
+	test refs/heads/foo = $(git -C whats-up symbolic-ref HEAD) &&
+	test refs/heads/foo = $(git -C whats-up config branch.foo.merge)
 '
 
 test_expect_success 'guesses initial branch name correctly' '
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 7d5b17909b..4fbbe5aff5 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -209,6 +209,15 @@ test_expect_success 'clone with file:// using protocol v2' '
 	grep "ref-prefix refs/tags/" log
 '
 
+test_expect_success 'clone of empty repo propagates name of default branch' '
+	git -c init.defaultBranch=mydefaultbranch init file_empty_parent &&
+	test_config -C file_empty_parent lsrefs.allowUnborn true &&
+
+	git -c init.defaultBranch=main -c protocol.version=2 \
+		clone "file://$(pwd)/file_empty_parent" file_empty_child &&
+	grep "refs/heads/mydefaultbranch" file_empty_child/.git/HEAD
+'
+
 test_expect_success 'fetch with file:// using protocol v2' '
 	test_when_finished "rm -f log" &&
 
-- 
2.29.2.729.g45daf8777d-goog


  parent reply	other threads:[~2020-12-21 22:33 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-08  1:31 Cloning empty repository uses locally configured default branch name Jonathan Tan
2020-12-08  2:16 ` Junio C Hamano
2020-12-08  2:32   ` brian m. carlson
2020-12-08 18:55   ` Jonathan Tan
2020-12-08 21:00     ` Junio C Hamano
2020-12-08 15:58 ` Jeff King
2020-12-08 20:06   ` Jonathan Tan
2020-12-08 21:15     ` Jeff King
2020-12-11 21:05 ` [PATCH] clone: in protocol v2, use remote's default branch Jonathan Tan
2020-12-11 23:41   ` Junio C Hamano
2020-12-14 12:38   ` Ævar Arnfjörð Bjarmason
2020-12-14 15:51     ` Felipe Contreras
2020-12-14 16:30     ` Junio C Hamano
2020-12-15  1:41       ` Ævar Arnfjörð Bjarmason
2020-12-15  2:22         ` Junio C Hamano
2020-12-15  2:38         ` Jeff King
2020-12-15  2:55           ` Junio C Hamano
2020-12-15  4:36             ` Jeff King
2020-12-16  3:09               ` Junio C Hamano
2020-12-16 18:39                 ` Jeff King
2020-12-16 20:56                   ` Junio C Hamano
2020-12-18  6:19                     ` Jeff King
2020-12-15  3:22         ` Felipe Contreras
2020-12-14 19:25     ` Jonathan Tan
2020-12-14 19:42       ` Felipe Contreras
2020-12-15  1:27   ` Jeff King
2020-12-15 19:10     ` Jonathan Tan
2020-12-16  2:07   ` [PATCH v2 0/3] Cloning with remote unborn HEAD Jonathan Tan
2020-12-16  2:07     ` [PATCH v2 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2020-12-16  6:16       ` Junio C Hamano
2020-12-16 23:49         ` Jonathan Tan
2020-12-16 18:23       ` Jeff King
2020-12-16 23:54         ` Jonathan Tan
2020-12-17  1:32           ` Junio C Hamano
2020-12-18  6:16             ` Jeff King
2020-12-16  2:07     ` [PATCH v2 2/3] connect, transport: add no-op arg for future patch Jonathan Tan
2020-12-16  6:20       ` Junio C Hamano
2020-12-16  2:07     ` [PATCH v2 3/3] clone: respect remote unborn HEAD Jonathan Tan
2020-12-21 22:30   ` [PATCH v3 0/3] Cloning with " Jonathan Tan
2020-12-21 22:30     ` [PATCH v3 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2020-12-21 22:31     ` [PATCH v3 2/3] connect, transport: add no-op arg for future patch Jonathan Tan
2020-12-21 22:31     ` Jonathan Tan [this message]
2020-12-21 23:48     ` [PATCH v3 0/3] Cloning with remote unborn HEAD Junio C Hamano
2021-01-21 20:14     ` Jeff King
2020-12-22 21:54   ` [PATCH v4 " Jonathan Tan
2020-12-22 21:54     ` [PATCH v4 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2021-01-21 20:48       ` Jeff King
2021-01-26 18:13         ` Jonathan Tan
2021-01-26 23:16           ` Jeff King
2020-12-22 21:54     ` [PATCH v4 2/3] connect, transport: add no-op arg for future patch Jonathan Tan
2021-01-21 20:55       ` Jeff King
2021-01-26 18:16         ` Jonathan Tan
2020-12-22 21:54     ` [PATCH v4 3/3] clone: respect remote unborn HEAD Jonathan Tan
2021-01-21 21:02       ` Jeff King
2021-01-26 18:22         ` Jonathan Tan
2021-01-26 23:04           ` Jeff King
2021-01-28  5:50             ` Junio C Hamano
2020-12-22 22:06     ` [PATCH v4 0/3] Cloning with " Junio C Hamano
2021-01-26 18:55 ` [PATCH v5 " Jonathan Tan
2021-01-26 18:55   ` [PATCH v5 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2021-01-26 21:38     ` Junio C Hamano
2021-01-26 23:03       ` Junio C Hamano
2021-01-30  3:55         ` Jonathan Tan
2021-01-26 23:20       ` Jeff King
2021-01-26 23:38         ` Junio C Hamano
2021-01-29 20:23       ` Jonathan Tan
2021-01-29 22:04         ` Junio C Hamano
2021-02-02  2:20           ` Jonathan Tan
2021-02-02  5:00             ` Junio C Hamano
2021-01-27  1:28     ` Ævar Arnfjörð Bjarmason
2021-01-30  4:04       ` Jonathan Tan
2021-01-26 18:55   ` [PATCH v5 2/3] connect, transport: encapsulate arg in struct Jonathan Tan
2021-01-26 21:54     ` Junio C Hamano
2021-01-30  4:06       ` Jonathan Tan
2021-01-26 18:55   ` [PATCH v5 3/3] clone: respect remote unborn HEAD Jonathan Tan
2021-01-26 22:24     ` Junio C Hamano
2021-01-30  4:27       ` Jonathan Tan
2021-01-27  1:11   ` [PATCH v5 0/3] Cloning with " Junio C Hamano
2021-01-27  4:25     ` Jeff King
2021-01-27  6:14       ` Junio C Hamano
2021-01-27  1:41   ` Ævar Arnfjörð Bjarmason
2021-01-30  4:41     ` Jonathan Tan
2021-01-30 11:13       ` Ævar Arnfjörð Bjarmason
2021-02-02  2:22       ` Jonathan Tan
2021-02-03 14:23         ` Ævar Arnfjörð Bjarmason
2021-02-05 22:28     ` Junio C Hamano
2021-02-02  2:14 ` [PATCH v6 " Jonathan Tan
2021-02-02  2:14   ` [PATCH v6 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2021-02-02 16:55     ` Junio C Hamano
2021-02-02 18:34       ` Jonathan Tan
2021-02-02 22:17         ` Junio C Hamano
2021-02-03  1:04           ` Jonathan Tan
2021-02-02  2:15   ` [PATCH v6 2/3] connect, transport: encapsulate arg in struct Jonathan Tan
2021-02-02  2:15   ` [PATCH v6 3/3] clone: respect remote unborn HEAD Jonathan Tan
2021-02-05  4:58 ` [PATCH v7 0/3] Cloning with " Jonathan Tan
2021-02-05  4:58   ` [PATCH v7 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2021-02-05 16:10     ` Jeff King
2021-02-05  4:58   ` [PATCH v7 2/3] connect, transport: encapsulate arg in struct Jonathan Tan
2021-02-05  4:58   ` [PATCH v7 3/3] clone: respect remote unborn HEAD Jonathan Tan
2021-02-05  5:25   ` [PATCH v7 0/3] Cloning with " Junio C Hamano
2021-02-05 16:15     ` Jeff King
2021-02-05 21:15     ` Ævar Arnfjörð Bjarmason
2021-02-05 23:07       ` Junio C Hamano
2021-02-05 20:48 ` [PATCH v8 " Jonathan Tan
2021-02-05 20:48   ` [PATCH v8 1/3] ls-refs: report unborn targets of symrefs Jonathan Tan
2021-02-05 20:48   ` [PATCH v8 2/3] connect, transport: encapsulate arg in struct Jonathan Tan
2021-02-05 20:48   ` [PATCH v8 3/3] clone: respect remote unborn HEAD Jonathan Tan
2021-02-06 18:51   ` [PATCH v8 0/3] Cloning with " Junio C Hamano
2021-02-08 22:28     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c2303dc9761493decd7a21a7f1e89d6dd9c646e4.1608587839.git.jonathantanmy@google.com \
    --to=jonathantanmy@google.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).