Commit 48a65a07 by Carlos Martín Nieto Committed by Vicent Marti

Only wait for pack if we need it

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 <carlos@cmartin.tk>
parent 9cf0f287
...@@ -121,6 +121,20 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headarray *refs); ...@@ -121,6 +121,20 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headarray *refs);
GIT_EXTERN(int) git_remote_negotiate(git_remote *remote); 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 * Free the memory associated with a remote
* *
* @param remote the remote to free * @param remote the remote to free
......
...@@ -45,7 +45,7 @@ static int whn_cmp(const void *a, const void *b) ...@@ -45,7 +45,7 @@ static int whn_cmp(const void *a, const void *b)
return headb->type - heada->type; return headb->type - heada->type;
} }
int filter_wants(git_remote *remote) static int filter_wants(git_remote *remote)
{ {
git_vector list; git_vector list;
git_headarray refs; git_headarray refs;
...@@ -61,13 +61,13 @@ int filter_wants(git_remote *remote) ...@@ -61,13 +61,13 @@ int filter_wants(git_remote *remote)
error = git_transport_ls(t, &refs); error = git_transport_ls(t, &refs);
if (error < GIT_SUCCESS) { 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; goto cleanup;
} }
spec = git_remote_fetchspec(remote); spec = git_remote_fetchspec(remote);
if (spec == NULL) { 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; goto cleanup;
} }
...@@ -152,11 +152,11 @@ int git_fetch_negotiate(git_remote *remote) ...@@ -152,11 +152,11 @@ int git_fetch_negotiate(git_remote *remote)
/* Don't try to negotiate when we don't want anything */ /* Don't try to negotiate when we don't want anything */
if (list->len == 0) if (list->len == 0)
return GIT_SUCCESS; return GIT_SUCCESS;
/* /*
* Now we have everything set up so we can start tell the server * Now we have everything set up so we can start tell the server
* what we want and what we have. * what we want and what we have.
*/ */
remote->need_pack = 1;
git_transport_send_wants(remote->transport, list); git_transport_send_wants(remote->transport, list);
error = git_reference_listall(&refs, repo, GIT_REF_LISTALL); error = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
...@@ -201,5 +201,10 @@ cleanup: ...@@ -201,5 +201,10 @@ cleanup:
int git_fetch_download_pack(char **out, git_remote *remote) 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); return git_transport_download_pack(out, remote->transport, remote->repo);
} }
...@@ -208,6 +208,11 @@ int git_remote_negotiate(git_remote *remote) ...@@ -208,6 +208,11 @@ int git_remote_negotiate(git_remote *remote)
return git_fetch_negotiate(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) git_headarray *git_remote_tips(git_remote *remote)
{ {
return &remote->refs; return &remote->refs;
......
...@@ -13,6 +13,7 @@ struct git_remote { ...@@ -13,6 +13,7 @@ struct git_remote {
struct git_refspec push; struct git_refspec push;
git_transport *transport; git_transport *transport;
git_repository *repo; git_repository *repo;
int need_pack:1;
}; };
#endif #endif
...@@ -320,7 +320,10 @@ static int store_pack(char **out, gitno_buffer *buf, git_repository *repo) ...@@ -320,7 +320,10 @@ static int store_pack(char **out, gitno_buffer *buf, git_repository *repo)
goto cleanup; goto cleanup;
while (1) { while (1) {
if (buf->offset == 0) error = gitno_recv(buf);
if (error < GIT_SUCCESS)
goto cleanup;
if (error == 0) /* Orderly shutdown */
break; break;
error = git_filebuf_write(&file, buf->data, buf->offset); 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) ...@@ -331,12 +334,17 @@ static int store_pack(char **out, gitno_buffer *buf, git_repository *repo)
} }
*out = git__strdup(file.path_lock); *out = git__strdup(file.path_lock);
if (*out == NULL) if (*out == NULL) {
error = GIT_ENOMEM; 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: cleanup:
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
git_filebuf_cleanup(&file); git_filebuf_cleanup(&file);
return error; return error;
} }
...@@ -357,7 +365,7 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor ...@@ -357,7 +365,7 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor
error = gitno_recv(&buf); error = gitno_recv(&buf);
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return git__rethrow(GIT_EOSERR, "Failed to receive data"); return git__rethrow(GIT_EOSERR, "Failed to receive data");
if (error < GIT_SUCCESS) /* Orderly shutdown */ if (error == 0) /* Orderly shutdown */
return GIT_SUCCESS; return GIT_SUCCESS;
ptr = buf.data; ptr = buf.data;
...@@ -382,7 +390,6 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor ...@@ -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 * No we have the packet, let's just put anything we get now
* into a packfile * into a packfile
*/ */
return store_pack(out, &buf, repo); return store_pack(out, &buf, repo);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment