diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fetch.c | 56 | ||||
-rw-r--r-- | src/fetch.h | 6 | ||||
-rw-r--r-- | src/remote.c | 6 | ||||
-rw-r--r-- | src/transport.h | 2 | ||||
-rw-r--r-- | src/transports/git.c | 4 | ||||
-rw-r--r-- | src/transports/http.c | 77 |
6 files changed, 65 insertions, 86 deletions
diff --git a/src/fetch.c b/src/fetch.c index 57a6d0265..8da4fd8cd 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -9,6 +9,7 @@ #include "git2/oid.h" #include "git2/refs.h" #include "git2/revwalk.h" +#include "git2/indexer.h" #include "common.h" #include "transport.h" @@ -101,30 +102,27 @@ int git_fetch_negotiate(git_remote *remote) return t->negotiate_fetch(t, remote->repo, &remote->refs); } -int git_fetch_download_pack(char **out, git_remote *remote) +int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats) { - if(!remote->need_pack) { - *out = NULL; + if(!remote->need_pack) return 0; - } - return remote->transport->download_pack(out, remote->transport, remote->repo); + return remote->transport->download_pack(remote->transport, remote->repo, bytes, stats); } /* Receiving data from a socket and storing it is pretty much the same for git and HTTP */ int git_fetch__download_pack( - char **out, const char *buffered, size_t buffered_size, GIT_SOCKET fd, - git_repository *repo) + git_repository *repo, + git_off_t *bytes, + git_indexer_stats *stats) { - git_filebuf file = GIT_FILEBUF_INIT; - int error; + int recvd; char buff[1024]; - git_buf path = GIT_BUF_INIT; - static const char suff[] = "/objects/pack/pack-received"; gitno_buffer buf; + git_indexer_stream *idx; gitno_buffer_setup(&buf, buff, sizeof(buff), fd); @@ -133,41 +131,33 @@ int git_fetch__download_pack( return -1; } - if (git_buf_joinpath(&path, repo->path_repository, suff) < 0) - goto on_error; + if (git_indexer_stream_new(&idx, git_repository_path(repo)) < 0) + return -1; - if (git_filebuf_open(&file, path.ptr, GIT_FILEBUF_TEMPORARY) < 0) + memset(stats, 0, sizeof(git_indexer_stats)); + if (git_indexer_stream_add(idx, buffered, buffered_size, stats) < 0) goto on_error; - /* Part of the packfile has been received, don't loose it */ - if (git_filebuf_write(&file, buffered, buffered_size) < 0) - goto on_error; + *bytes = buffered_size; - while (1) { - if (git_filebuf_write(&file, buf.data, buf.offset) < 0) + do { + if (git_indexer_stream_add(idx, buf.data, buf.offset, stats) < 0) goto on_error; gitno_consume_n(&buf, buf.offset); - error = gitno_recv(&buf); - if (error < GIT_SUCCESS) + if ((recvd = gitno_recv(&buf)) < 0) goto on_error; - if (error == 0) /* Orderly shutdown */ - break; - } - *out = git__strdup(file.path_lock); - if (*out == NULL) - goto on_error; + *bytes += recvd; + } while(recvd > 0); - /* A bit dodgy, but we need to keep the pack at the temporary path */ - if (git_filebuf_commit_at(&file, file.path_lock, GIT_PACK_FILE_MODE) < 0) + if (git_indexer_stream_finalize(idx, stats)) goto on_error; - git_buf_free(&path); - + git_indexer_stream_free(idx); return 0; + on_error: - git_buf_free(&path); - git_filebuf_cleanup(&file); + git_indexer_stream_free(idx); return -1; } diff --git a/src/fetch.h b/src/fetch.h index c1ab84034..03767be8d 100644 --- a/src/fetch.h +++ b/src/fetch.h @@ -10,9 +10,9 @@ #include "netops.h" int git_fetch_negotiate(git_remote *remote); -int git_fetch_download_pack(char **out, git_remote *remote); +int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats); -int git_fetch__download_pack(char **out, const char *buffered, size_t buffered_size, - GIT_SOCKET fd, git_repository *repo); +int git_fetch__download_pack(const char *buffered, size_t buffered_size, GIT_SOCKET fd, + git_repository *repo, git_off_t *bytes, git_indexer_stats *stats); #endif diff --git a/src/remote.c b/src/remote.c index b48a23339..bbb491dd8 100644 --- a/src/remote.c +++ b/src/remote.c @@ -297,16 +297,16 @@ int git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload) return remote->transport->ls(remote->transport, list_cb, payload); } -int git_remote_download(char **filename, git_remote *remote) +int git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats) { int error; - assert(filename && remote); + assert(remote && bytes && stats); if ((error = git_fetch_negotiate(remote)) < 0) return error; - return git_fetch_download_pack(filename, remote); + return git_fetch_download_pack(remote, bytes, stats); } int git_remote_update_tips(git_remote *remote) diff --git a/src/transport.h b/src/transport.h index 4c123571d..1cea32bee 100644 --- a/src/transport.h +++ b/src/transport.h @@ -81,7 +81,7 @@ struct git_transport { /** * Download the packfile */ - int (*download_pack)(char **out, struct git_transport *transport, git_repository *repo); + int (*download_pack)(struct git_transport *transport, git_repository *repo, git_off_t *bytes, git_indexer_stats *stats); /** * Fetch the changes */ diff --git a/src/transports/git.c b/src/transports/git.c index 825f072c8..62106de22 100644 --- a/src/transports/git.c +++ b/src/transports/git.c @@ -382,7 +382,7 @@ static int git_send_done(git_transport *transport) return git_pkt_send_done(t->socket); } -static int git_download_pack(char **out, git_transport *transport, git_repository *repo) +static int git_download_pack(git_transport *transport, git_repository *repo, git_off_t *bytes, git_indexer_stats *stats) { transport_git *t = (transport_git *) transport; int error = 0, read_bytes; @@ -410,7 +410,7 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor if (pkt->type == GIT_PKT_PACK) { git__free(pkt); - return git_fetch__download_pack(out, buf->data, buf->offset, t->socket, repo); + return git_fetch__download_pack(buf->data, buf->offset, t->socket, repo, bytes, stats); } /* For now we don't care about anything */ diff --git a/src/transports/http.c b/src/transports/http.c index 0938fefff..e6a709403 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -529,7 +529,8 @@ cleanup: } typedef struct { - git_filebuf *file; + git_indexer_stream *idx; + git_indexer_stats *stats; transport_http *transport; } download_pack_cbdata; @@ -545,10 +546,10 @@ static int on_body_download_pack(http_parser *parser, const char *str, size_t le { download_pack_cbdata *data = (download_pack_cbdata *) parser->data; transport_http *t = data->transport; - git_filebuf *file = data->file; + git_indexer_stream *idx = data->idx; + git_indexer_stats *stats = data->stats; - - return t->error = git_filebuf_write(file, str, len); + return t->error = git_indexer_stream_add(idx, str, len, stats); } /* @@ -557,80 +558,68 @@ static int on_body_download_pack(http_parser *parser, const char *str, size_t le * the simple downloader. Furthermore, we're using keep-alive * connections, so the simple downloader would just hang. */ -static int http_download_pack(char **out, git_transport *transport, git_repository *repo) +static int http_download_pack(git_transport *transport, git_repository *repo, git_off_t *bytes, git_indexer_stats *stats) { transport_http *t = (transport_http *) transport; git_buf *oldbuf = &t->buf; - int ret = 0; + int recvd; http_parser_settings settings; char buffer[1024]; gitno_buffer buf; + git_indexer_stream *idx = NULL; download_pack_cbdata data; - git_filebuf file = GIT_FILEBUF_INIT; - git_buf path = GIT_BUF_INIT; - char suff[] = "/objects/pack/pack-received\0"; + + gitno_buffer_setup(&buf, buffer, sizeof(buffer), t->socket); + + if (memcmp(oldbuf->ptr, "PACK", strlen("PACK"))) { + giterr_set(GITERR_NET, "The pack doesn't start with a pack signature"); + return -1; + } + + if (git_indexer_stream_new(&idx, git_repository_path(repo)) < 0) + return -1; + /* * This is part of the previous response, so we don't want to * re-init the parser, just set these two callbacks. */ - data.file = &file; + memset(stats, 0, sizeof(git_indexer_stats)); + data.stats = stats; + data.idx = idx; data.transport = t; t->parser.data = &data; t->transfer_finished = 0; memset(&settings, 0x0, sizeof(settings)); settings.on_message_complete = on_message_complete_download_pack; settings.on_body = on_body_download_pack; + *bytes = oldbuf->size; - gitno_buffer_setup(&buf, buffer, sizeof(buffer), t->socket); - - if (memcmp(oldbuf->ptr, "PACK", strlen("PACK"))) { - giterr_set(GITERR_NET, "The pack doesn't start with a pack signature"); - return -1; - } - - if (git_buf_joinpath(&path, repo->path_repository, suff) < 0) - goto on_error; - - if (git_filebuf_open(&file, path.ptr, GIT_FILEBUF_TEMPORARY) < 0) - goto on_error; - - /* Part of the packfile has been received, don't loose it */ - if (git_filebuf_write(&file, oldbuf->ptr, oldbuf->size) < 0) + if (git_indexer_stream_add(idx, oldbuf->ptr, oldbuf->size, stats) < 0) goto on_error; - while(1) { + do { size_t parsed; - ret = gitno_recv(&buf); - if (ret < 0) + if ((recvd = gitno_recv(&buf)) < 0) goto on_error; parsed = http_parser_execute(&t->parser, &settings, buf.data, buf.offset); - /* Both should happen at the same time */ if (parsed != buf.offset || t->error < 0) - return t->error; + goto on_error; + *bytes += recvd; gitno_consume_n(&buf, parsed); + } while (recvd > 0 && !t->transfer_finished); - if (ret == 0 || t->transfer_finished) { - break; - } - } - - *out = git__strdup(file.path_lock); - GITERR_CHECK_ALLOC(*out); - - /* A bit dodgy, but we need to keep the pack at the temporary path */ - ret = git_filebuf_commit_at(&file, file.path_lock, GIT_PACK_FILE_MODE); - - git_buf_free(&path); + if (git_indexer_stream_finalize(idx, stats) < 0) + goto on_error; + git_indexer_stream_free(idx); return 0; on_error: - git_filebuf_cleanup(&file); - git_buf_free(&path); + git_indexer_stream_free(idx); return -1; } |