All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bence Ferdinandy <bence@ferdinandy.com>
To: git@vger.kernel.org
Cc: "Fővárosi Vízművek Zrt." <noreply@vizmuvek.hu>,
	"Bence Ferdinandy" <bence@ferdinandy.com>
Subject: [PATCH v10 8/8] fetch set_head: handle mirrored bare repositories
Date: Mon, 21 Oct 2024 15:37:05 +0200	[thread overview]
Message-ID: <20241021134354.705636-9-bence@ferdinandy.com> (raw)
In-Reply-To: <20241021134354.705636-1-bence@ferdinandy.com>

When adding a remote to bare repository with "git remote add --mirror",
running fetch will fail to update HEAD to the remote's HEAD, since it
does not know how to handle bare repositories. On the other hand HEAD
already has content, since "git init --bare" has already set HEAD to
whatever is the default branch set for the user. Unless this - by chance
- is the same as the remote's HEAD, HEAD will be pointing to a bad
symref. Teach set_head to handle bare repositories, by overwriting HEAD
so it mirrors the remote's HEAD.

Note, that in this case overriding the local HEAD reference is
necessary, since HEAD will exist before fetch can be run, but this
should not be an issue, since the whole purpose of --mirror is to be an
exact mirror of the remote, so following any changes to HEAD makes
sense.

Also note, that although "git remote set-head" also fails when trying to
update the remote's locally tracked HEAD in a mirrored bare repository,
the usage of the command does not make much sense after this patch:
fetch will update the remote HEAD correctly, and setting it manually to
something else is antithetical to the concept of mirroring.

Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
---

Notes:
    v10: - new patch
         - handles the issue discovered in
           https://lore.kernel.org/git/D4ZAELFWJMKN.S88LJ6YK31LZ@ferdinandy.com/T/

 builtin/fetch.c   | 16 ++++++++++++----
 t/t5505-remote.sh | 10 ++++++++++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 31edc67447..249556c9c6 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1632,14 +1632,22 @@ static int set_head(const struct ref *remote_refs)
 	else
 		head_name = xstrdup(heads.items[0].string);
 	if (head_name) {
-		strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote);
-		strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name);
+		int is_bare = is_bare_repository();
+		if (is_bare) {
+			strbuf_addstr(&b_head, "HEAD");
+			strbuf_addf(&b_remote_head, "refs/heads/%s", head_name);
+		} else {
+			strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote);
+			strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name);
+		}
 		/* make sure it's valid */
-		if (!refs_ref_exists(refs, b_remote_head.buf))
+		if (!is_bare && !refs_ref_exists(refs, b_remote_head.buf)) {
 			result = 1;
+		}
 		else if (refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf,
-					"fetch", &b_local_head, 1))
+					"fetch", &b_local_head, !is_bare)) {
 			result = 1;
+		}
 		else
 			report_set_head(remote, head_name, &b_local_head);
 
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 4990d00209..dfa78f3e8d 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -545,6 +545,16 @@ test_expect_success 'add --mirror && prune' '
 	)
 '
 
+test_expect_success 'add --mirror setting HEAD' '
+	mkdir headmirror &&
+	(
+		cd headmirror &&
+		git init --bare -b notmain &&
+		git remote add --mirror -f origin ../one &&
+		test "$(git symbolic-ref HEAD)" = "refs/heads/main"
+	)
+'
+
 test_expect_success 'add --mirror=fetch' '
 	mkdir mirror-fetch &&
 	git init -b main mirror-fetch/parent &&
-- 
2.47.0.94.g8861098b6d


  parent reply	other threads:[~2024-10-21 13:45 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1088915169.629942.1729445083543@FVRT-HAMMYAS-P.vizmuvek.hu>
2024-10-21 13:36 ` [PATCH v10 0/8] set-head/fetch remote/HEAD updates Bence Ferdinandy
2024-10-21 13:36   ` [PATCH v10 1/8] t/t5505-remote: set default branch to main Bence Ferdinandy
2024-10-21 13:36   ` [PATCH v10 2/8] refs: atomically record overwritten ref in update_symref Bence Ferdinandy
2024-10-21 13:37   ` [PATCH v10 3/8] remote set-head: refactor for readability Bence Ferdinandy
2024-10-21 13:37   ` [PATCH v10 4/8] remote set-head: better output for --auto Bence Ferdinandy
2024-10-21 13:37   ` [PATCH v10 5/8] refs: add TRANSACTION_CREATE_EXISTS error Bence Ferdinandy
2024-10-21 13:37   ` [PATCH v10 6/8] refs: add create_only option to refs_update_symref_extended Bence Ferdinandy
2024-10-21 13:37   ` [PATCH v10 7/8] fetch: set remote/HEAD if it does not exist Bence Ferdinandy
2024-10-21 13:37   ` Bence Ferdinandy [this message]
2024-10-21 20:43   ` [PATCH v10 0/8] set-head/fetch remote/HEAD updates Taylor Blau
2024-10-21 21:06     ` Bence Ferdinandy
2024-10-22 17:39   ` Taylor Blau
2024-10-22 18:33     ` Bence Ferdinandy
2024-10-22 19:04       ` Taylor Blau
2024-10-22 19:09         ` Bence Ferdinandy

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

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

  git send-email \
    --in-reply-to=20241021134354.705636-9-bence@ferdinandy.com \
    --to=bence@ferdinandy.com \
    --cc=git@vger.kernel.org \
    --cc=noreply@vizmuvek.hu \
    /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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.