Merge branch 'jt/cdn-offload'
The "fetch/clone" protocol has been updated to allow the server to instruct the clients to grab pre-packaged packfile(s) in addition to the packed object data coming over the wire. * jt/cdn-offload: upload-pack: fix a sparse '0 as NULL pointer' warning upload-pack: send part of packfile response as uri fetch-pack: support more than one pack lockfile upload-pack: refactor reading of pack-objects out Documentation: add Packfile URIs design doc Documentation: order protocol v2 sections http-fetch: support fetching packfiles by URL http-fetch: refactor into function http: refactor finish_http_pack_request() http: use --stdin when indexing dumb HTTP pack
This commit is contained in:
92
http.c
92
http.c
@ -2261,70 +2261,74 @@ void release_http_pack_request(struct http_pack_request *preq)
|
||||
|
||||
int finish_http_pack_request(struct http_pack_request *preq)
|
||||
{
|
||||
struct packed_git **lst;
|
||||
struct packed_git *p = preq->target;
|
||||
char *tmp_idx;
|
||||
size_t len;
|
||||
struct child_process ip = CHILD_PROCESS_INIT;
|
||||
|
||||
close_pack_index(p);
|
||||
int tmpfile_fd;
|
||||
int ret = 0;
|
||||
|
||||
fclose(preq->packfile);
|
||||
preq->packfile = NULL;
|
||||
|
||||
lst = preq->lst;
|
||||
tmpfile_fd = xopen(preq->tmpfile.buf, O_RDONLY);
|
||||
|
||||
argv_array_push(&ip.args, "index-pack");
|
||||
argv_array_push(&ip.args, "--stdin");
|
||||
ip.git_cmd = 1;
|
||||
ip.in = tmpfile_fd;
|
||||
if (preq->generate_keep) {
|
||||
argv_array_pushf(&ip.args, "--keep=git %"PRIuMAX,
|
||||
(uintmax_t)getpid());
|
||||
ip.out = 0;
|
||||
} else {
|
||||
ip.no_stdout = 1;
|
||||
}
|
||||
|
||||
if (run_command(&ip)) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
close(tmpfile_fd);
|
||||
unlink(preq->tmpfile.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void http_install_packfile(struct packed_git *p,
|
||||
struct packed_git **list_to_remove_from)
|
||||
{
|
||||
struct packed_git **lst = list_to_remove_from;
|
||||
|
||||
while (*lst != p)
|
||||
lst = &((*lst)->next);
|
||||
*lst = (*lst)->next;
|
||||
|
||||
if (!strip_suffix(preq->tmpfile.buf, ".pack.temp", &len))
|
||||
BUG("pack tmpfile does not end in .pack.temp?");
|
||||
tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile.buf);
|
||||
|
||||
argv_array_push(&ip.args, "index-pack");
|
||||
argv_array_pushl(&ip.args, "-o", tmp_idx, NULL);
|
||||
argv_array_push(&ip.args, preq->tmpfile.buf);
|
||||
ip.git_cmd = 1;
|
||||
ip.no_stdin = 1;
|
||||
ip.no_stdout = 1;
|
||||
|
||||
if (run_command(&ip)) {
|
||||
unlink(preq->tmpfile.buf);
|
||||
unlink(tmp_idx);
|
||||
free(tmp_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unlink(sha1_pack_index_name(p->hash));
|
||||
|
||||
if (finalize_object_file(preq->tmpfile.buf, sha1_pack_name(p->hash))
|
||||
|| finalize_object_file(tmp_idx, sha1_pack_index_name(p->hash))) {
|
||||
free(tmp_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
install_packed_git(the_repository, p);
|
||||
free(tmp_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct http_pack_request *new_http_pack_request(
|
||||
struct packed_git *target, const char *base_url)
|
||||
const unsigned char *packed_git_hash, const char *base_url) {
|
||||
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
end_url_with_slash(&buf, base_url);
|
||||
strbuf_addf(&buf, "objects/pack/pack-%s.pack",
|
||||
hash_to_hex(packed_git_hash));
|
||||
return new_direct_http_pack_request(packed_git_hash,
|
||||
strbuf_detach(&buf, NULL));
|
||||
}
|
||||
|
||||
struct http_pack_request *new_direct_http_pack_request(
|
||||
const unsigned char *packed_git_hash, char *url)
|
||||
{
|
||||
off_t prev_posn = 0;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct http_pack_request *preq;
|
||||
|
||||
preq = xcalloc(1, sizeof(*preq));
|
||||
strbuf_init(&preq->tmpfile, 0);
|
||||
preq->target = target;
|
||||
|
||||
end_url_with_slash(&buf, base_url);
|
||||
strbuf_addf(&buf, "objects/pack/pack-%s.pack",
|
||||
hash_to_hex(target->hash));
|
||||
preq->url = strbuf_detach(&buf, NULL);
|
||||
preq->url = url;
|
||||
|
||||
strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(target->hash));
|
||||
strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(packed_git_hash));
|
||||
preq->packfile = fopen(preq->tmpfile.buf, "a");
|
||||
if (!preq->packfile) {
|
||||
error("Unable to open local file %s for pack",
|
||||
@ -2348,7 +2352,7 @@ struct http_pack_request *new_http_pack_request(
|
||||
if (http_is_verbose)
|
||||
fprintf(stderr,
|
||||
"Resuming fetch of pack %s at byte %"PRIuMAX"\n",
|
||||
hash_to_hex(target->hash),
|
||||
hash_to_hex(packed_git_hash),
|
||||
(uintmax_t)prev_posn);
|
||||
http_opt_request_remainder(preq->slot->curl, prev_posn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user