http: refactor finish_http_pack_request()

finish_http_pack_request() does multiple tasks, including some
housekeeping on a struct packed_git - (1) closing its index, (2)
removing it from a list, and (3) installing it. These concerns are
independent of fetching a pack through HTTP: they are there only because
(1) the calling code opens the pack's index before deciding to fetch it,
(2) the calling code maintains a list of packfiles that can be fetched,
and (3) the calling code fetches it in order to make use of its objects
in the same process.

In preparation for a subsequent commit, which adds a feature that does
not need any of this housekeeping, remove (1), (2), and (3) from
finish_http_pack_request(). (2) and (3) are now done by a helper
function, and (1) is the responsibility of the caller (in this patch,
done closer to the point where the pack index is opened).

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jonathan Tan 2020-06-10 13:57:16 -07:00 committed by Junio C Hamano
parent 9cb3cab560
commit eb05349247
4 changed files with 35 additions and 22 deletions

View File

@ -117,6 +117,7 @@ enum transfer_state {
struct transfer_request { struct transfer_request {
struct object *obj; struct object *obj;
struct packed_git *target;
char *url; char *url;
char *dest; char *dest;
struct remote_lock *lock; struct remote_lock *lock;
@ -314,17 +315,18 @@ static void start_fetch_packed(struct transfer_request *request)
release_request(request); release_request(request);
return; return;
} }
close_pack_index(target);
request->target = target;
fprintf(stderr, "Fetching pack %s\n", fprintf(stderr, "Fetching pack %s\n",
hash_to_hex(target->hash)); hash_to_hex(target->hash));
fprintf(stderr, " which contains %s\n", oid_to_hex(&request->obj->oid)); fprintf(stderr, " which contains %s\n", oid_to_hex(&request->obj->oid));
preq = new_http_pack_request(target, repo->url); preq = new_http_pack_request(target->hash, repo->url);
if (preq == NULL) { if (preq == NULL) {
repo->can_update_info_refs = 0; repo->can_update_info_refs = 0;
return; return;
} }
preq->lst = &repo->packs;
/* Make sure there isn't another open request for this pack */ /* Make sure there isn't another open request for this pack */
while (check_request) { while (check_request) {
@ -597,6 +599,8 @@ static void finish_request(struct transfer_request *request)
} }
if (fail) if (fail)
repo->can_update_info_refs = 0; repo->can_update_info_refs = 0;
else
http_install_packfile(request->target, &repo->packs);
release_request(request); release_request(request);
} }
} }

View File

@ -439,6 +439,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne
target = find_sha1_pack(sha1, repo->packs); target = find_sha1_pack(sha1, repo->packs);
if (!target) if (!target)
return -1; return -1;
close_pack_index(target);
if (walker->get_verbosely) { if (walker->get_verbosely) {
fprintf(stderr, "Getting pack %s\n", fprintf(stderr, "Getting pack %s\n",
@ -447,10 +448,9 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne
hash_to_hex(sha1)); hash_to_hex(sha1));
} }
preq = new_http_pack_request(target, repo->base); preq = new_http_pack_request(target->hash, repo->base);
if (preq == NULL) if (preq == NULL)
goto abort; goto abort;
preq->lst = &repo->packs;
preq->slot->results = &results; preq->slot->results = &results;
if (start_active_slot(preq->slot)) { if (start_active_slot(preq->slot)) {
@ -469,6 +469,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne
release_http_pack_request(preq); release_http_pack_request(preq);
if (ret) if (ret)
return ret; return ret;
http_install_packfile(target, &repo->packs);
return 0; return 0;

31
http.c
View File

@ -2268,22 +2268,13 @@ void release_http_pack_request(struct http_pack_request *preq)
int finish_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;
struct child_process ip = CHILD_PROCESS_INIT; struct child_process ip = CHILD_PROCESS_INIT;
int tmpfile_fd; int tmpfile_fd;
int ret = 0; int ret = 0;
close_pack_index(p);
fclose(preq->packfile); fclose(preq->packfile);
preq->packfile = NULL; preq->packfile = NULL;
lst = preq->lst;
while (*lst != p)
lst = &((*lst)->next);
*lst = (*lst)->next;
tmpfile_fd = xopen(preq->tmpfile.buf, O_RDONLY); tmpfile_fd = xopen(preq->tmpfile.buf, O_RDONLY);
argv_array_push(&ip.args, "index-pack"); argv_array_push(&ip.args, "index-pack");
@ -2297,15 +2288,26 @@ int finish_http_pack_request(struct http_pack_request *preq)
goto cleanup; goto cleanup;
} }
install_packed_git(the_repository, p);
cleanup: cleanup:
close(tmpfile_fd); close(tmpfile_fd);
unlink(preq->tmpfile.buf); unlink(preq->tmpfile.buf);
return ret; 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;
install_packed_git(the_repository, p);
}
struct http_pack_request *new_http_pack_request( 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)
{ {
off_t prev_posn = 0; off_t prev_posn = 0;
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
@ -2313,14 +2315,13 @@ struct http_pack_request *new_http_pack_request(
preq = xcalloc(1, sizeof(*preq)); preq = xcalloc(1, sizeof(*preq));
strbuf_init(&preq->tmpfile, 0); strbuf_init(&preq->tmpfile, 0);
preq->target = target;
end_url_with_slash(&buf, base_url); end_url_with_slash(&buf, base_url);
strbuf_addf(&buf, "objects/pack/pack-%s.pack", strbuf_addf(&buf, "objects/pack/pack-%s.pack",
hash_to_hex(target->hash)); hash_to_hex(packed_git_hash));
preq->url = strbuf_detach(&buf, NULL); preq->url = strbuf_detach(&buf, NULL);
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"); preq->packfile = fopen(preq->tmpfile.buf, "a");
if (!preq->packfile) { if (!preq->packfile) {
error("Unable to open local file %s for pack", error("Unable to open local file %s for pack",
@ -2344,7 +2345,7 @@ struct http_pack_request *new_http_pack_request(
if (http_is_verbose) if (http_is_verbose)
fprintf(stderr, fprintf(stderr,
"Resuming fetch of pack %s at byte %"PRIuMAX"\n", "Resuming fetch of pack %s at byte %"PRIuMAX"\n",
hash_to_hex(target->hash), hash_to_hex(packed_git_hash),
(uintmax_t)prev_posn); (uintmax_t)prev_posn);
http_opt_request_remainder(preq->slot->curl, prev_posn); http_opt_request_remainder(preq->slot->curl, prev_posn);
} }

13
http.h
View File

@ -216,18 +216,25 @@ int http_get_info_packs(const char *base_url,
struct http_pack_request { struct http_pack_request {
char *url; char *url;
struct packed_git *target;
struct packed_git **lst;
FILE *packfile; FILE *packfile;
struct strbuf tmpfile; struct strbuf tmpfile;
struct active_request_slot *slot; struct active_request_slot *slot;
}; };
struct http_pack_request *new_http_pack_request( 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);
int finish_http_pack_request(struct http_pack_request *preq); int finish_http_pack_request(struct http_pack_request *preq);
void release_http_pack_request(struct http_pack_request *preq); void release_http_pack_request(struct http_pack_request *preq);
/*
* Remove p from the given list, and invoke install_packed_git() on it.
*
* This is a convenience function for users that have obtained a list of packs
* from http_get_info_packs() and have chosen a specific pack to fetch.
*/
void http_install_packfile(struct packed_git *p,
struct packed_git **list_to_remove_from);
/* Helpers for fetching object */ /* Helpers for fetching object */
struct http_object_request { struct http_object_request {
char *url; char *url;