From 48a65a071d9d6689a0ebb7891a20e8dab5fd3cdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 4 Aug 2011 22:42:58 +0200 Subject: [PATCH] Only wait for pack if we need it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide the git_remote_download function to instruct the library to downlad the packfile and let the user know the temporary location. Signed-off-by: Carlos Martín Nieto --- include/git2/remote.h | 14 ++++++++++++++ src/fetch.c | 13 +++++++++---- src/remote.c | 5 +++++ src/remote.h | 1 + src/transport_git.c | 15 +++++++++++---- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/git2/remote.h b/include/git2/remote.h index 207fe271d..74b0a05c6 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -120,6 +120,20 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headarray *refs); */ GIT_EXTERN(int) git_remote_negotiate(git_remote *remote); +/** + * Download the packfile + * + * The packfile is downloaded with a temporary filename, as it's final + * name is not known yet. If there was no packfile needed (all the + * objects were available locally), filename will be NULL and the + * function will return success. + * + * @param remote the remote to download from + * @param filename where to store the temproray filename + * @return GIT_SUCCESS or an error code + */ +GIT_EXTERN(int) git_remote_download(char **filename, git_remote *remote); + /** * Free the memory associated with a remote * diff --git a/src/fetch.c b/src/fetch.c index 7e671b799..7abc196e4 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -45,7 +45,7 @@ static int whn_cmp(const void *a, const void *b) return headb->type - heada->type; } -int filter_wants(git_remote *remote) +static int filter_wants(git_remote *remote) { git_vector list; git_headarray refs; @@ -61,13 +61,13 @@ int filter_wants(git_remote *remote) error = git_transport_ls(t, &refs); if (error < GIT_SUCCESS) { - error = git__rethrow(error, "Failed to list local refs"); + error = git__rethrow(error, "Failed to get remote ref list"); goto cleanup; } spec = git_remote_fetchspec(remote); if (spec == NULL) { - error = git__throw(GIT_ERROR, "The remote has to fetchspec"); + error = git__throw(GIT_ERROR, "The remote has no fetchspec"); goto cleanup; } @@ -152,11 +152,11 @@ int git_fetch_negotiate(git_remote *remote) /* Don't try to negotiate when we don't want anything */ if (list->len == 0) return GIT_SUCCESS; - /* * Now we have everything set up so we can start tell the server * what we want and what we have. */ + remote->need_pack = 1; git_transport_send_wants(remote->transport, list); error = git_reference_listall(&refs, repo, GIT_REF_LISTALL); @@ -201,5 +201,10 @@ cleanup: int git_fetch_download_pack(char **out, git_remote *remote) { + if(!remote->need_pack) { + *out = NULL; + return GIT_SUCCESS; + } + return git_transport_download_pack(out, remote->transport, remote->repo); } diff --git a/src/remote.c b/src/remote.c index 07628d8d0..75f2dc700 100644 --- a/src/remote.c +++ b/src/remote.c @@ -208,6 +208,11 @@ int git_remote_negotiate(git_remote *remote) return git_fetch_negotiate(remote); } +int git_remote_download(char **filename, git_remote *remote) +{ + return git_fetch_download_pack(filename, remote); +} + git_headarray *git_remote_tips(git_remote *remote) { return &remote->refs; diff --git a/src/remote.h b/src/remote.h index f5686a29c..21313acd4 100644 --- a/src/remote.h +++ b/src/remote.h @@ -13,6 +13,7 @@ struct git_remote { struct git_refspec push; git_transport *transport; git_repository *repo; + int need_pack:1; }; #endif diff --git a/src/transport_git.c b/src/transport_git.c index 871c797c5..46678a28e 100644 --- a/src/transport_git.c +++ b/src/transport_git.c @@ -320,7 +320,10 @@ static int store_pack(char **out, gitno_buffer *buf, git_repository *repo) goto cleanup; while (1) { - if (buf->offset == 0) + error = gitno_recv(buf); + if (error < GIT_SUCCESS) + goto cleanup; + if (error == 0) /* Orderly shutdown */ break; error = git_filebuf_write(&file, buf->data, buf->offset); @@ -331,12 +334,17 @@ static int store_pack(char **out, gitno_buffer *buf, git_repository *repo) } *out = git__strdup(file.path_lock); - if (*out == NULL) + if (*out == NULL) { error = GIT_ENOMEM; + goto cleanup; + } + /* A bit dodgy, but we need to keep the pack at the temporary path */ + error = git_filebuf_commit_at(&file, file.path_lock); cleanup: if (error < GIT_SUCCESS) git_filebuf_cleanup(&file); + return error; } @@ -357,7 +365,7 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor error = gitno_recv(&buf); if (error < GIT_SUCCESS) return git__rethrow(GIT_EOSERR, "Failed to receive data"); - if (error < GIT_SUCCESS) /* Orderly shutdown */ + if (error == 0) /* Orderly shutdown */ return GIT_SUCCESS; ptr = buf.data; @@ -382,7 +390,6 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor * No we have the packet, let's just put anything we get now * into a packfile */ - return store_pack(out, &buf, repo); }