Skip to content

Commit b1e3ec2

Browse files
Merge tb/codex/parallel-packfile-uris into codex
Integrate the current tb/codex/parallel-packfile-uris topic into the internally distributed codex branch. Codex-Integration: tb/codex/parallel-packfile-uris@a08b8d8bb7e3082e9d8e3d29e1535579234784be
2 parents ac651c4 + a08b8d8 commit b1e3ec2

22 files changed

Lines changed: 621 additions & 37 deletions

Documentation/config/fetch.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ A value of 0 will give some reasonable default. If unset, it defaults to 1.
9494
For submodules, this setting can be overridden using the `submodule.fetchJobs`
9595
config setting.
9696

97+
`fetch.packfileUriJobs`::
98+
Specifies the maximum number of packfile URI downloads and indexers
99+
to run at once. The default is 1, which preserves advertised URI
100+
order.
101+
+
102+
Values greater than 1 are used only when the server advertises and the
103+
client requests the `no-ref-delta` promise. Each URI pack is then checked
104+
with `index-pack --no-ref-delta` before it is accepted.
105+
Responses with one URI retain the serial path.
106+
97107
`fetch.writeCommitGraph`::
98108
Set to true to write a commit-graph after every `git fetch` command
99109
that downloads a pack-file from a remote. Using the `--split` option,

Documentation/config/uploadpack.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,14 @@ uploadpack.allowRefInWant::
8686
is intended for the benefit of load-balanced servers which may
8787
not have the same view of what OIDs their refs point to due to
8888
replication delay.
89+
90+
uploadpack.allowNoRefDelta::
91+
If this option is set, `upload-pack` may advertise the
92+
`no-ref-delta` feature of the protocol version 2 `fetch`
93+
command. When a client requests the feature, `upload-pack` passes
94+
`--no-ref-delta` to `pack-objects` for the inline pack and promises
95+
that every pack named in a `packfile-uris` response section also
96+
contains no `REF_DELTA` entries. `upload-pack` does not inspect
97+
configured URI packs, so the server administrator must create each
98+
pack with `pack-objects --no-ref-delta` or otherwise verify this
99+
property. The default is `false`.

Documentation/git-index-pack.adoc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ git-index-pack - Build pack index file for an existing packed archive
99
SYNOPSIS
1010
--------
1111
[verse]
12-
'git index-pack' [-v] [-o <index-file>] [--[no-]rev-index] <pack-file>
13-
'git index-pack' --stdin [--fix-thin] [--keep] [-v] [-o <index-file>]
12+
'git index-pack' [-v] [-o <index-file>] [--no-ref-delta]
13+
[--[no-]rev-index] <pack-file>
14+
'git index-pack' --stdin [--fix-thin] [--keep] [--no-ref-delta]
15+
[-v] [-o <index-file>]
1416
[--[no-]rev-index] [<pack-file>]
1517

1618

@@ -60,6 +62,11 @@ OPTIONS
6062
excluded objects the deltified objects are based on to the
6163
pack. This option only makes sense in conjunction with --stdin.
6264

65+
--no-ref-delta::
66+
Reject a pack containing a `REF_DELTA` entry. `OFS_DELTA` entries
67+
are accepted. This option can be used to verify a protocol promise
68+
that a pack contains no `REF_DELTA` entries.
69+
6370
--keep::
6471
Before moving the index into its final destination
6572
create an empty .keep file for the associated pack file.

Documentation/git-pack-objects.adoc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ SYNOPSIS
1010
--------
1111
[verse]
1212
'git pack-objects' [-q | --progress | --all-progress] [--all-progress-implied]
13-
[--no-reuse-delta] [--delta-base-offset] [--non-empty]
13+
[--no-reuse-delta] [--delta-base-offset] [--no-ref-delta]
14+
[--non-empty]
1415
[--local] [--incremental] [--window=<n>] [--depth=<n>]
1516
[--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
1617
[--cruft] [--cruft-expiration=<time>]
@@ -297,6 +298,11 @@ Note: Porcelain commands such as `git gc` (see linkgit:git-gc[1]),
297298
in modern Git when they put objects in your repository into pack files.
298299
So does `git bundle` (see linkgit:git-bundle[1]) when it creates a bundle.
299300

301+
--no-ref-delta::
302+
Do not emit deltas which represent their base by their literal
303+
object ID. This is independent of `--delta-base-offset`;
304+
without that option, no deltas are emitted.
305+
300306
--threads=<n>::
301307
Specifies the number of threads to spawn when searching for best
302308
delta matches. This requires that pack-objects be compiled with

Documentation/gitprotocol-capabilities.adoc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ were sent. Server MUST NOT ignore capabilities that client requested
3434
and server advertised. As a consequence of these rules, server MUST
3535
NOT advertise capabilities it does not understand.
3636

37-
The 'atomic', 'report-status', 'report-status-v2', 'delete-refs', 'quiet',
38-
and 'push-cert' capabilities are sent and recognized by the receive-pack
39-
(push to server) process.
37+
The 'atomic', 'report-status', 'report-status-v2', 'delete-refs',
38+
'no-ref-delta', 'quiet', and 'push-cert' capabilities are sent and
39+
recognized by the receive-pack (push to server) process.
4040

4141
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
4242
by both upload-pack and receive-pack protocols. The 'agent' and 'session-id'
@@ -174,6 +174,21 @@ The server can send, and the client can understand, PACKv2 with delta referring
174174
its base by position in pack rather than by an obj-id. That is, they can
175175
send/read OBJ_OFS_DELTA (aka type 6) in a packfile.
176176
177+
no-ref-delta
178+
------------
179+
180+
The receive-pack server can request, and the client can send, PACKv2
181+
without deltas referring to their bases by an obj-id. That is, the
182+
client MUST NOT send OBJ_REF_DELTA (aka type 7) in a packfile when the
183+
server advertises this capability.
184+
185+
This does not imply that the server understands OBJ_OFS_DELTA entries;
186+
that is negotiated separately with the 'ofs-delta' capability.
187+
188+
Protocol v2 `fetch` uses the same name for the corresponding
189+
upload-pack request. There, the promise covers both the inline pack and
190+
any packs named by a `packfile-uris` section.
191+
177192
agent
178193
-----
179194

Documentation/gitprotocol-v2.adoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,18 @@ to the server.
376376
client should download from all given URIs. Currently, the
377377
protocols supported are "http" and "https".
378378
379+
If the 'no-ref-delta' feature is advertised, the following argument can
380+
be included in the client's request:
381+
382+
no-ref-delta
383+
Indicates that the server MUST NOT include a `REF_DELTA` entry in
384+
the inline `packfile` section or any pack named by a
385+
`packfile-uris` section.
386+
+
387+
`no-ref-delta` does not imply `ofs-delta`. The server may use `OFS_DELTA`
388+
only when the client also requests `ofs-delta`. By definition, an
389+
`OFS_DELTA` refers to an earlier entry in the same pack.
390+
379391
If the 'wait-for-done' feature is advertised, the following argument
380392
can be included in the client's request.
381393

Documentation/technical/packfile-uri.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ Clients should then download and index all the given URIs (in addition to
2525
downloading and indexing the packfile given in the `packfile` section of the
2626
response) before performing the connectivity check.
2727

28+
URI packs are normally indexed in advertised order, since a later pack may
29+
contain a `REF_DELTA` whose base is installed by an earlier response pack.
30+
If the server advertises `no-ref-delta` and the client requests it, the
31+
promise covers the inline pack and every URI pack. A client may then index
32+
URI packs concurrently, while rejecting any pack that contains a
33+
`REF_DELTA`.
34+
2835
Server design
2936
-------------
3037

builtin/index-pack.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include "strvec.h"
3434

3535
static const char index_pack_usage[] =
36-
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict[=<msg-id>=<severity>...]] [--fsck-objects[=<msg-id>=<severity>...]] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
36+
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict[=<msg-id>=<severity>...]] [--fsck-objects[=<msg-id>=<severity>...]] [--no-ref-delta] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
3737

3838
struct object_entry {
3939
struct pack_idx_entry idx;
@@ -138,6 +138,7 @@ static int strict;
138138
static int do_fsck_object;
139139
static struct fsck_options fsck_options;
140140
static int verbose;
141+
static int no_ref_delta;
141142
static const char *progress_title;
142143
static int show_resolving_progress;
143144
static int show_stat;
@@ -550,6 +551,9 @@ static void *unpack_raw_entry(struct object_entry *obj,
550551

551552
switch (obj->type) {
552553
case OBJ_REF_DELTA:
554+
if (no_ref_delta)
555+
bad_object(obj->idx.offset,
556+
_("REF_DELTA not allowed by --no-ref-delta"));
553557
oidread(ref_oid, fill(the_hash_algo->rawsz),
554558
the_repository->hash_algo);
555559
use(the_hash_algo->rawsz);
@@ -1937,6 +1941,8 @@ int cmd_index_pack(int argc,
19371941
from_stdin = 1;
19381942
} else if (!strcmp(arg, "--fix-thin")) {
19391943
fix_thin_pack = 1;
1944+
} else if (!strcmp(arg, "--no-ref-delta")) {
1945+
no_ref_delta = 1;
19401946
} else if (skip_to_optional_arg(arg, "--strict", &arg)) {
19411947
strict = 1;
19421948
do_fsck_object = 1;

builtin/pack-objects.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ static inline void oe_set_delta_size(struct packing_data *pack,
191191

192192
static const char *const pack_usage[] = {
193193
N_("git pack-objects [-q | --progress | --all-progress] [--all-progress-implied]\n"
194-
" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n"
194+
" [--no-reuse-delta] [--delta-base-offset] [--no-ref-delta]\n"
195+
" [--non-empty]\n"
195196
" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n"
196197
" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n"
197198
" [--cruft] [--cruft-expiration=<time>]\n"
@@ -222,6 +223,7 @@ static int ignore_packed_keep_in_core;
222223
static int ignore_packed_keep_in_core_open;
223224
static int ignore_packed_keep_in_core_has_cruft;
224225
static int allow_ofs_delta;
226+
static int allow_ref_delta = 1;
225227
static struct pack_idx_option pack_idx_opts;
226228
static const char *base_name;
227229
static int progress = 1;
@@ -2212,6 +2214,13 @@ static int can_reuse_delta(const struct object_id *base_oid,
22122214
*/
22132215
base = packlist_find(&to_pack, base_oid);
22142216
if (base) {
2217+
/*
2218+
* A preferred base is omitted from the resulting pack, so it
2219+
* can only be referenced by object ID.
2220+
*/
2221+
if (base->preferred_base && !allow_ref_delta)
2222+
return 0;
2223+
22152224
if (!in_same_island(&delta->idx.oid, &base->idx.oid))
22162225
return 0;
22172226
*base_out = base;
@@ -2223,7 +2232,8 @@ static int can_reuse_delta(const struct object_id *base_oid,
22232232
* even if it was buried too deep in history to make it into the
22242233
* packing list.
22252234
*/
2226-
if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, base_oid)) {
2235+
if (allow_ref_delta && thin &&
2236+
bitmap_has_oid_in_uninteresting(bitmap_git, base_oid)) {
22272237
if (use_delta_islands) {
22282238
if (!in_same_island(&delta->idx.oid, base_oid))
22292239
return 0;
@@ -3412,6 +3422,9 @@ static int should_attempt_deltas(struct object_entry *entry)
34123422
if (entry->no_try_delta)
34133423
return 0;
34143424

3425+
if (entry->preferred_base && !allow_ref_delta)
3426+
return 0;
3427+
34153428
if (!entry->preferred_base) {
34163429
if (oe_type(entry) < 0)
34173430
die(_("unable to get type of object %s"),
@@ -3654,7 +3667,8 @@ static void prepare_pack(int window, int depth)
36543667
if (!pack_to_stdout)
36553668
do_check_packed_object_crc = 1;
36563669

3657-
if (!to_pack.nr_objects || !window || !depth)
3670+
if (!to_pack.nr_objects || !window || !depth ||
3671+
(!allow_ref_delta && !allow_ofs_delta))
36583672
return;
36593673

36603674
if (path_walk)
@@ -4717,7 +4731,7 @@ static int pack_options_allow_reuse(void)
47174731
!ignore_packed_keep_on_disk &&
47184732
!ignore_packed_keep_in_core &&
47194733
(!local || !have_non_local_packs) &&
4720-
!incremental;
4734+
!incremental && (allow_ref_delta || allow_ofs_delta);
47214735
}
47224736

47234737
static int get_object_list_from_bitmap(struct rev_info *revs)
@@ -4739,7 +4753,8 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
47394753
&reuse_packfiles,
47404754
&reuse_packfiles_nr,
47414755
&reuse_packfile_bitmap,
4742-
allow_pack_reuse == MULTI_PACK_REUSE);
4756+
allow_pack_reuse == MULTI_PACK_REUSE,
4757+
allow_ref_delta);
47434758

47444759
if (reuse_packfiles) {
47454760
reuse_packfile_objects = bitmap_popcount(reuse_packfile_bitmap);
@@ -5170,6 +5185,8 @@ int cmd_pack_objects(int argc,
51705185
N_("reuse existing objects")),
51715186
OPT_BOOL(0, "delta-base-offset", &allow_ofs_delta,
51725187
N_("use OFS_DELTA objects")),
5188+
OPT_BOOL(0, "ref-delta", &allow_ref_delta,
5189+
N_("use REF_DELTA objects")),
51735190
OPT_INTEGER(0, "threads", &delta_search_threads,
51745191
N_("use threads when searching for best delta matches")),
51755192
OPT_BOOL(0, "non-empty", &non_empty,
@@ -5368,7 +5385,7 @@ int cmd_pack_objects(int argc,
53685385
if (unpack_unreachable || keep_unreachable || pack_loose_unreachable)
53695386
use_internal_rev_list = 1;
53705387

5371-
if (!reuse_object)
5388+
if (!reuse_object || (!allow_ref_delta && !allow_ofs_delta))
53725389
reuse_delta = 0;
53735390
if (cfg->pack_compression_level == -1)
53745391
cfg->pack_compression_level = Z_DEFAULT_COMPRESSION;

builtin/receive-pack.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static struct strbuf fsck_msg_types = STRBUF_INIT;
6565
static int receive_unpack_limit = -1;
6666
static int transfer_unpack_limit = -1;
6767
static int advertise_atomic_push = 1;
68+
static int advertise_no_ref_delta;
6869
static int advertise_push_options;
6970
static int advertise_sid;
7071
static int unpack_limit = 100;
@@ -287,6 +288,8 @@ static void show_ref(const char *path, const struct object_id *oid)
287288
strbuf_addstr(&cap, " atomic");
288289
if (prefer_ofs_delta)
289290
strbuf_addstr(&cap, " ofs-delta");
291+
if (advertise_no_ref_delta)
292+
strbuf_addstr(&cap, " no-ref-delta");
290293
if (push_cert_nonce)
291294
strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
292295
if (advertise_push_options)
@@ -2629,6 +2632,8 @@ int cmd_receive_pack(int argc,
26292632
OPT_HIDDEN_BOOL(0, "http-backend-info-refs", &advertise_refs, NULL),
26302633
OPT_ALIAS(0, "advertise-refs", "http-backend-info-refs"),
26312634
OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL),
2635+
OPT_HIDDEN_BOOL(0, "advertise-no-ref-delta-for-testing",
2636+
&advertise_no_ref_delta, NULL),
26322637
OPT_END()
26332638
};
26342639

0 commit comments

Comments
 (0)