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'
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
-----
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;
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)
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()
};
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)
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"))
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,
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 &&