Git development
 help / color / mirror / Atom feed
From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Patrick Steinhardt <ps@pks.im>,
	Christian Couder <christian.couder@gmail.com>
Subject: [PATCH] promisor-remote: fix crash without a repository
Date: Fri, 13 Nov 2026 01:06:01 +0100	[thread overview]
Message-ID: <20261113000600.202744-2-christian.couder@gmail.com> (raw)

When `git ls-remote` is run outside a repo with some promisor remote
related config options that make it write to its config, namely:

  - "promisor.acceptFromServerUrl", which makes it auto-create a
    remote, or
  - "promisor.acceptFromServer" with "promisor.storeFields", which
    makes it store fields,

it crashes in configure_auto_promisor_remote() or store_one_field(), as
the `repo` argument passed to these functions has its `gitdir` member
set to NULL.

This has been happening since 3e20258d11 (promisor-remote: allow a
client to store fields, 2026-02-16) for the `storeFields` case, and
since 7a56394fc6 (promisor-remote: auto-configure unknown remotes,
2026-05-27) for the auto-creation case.

Let's fix that by checking if `repo->gitdir` is NULL at the beginning
of filter_promisor_remote() and returning from it right away in that
case. It doesn't make sense to further process the promisor remote
advertisement as `git ls-remote` currently has no use for promisor
remotes anyway.

Note that `git ls-remote` seems to be the only command that can run
outside a repo and still process the "promisor-remote" capability
advertised by the server, as sending the `ls-refs` protocol v2
command makes it call send_capabilities(), which processes that
advertisement.

Let's also add tests in t5710 for both cases where a crash happened.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
---

This is a fix for another bug found during the NVIDIA hackathon
following the Gerrit User Summit 2026.

 promisor-remote.c                     |  7 +++++-
 t/t5710-promisor-remote-capability.sh | 31 +++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/promisor-remote.c b/promisor-remote.c
index 316d9950aa..9c405847bb 100644
--- a/promisor-remote.c
+++ b/promisor-remote.c
@@ -1310,9 +1310,14 @@ static void filter_promisor_remote(struct repository *repo,
 	struct store_info *store_info = NULL;
 	struct string_list_item *item;
 	bool reload_config = false;
-	enum accept_promisor accept = accept_from_server(repo);
+	enum accept_promisor accept;
 	struct string_list accept_urls = STRING_LIST_INIT_DUP;
 
+	if (!repo->gitdir)
+		return;
+
+	accept = accept_from_server(repo);
+
 	/* Load and validate the acceptFromServerUrl config */
 	load_accept_from_server_url(repo, &accept_urls);
 
diff --git a/t/t5710-promisor-remote-capability.sh b/t/t5710-promisor-remote-capability.sh
index 463e9e00b0..50a73ec8b0 100755
--- a/t/t5710-promisor-remote-capability.sh
+++ b/t/t5710-promisor-remote-capability.sh
@@ -813,6 +813,37 @@ test_expect_success "clone with invalid promisor.acceptFromServerUrl" '
 	initialize_server 1 "$oid"
 '
 
+test_expect_success "ls-remote without a repo doesn't auto-configure" '
+	git -C server config promisor.advertise true &&
+
+	nongit git -c promisor.acceptFromServerUrl="$ENCODED_TRASH_DIRECTORY_URL/*" \
+		ls-remote "$TRASH_DIRECTORY_URL/server" >out 2>&1 &&
+
+	# Refs are properly listed
+	test_grep "refs/heads/" out &&
+
+	# No remote is configured
+	test_grep ! "Auto-creating" out
+'
+
+test_expect_success "ls-remote without a repo doesn't store fields" '
+	git -C server config promisor.advertise true &&
+	test_config -C server promisor.sendFields token &&
+	test_config -C server remote.lop.token "fooBar" &&
+
+	nongit git -c promisor.acceptFromServer=All \
+		-c promisor.storeFields=token \
+		-c remote.lop.promisor=true \
+		-c remote.lop.url="$TRASH_DIRECTORY_URL/lop" \
+		ls-remote "$TRASH_DIRECTORY_URL/server" >out 2>&1 &&
+
+	# Refs are properly listed
+	test_grep "refs/heads/" out &&
+
+	# No field is stored
+	test_grep ! "Storing new token" out
+'
+
 test_expect_success "clone with promisor.sendFields" '
 	git -C server config promisor.advertise true &&
 	test_when_finished "rm -rf client" &&

base-commit: 1891de46f79dc444a47db1c87bd0c8c76b5463f2
-- 
2.56.0


             reply	other threads:[~2026-11-13  0:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13  0:06 Christian Couder [this message]
2026-11-13 19:42 ` [PATCH] promisor-remote: fix crash without a repository 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

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

  git send-email \
    --in-reply-to=20261113000600.202744-2-christian.couder@gmail.com \
    --to=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=ps@pks.im \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox