upload-pack: send part of packfile response as uri
Teach upload-pack to send part of its packfile response as URIs. An administrator may configure a repository with one or more "uploadpack.blobpackfileuri" lines, each line containing an OID, a pack hash, and a URI. A client may configure fetch.uriprotocols to be a comma-separated list of protocols that it is willing to use to fetch additional packfiles - this list will be sent to the server. Whenever an object with one of those OIDs would appear in the packfile transmitted by upload-pack, the server may exclude that object, and instead send the URI. The client will then download the packs referred to by those URIs before performing the connectivity check. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
9da69a6539
commit
dd4b732df7
@ -117,6 +117,8 @@ static unsigned long window_memory_limit = 0;
|
||||
|
||||
static struct list_objects_filter_options filter_options;
|
||||
|
||||
static struct string_list uri_protocols = STRING_LIST_INIT_NODUP;
|
||||
|
||||
enum missing_action {
|
||||
MA_ERROR = 0, /* fail if any missing objects are encountered */
|
||||
MA_ALLOW_ANY, /* silently allow ALL missing objects */
|
||||
@ -125,6 +127,15 @@ enum missing_action {
|
||||
static enum missing_action arg_missing_action;
|
||||
static show_object_fn fn_show_object;
|
||||
|
||||
struct configured_exclusion {
|
||||
struct oidmap_entry e;
|
||||
char *pack_hash_hex;
|
||||
char *uri;
|
||||
};
|
||||
static struct oidmap configured_exclusions;
|
||||
|
||||
static struct oidset excluded_by_config;
|
||||
|
||||
/*
|
||||
* stats
|
||||
*/
|
||||
@ -969,6 +980,25 @@ static void write_reused_pack(struct hashfile *f)
|
||||
unuse_pack(&w_curs);
|
||||
}
|
||||
|
||||
static void write_excluded_by_configs(void)
|
||||
{
|
||||
struct oidset_iter iter;
|
||||
const struct object_id *oid;
|
||||
|
||||
oidset_iter_init(&excluded_by_config, &iter);
|
||||
while ((oid = oidset_iter_next(&iter))) {
|
||||
struct configured_exclusion *ex =
|
||||
oidmap_get(&configured_exclusions, oid);
|
||||
|
||||
if (!ex)
|
||||
BUG("configured exclusion wasn't configured");
|
||||
write_in_full(1, ex->pack_hash_hex, strlen(ex->pack_hash_hex));
|
||||
write_in_full(1, " ", 1);
|
||||
write_in_full(1, ex->uri, strlen(ex->uri));
|
||||
write_in_full(1, "\n", 1);
|
||||
}
|
||||
}
|
||||
|
||||
static const char no_split_warning[] = N_(
|
||||
"disabling bitmap writing, packs are split due to pack.packSizeLimit"
|
||||
);
|
||||
@ -1266,6 +1296,25 @@ static int want_object_in_pack(const struct object_id *oid,
|
||||
}
|
||||
}
|
||||
|
||||
if (uri_protocols.nr) {
|
||||
struct configured_exclusion *ex =
|
||||
oidmap_get(&configured_exclusions, oid);
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
if (ex) {
|
||||
for (i = 0; i < uri_protocols.nr; i++) {
|
||||
if (skip_prefix(ex->uri,
|
||||
uri_protocols.items[i].string,
|
||||
&p) &&
|
||||
*p == ':') {
|
||||
oidset_insert(&excluded_by_config, oid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2864,6 +2913,29 @@ static int git_pack_config(const char *k, const char *v, void *cb)
|
||||
pack_idx_opts.version);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "uploadpack.blobpackfileuri")) {
|
||||
struct configured_exclusion *ex = xmalloc(sizeof(*ex));
|
||||
const char *oid_end, *pack_end;
|
||||
/*
|
||||
* Stores the pack hash. This is not a true object ID, but is
|
||||
* of the same form.
|
||||
*/
|
||||
struct object_id pack_hash;
|
||||
|
||||
if (parse_oid_hex(v, &ex->e.oid, &oid_end) ||
|
||||
*oid_end != ' ' ||
|
||||
parse_oid_hex(oid_end + 1, &pack_hash, &pack_end) ||
|
||||
*pack_end != ' ')
|
||||
die(_("value of uploadpack.blobpackfileuri must be "
|
||||
"of the form '<object-hash> <pack-hash> <uri>' (got '%s')"), v);
|
||||
if (oidmap_get(&configured_exclusions, &ex->e.oid))
|
||||
die(_("object already configured in another "
|
||||
"uploadpack.blobpackfileuri (got '%s')"), v);
|
||||
ex->pack_hash_hex = xcalloc(1, pack_end - oid_end);
|
||||
memcpy(ex->pack_hash_hex, oid_end + 1, pack_end - oid_end - 1);
|
||||
ex->uri = xstrdup(pack_end + 1);
|
||||
oidmap_put(&configured_exclusions, ex);
|
||||
}
|
||||
return git_default_config(k, v, cb);
|
||||
}
|
||||
|
||||
@ -3462,6 +3534,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
N_("do not pack objects in promisor packfiles")),
|
||||
OPT_BOOL(0, "delta-islands", &use_delta_islands,
|
||||
N_("respect islands during delta compression")),
|
||||
OPT_STRING_LIST(0, "uri-protocol", &uri_protocols,
|
||||
N_("protocol"),
|
||||
N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
@ -3650,6 +3725,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
trace2_region_enter("pack-objects", "write-pack-file", the_repository);
|
||||
write_excluded_by_configs();
|
||||
write_pack_file();
|
||||
trace2_region_leave("pack-objects", "write-pack-file", the_repository);
|
||||
|
||||
|
Reference in New Issue
Block a user