mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 02:40:09 +00:00
remote: support fetch cancelation
Introduce git_remote_stop() which sets a variable that is checked by the fetch process in a few key places. If this is variable is set, the fetch is aborted.
This commit is contained in:
parent
4c47a8bcfe
commit
f0d2ddbbf8
@ -198,6 +198,14 @@ GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_in
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_remote_connected(git_remote *remote);
|
GIT_EXTERN(int) git_remote_connected(git_remote *remote);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the operation
|
||||||
|
*
|
||||||
|
* At certain points in its operation, the network code checks whether
|
||||||
|
* the operation has been cancelled and if so stops the operation.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(void) git_remote_stop(git_remote *remote);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect from the remote
|
* Disconnect from the remote
|
||||||
*
|
*
|
||||||
|
33
src/fetch.c
33
src/fetch.c
@ -152,7 +152,7 @@ int git_fetch_negotiate(git_remote *remote)
|
|||||||
gitno_buffer *buf = &t->buffer;
|
gitno_buffer *buf = &t->buffer;
|
||||||
git_buf data = GIT_BUF_INIT;
|
git_buf data = GIT_BUF_INIT;
|
||||||
git_revwalk *walk = NULL;
|
git_revwalk *walk = NULL;
|
||||||
int error, pkt_type;
|
int error = -1, pkt_type;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
|
|
||||||
@ -190,6 +190,12 @@ int git_fetch_negotiate(git_remote *remote)
|
|||||||
git_pkt_buffer_have(&oid, &data);
|
git_pkt_buffer_have(&oid, &data);
|
||||||
i++;
|
i++;
|
||||||
if (i % 20 == 0) {
|
if (i % 20 == 0) {
|
||||||
|
if (t->cancel.val) {
|
||||||
|
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
|
||||||
|
error = GIT_EUSER;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
git_pkt_buffer_flush(&data);
|
git_pkt_buffer_flush(&data);
|
||||||
if (git_buf_oom(&data))
|
if (git_buf_oom(&data))
|
||||||
goto on_error;
|
goto on_error;
|
||||||
@ -254,6 +260,11 @@ int git_fetch_negotiate(git_remote *remote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
git_pkt_buffer_done(&data);
|
git_pkt_buffer_done(&data);
|
||||||
|
if (t->cancel.val) {
|
||||||
|
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
|
||||||
|
error = GIT_EUSER;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
if (t->negotiation_step(t, data.ptr, data.size) < 0)
|
if (t->negotiation_step(t, data.ptr, data.size) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
@ -288,7 +299,7 @@ int git_fetch_negotiate(git_remote *remote)
|
|||||||
on_error:
|
on_error:
|
||||||
git_revwalk_free(walk);
|
git_revwalk_free(walk);
|
||||||
git_buf_free(&data);
|
git_buf_free(&data);
|
||||||
return -1;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats)
|
int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats)
|
||||||
@ -305,11 +316,16 @@ int git_fetch_download_pack(git_remote *remote, git_off_t *bytes, git_indexer_st
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int no_sideband(git_indexer_stream *idx, gitno_buffer *buf, git_off_t *bytes, git_indexer_stats *stats)
|
static int no_sideband(git_transport *t, git_indexer_stream *idx, gitno_buffer *buf, git_off_t *bytes, git_indexer_stats *stats)
|
||||||
{
|
{
|
||||||
int recvd;
|
int recvd;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (t->cancel.val) {
|
||||||
|
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
|
||||||
|
return GIT_EUSER;
|
||||||
|
}
|
||||||
|
|
||||||
if (git_indexer_stream_add(idx, buf->data, buf->offset, stats) < 0)
|
if (git_indexer_stream_add(idx, buf->data, buf->offset, stats) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -337,6 +353,7 @@ int git_fetch__download_pack(
|
|||||||
git_buf path = GIT_BUF_INIT;
|
git_buf path = GIT_BUF_INIT;
|
||||||
gitno_buffer *buf = &t->buffer;
|
gitno_buffer *buf = &t->buffer;
|
||||||
git_indexer_stream *idx = NULL;
|
git_indexer_stream *idx = NULL;
|
||||||
|
int error = -1;
|
||||||
|
|
||||||
if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0)
|
if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -354,7 +371,7 @@ int git_fetch__download_pack(
|
|||||||
* check which one belongs there.
|
* check which one belongs there.
|
||||||
*/
|
*/
|
||||||
if (!t->caps.side_band && !t->caps.side_band_64k) {
|
if (!t->caps.side_band && !t->caps.side_band_64k) {
|
||||||
if (no_sideband(idx, buf, bytes, stats) < 0)
|
if (no_sideband(t, idx, buf, bytes, stats) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
git_indexer_stream_free(idx);
|
git_indexer_stream_free(idx);
|
||||||
@ -362,6 +379,12 @@ int git_fetch__download_pack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (t->cancel.val) {
|
||||||
|
giterr_set(GITERR_NET, "The fetch was cancelled by the user");
|
||||||
|
error = GIT_EUSER;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
git_pkt *pkt;
|
git_pkt *pkt;
|
||||||
if (recv_pkt(&pkt, buf) < 0)
|
if (recv_pkt(&pkt, buf) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
@ -395,7 +418,7 @@ int git_fetch__download_pack(
|
|||||||
on_error:
|
on_error:
|
||||||
git_buf_free(&path);
|
git_buf_free(&path);
|
||||||
git_indexer_stream_free(idx);
|
git_indexer_stream_free(idx);
|
||||||
return -1;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_fetch_setup_walk(git_revwalk **out, git_repository *repo)
|
int git_fetch_setup_walk(git_revwalk **out, git_repository *repo)
|
||||||
|
@ -558,6 +558,11 @@ int git_remote_connected(git_remote *remote)
|
|||||||
return remote->transport == NULL ? 0 : remote->transport->connected;
|
return remote->transport == NULL ? 0 : remote->transport->connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void git_remote_stop(git_remote *remote)
|
||||||
|
{
|
||||||
|
git_atomic_set(&remote->transport->cancel, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void git_remote_disconnect(git_remote *remote)
|
void git_remote_disconnect(git_remote *remote)
|
||||||
{
|
{
|
||||||
assert(remote);
|
assert(remote);
|
||||||
|
@ -91,6 +91,8 @@ struct git_transport {
|
|||||||
GIT_SOCKET socket;
|
GIT_SOCKET socket;
|
||||||
git_transport_caps caps;
|
git_transport_caps caps;
|
||||||
void *cb_data;
|
void *cb_data;
|
||||||
|
git_atomic cancel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect and store the remote heads
|
* Connect and store the remote heads
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user