All of lore.kernel.org
 help / color / mirror / Atom feed
From: Taylor Blau <ttaylorr@openai.com>
To: git@vger.kernel.org, git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 4/4] send-pack: honor `no-ref-delta` capability
Date: Sun, 12 Jul 2026 18:12:07 -0700	[thread overview]
Message-ID: <alQ7Z8V9gJq2Pq33@com-79390> (raw)
In-Reply-To: <cover.1783905084.git.ttaylorr@openai.com>

Add a 'no-ref-delta' receive-pack capability and teach send-pack to pass
'--no-ref-delta' to 'pack-objects' when the server advertises it.

Keep this separate from 'ofs-delta' so that a server may request that
`send-pack` omit `REF_DELTA` without also accepting `OFS_DELTA`.

Signed-off-by: Taylor Blau <ttaylorr@openai.com>
---
 Documentation/gitprotocol-capabilities.adoc | 17 ++++++++++++++---
 builtin/receive-pack.c                      |  5 +++++
 send-pack.c                                 |  4 ++++
 send-pack.h                                 |  1 +
 t/t5516-fetch-push.sh                       | 14 ++++++++++++++
 5 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/Documentation/gitprotocol-capabilities.adoc b/Documentation/gitprotocol-capabilities.adoc
index 2cf7735be4..bbe88defdf 100644
--- a/Documentation/gitprotocol-capabilities.adoc
+++ b/Documentation/gitprotocol-capabilities.adoc
@@ -34,9 +34,9 @@ were sent.  Server MUST NOT ignore capabilities that client requested
 and server advertised.  As a consequence of these rules, server MUST
 NOT advertise capabilities it does not understand.
 
-The 'atomic', 'report-status', 'report-status-v2', 'delete-refs', 'quiet',
-and 'push-cert' capabilities are sent and recognized by the receive-pack
-(push to server) process.
+The 'atomic', 'report-status', 'report-status-v2', 'delete-refs',
+'no-ref-delta', 'quiet', and 'push-cert' capabilities are sent and
+recognized by the receive-pack (push to server) process.
 
 The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
 by both upload-pack and receive-pack protocols.  The 'agent' and 'session-id'
@@ -174,6 +174,17 @@ The server can send, and the client can understand, PACKv2 with delta referring
 its base by position in pack rather than by an obj-id.  That is, they can
 send/read OBJ_OFS_DELTA (aka type 6) in a packfile.
 
+no-ref-delta
+------------
+
+The receive-pack server can request, and the client can send, PACKv2
+without deltas referring to their bases by an obj-id. That is, the
+client MUST NOT send OBJ_REF_DELTA (aka type 7) in a packfile when the
+server advertises this capability.
+
+This does not imply that the server understands OBJ_OFS_DELTA entries;
+that is negotiated separately with the 'ofs-delta' capability.
+
 agent
 -----
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 19eb6a1b61..1c516cbdc6 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -66,6 +66,7 @@ static struct strbuf fsck_msg_types = STRBUF_INIT;
 static int receive_unpack_limit = -1;
 static int transfer_unpack_limit = -1;
 static int advertise_atomic_push = 1;
+static int advertise_no_ref_delta;
 static int advertise_push_options;
 static int advertise_sid;
 static int unpack_limit = 100;
@@ -290,6 +291,8 @@ static void show_ref(const char *path, const struct object_id *oid)
 			strbuf_addstr(&cap, " atomic");
 		if (prefer_ofs_delta)
 			strbuf_addstr(&cap, " ofs-delta");
+		if (advertise_no_ref_delta)
+			strbuf_addstr(&cap, " no-ref-delta");
 		if (push_cert_nonce)
 			strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
 		if (advertise_push_options)
@@ -2631,6 +2634,8 @@ int cmd_receive_pack(int argc,
 		OPT_HIDDEN_BOOL(0, "http-backend-info-refs", &advertise_refs, NULL),
 		OPT_ALIAS(0, "advertise-refs", "http-backend-info-refs"),
 		OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL),
+		OPT_HIDDEN_BOOL(0, "advertise-no-ref-delta-for-testing",
+				&advertise_no_ref_delta, NULL),
 		OPT_END()
 	};
 
diff --git a/send-pack.c b/send-pack.c
index 3bb5afc687..2beb1c4be9 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -80,6 +80,8 @@ static int pack_objects(struct repository *r,
 		strvec_push(&po.args, "--thin");
 	if (args->use_ofs_delta)
 		strvec_push(&po.args, "--delta-base-offset");
+	if (args->no_ref_delta)
+		strvec_push(&po.args, "--no-ref-delta");
 	if (args->quiet || !args->progress)
 		strvec_push(&po.args, "-q");
 	if (args->progress)
@@ -570,6 +572,8 @@ int send_pack(struct repository *r,
 		allow_deleting_refs = 1;
 	if (server_supports("ofs-delta"))
 		args->use_ofs_delta = 1;
+	if (server_supports("no-ref-delta"))
+		args->no_ref_delta = 1;
 	if (server_supports("side-band-64k"))
 		use_sideband = 1;
 	if (server_supports("quiet"))
diff --git a/send-pack.h b/send-pack.h
index 13850c98bb..30be2be0f2 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -28,6 +28,7 @@ struct send_pack_args {
 		force_update:1,
 		use_thin_pack:1,
 		use_ofs_delta:1,
+		no_ref_delta:1,
 		dry_run:1,
 		/* One of the SEND_PACK_PUSH_CERT_* constants. */
 		push_cert:2,
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 1b986349a8..c00074afe8 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1548,6 +1548,20 @@ EOF
 	git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/main:refs/heads/foo
 '
 
+test_expect_success 'push honors no-ref-delta capability' '
+	test_commit no-ref-delta &&
+
+	rcvpck="git receive-pack --advertise-no-ref-delta-for-testing" &&
+
+	GIT_TRACE2_EVENT="$PWD/no-ref-delta" \
+	git push --receive-pack="$rcvpck" no-thin/.git \
+		refs/heads/main:refs/heads/bar &&
+
+	test_subcommand git pack-objects --all-progress-implied --revs \
+		--stdout --thin --delta-base-offset --no-ref-delta -q \
+		<no-ref-delta
+'
+
 test_expect_success 'pushing a tag pushes the tagged object' '
 	blob=$(echo unreferenced | git hash-object -w --stdin) &&
 	git tag -m foo tag-of-blob $blob &&
-- 
2.55.0

      parent reply	other threads:[~2026-07-13  1:12 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1783905084.git.ttaylorr@openai.com>
2026-07-13  1:11 ` [PATCH 1/4] t/helper: teach pack-deltas to list delta entries Taylor Blau
2026-07-13  1:11 ` [PATCH 2/4] pack-objects: introduce `--no-ref-delta` Taylor Blau
2026-07-13  1:12 ` [PATCH 3/4] pack-objects: support reuse with `--no-ref-delta` Taylor Blau
2026-07-13  1:12 ` Taylor Blau [this message]

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=alQ7Z8V9gJq2Pq33@com-79390 \
    --to=ttaylorr@openai.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /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.