Commit 8443ed6c by Vicent Marti

Merge pull request #2284 from jacquesg/push-progress-callback

Fire progress and update tips callbacks also for pushes.
parents 332e4f20 f70cfd34
......@@ -97,7 +97,7 @@ int fetch(git_repository *repo, int argc, char **argv)
// Set up the callbacks (only update_tips for now)
callbacks.update_tips = &update_cb;
callbacks.progress = &progress_cb;
callbacks.sideband_progress = &progress_cb;
callbacks.credentials = cred_acquire_cb;
git_remote_set_callbacks(remote, &callbacks);
......
......@@ -32,7 +32,7 @@ GIT_EXTERN(int) git_indexer_new(
const char *path,
unsigned int mode,
git_odb *odb,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_cb_payload);
/**
......
......@@ -338,7 +338,7 @@ GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const gi
GIT_EXTERN(int) git_odb_write_pack(
git_odb_writepack **out,
git_odb *db,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload);
/**
......
......@@ -140,7 +140,7 @@ GIT_EXTERN(int) git_packbuilder_write(
git_packbuilder *pb,
const char *path,
unsigned int mode,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_cb_payload);
/**
......
......@@ -457,7 +457,7 @@ struct git_remote_callbacks {
* progress side-band will be passed to this function (this is
* the 'counting objects' output.
*/
int (*progress)(const char *str, int len, void *data);
git_transport_message_cb sideband_progress;
/**
* Completion is called when different parts of the download
......@@ -472,14 +472,14 @@ struct git_remote_callbacks {
* Returning GIT_PASSTHROUGH will make libgit2 behave as
* though this field isn't set.
*/
int (*credentials)(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data);
git_cred_acquire_cb credentials;
/**
* During the download of new data, this will be regularly
* called with the current count of progress done by the
* indexer.
*/
int (*transfer_progress)(const git_transfer_progress *stats, void *data);
git_transfer_progress_cb transfer_progress;
/**
* Each time a reference is updated locally, this function
......
......@@ -81,7 +81,7 @@ struct git_odb_backend {
int (* writepack)(
git_odb_writepack **, git_odb_backend *, git_odb *odb,
git_transfer_progress_callback progress_cb, void *progress_payload);
git_transfer_progress_cb progress_cb, void *progress_payload);
void (* free)(git_odb_backend *);
};
......
......@@ -287,7 +287,7 @@ struct git_transport {
git_transport *transport,
git_repository *repo,
git_transfer_progress *stats,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload);
/* Checks to see if the transport is connected */
......
......@@ -241,7 +241,7 @@ typedef struct git_transfer_progress {
* @param stats Structure containing information about the state of the transfer
* @param payload Payload provided by caller
*/
typedef int (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload);
typedef int (*git_transfer_progress_cb)(const git_transfer_progress *stats, void *payload);
/**
* Opaque structure representing a submodule.
......
......@@ -17,7 +17,7 @@ int git_fetch__download_pack(
git_transport *t,
git_repository *repo,
git_transfer_progress *stats,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload);
int git_fetch_setup_walk(git_revwalk **out, git_repository *repo);
......
......@@ -45,7 +45,7 @@ struct git_indexer {
unsigned int fanout[256];
git_hash_ctx hash_ctx;
git_oid hash;
git_transfer_progress_callback progress_cb;
git_transfer_progress_cb progress_cb;
void *progress_payload;
char objbuf[8*1024];
......@@ -120,7 +120,7 @@ int git_indexer_new(
const char *prefix,
unsigned int mode,
git_odb *odb,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload)
{
git_indexer *idx;
......
......@@ -1051,7 +1051,7 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
return error;
}
int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_callback progress_cb, void *progress_payload)
int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_cb progress_cb, void *progress_payload)
{
size_t i, writes = 0;
int error = GIT_ERROR;
......
......@@ -563,7 +563,7 @@ static void pack_backend__writepack_free(struct git_odb_writepack *_writepack)
static int pack_backend__writepack(struct git_odb_writepack **out,
git_odb_backend *_backend,
git_odb *odb,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload)
{
struct pack_backend *backend;
......
......@@ -1288,7 +1288,7 @@ int git_packbuilder_write(
git_packbuilder *pb,
const char *path,
unsigned int mode,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_cb_payload)
{
git_indexer *indexer;
......
......@@ -208,9 +208,7 @@ int git_push_update_tips(
int error = 0;
git_vector_foreach(&push->status, i, status) {
/* If this ref update was successful (ok, not ng), it will have an empty message */
if (status->msg)
continue;
int fire_callback = 1;
/* Find the corresponding remote ref */
fetch_spec = git_remote__matching_refspec(push->remote, status->ref);
......@@ -230,24 +228,38 @@ int git_push_update_tips(
if (j == push->specs.length)
continue;
/* Update the remote ref */
if (git_oid_iszero(&push_spec->loid)) {
error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name));
/* If this ref update was successful (ok, not ng), it will have an empty message */
if (status->msg == NULL) {
/* Update the remote ref */
if (git_oid_iszero(&push_spec->loid)) {
error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name));
if (!error) {
if ((error = git_reference_delete(remote_ref)) < 0) {
if (error >= 0) {
error = git_reference_delete(remote_ref);
git_reference_free(remote_ref);
goto on_error;
}
git_reference_free(remote_ref);
} else if (error == GIT_ENOTFOUND)
giterr_clear();
else
} else {
error = git_reference_create(NULL, push->remote->repo,
git_buf_cstr(&remote_ref_name), &push_spec->loid, 1, signature,
reflog_message ? reflog_message : "update by push");
}
}
if (error < 0) {
if (error != GIT_ENOTFOUND)
goto on_error;
} else if ((error = git_reference_create(NULL, push->remote->repo,
git_buf_cstr(&remote_ref_name), &push_spec->loid, 1, signature,
reflog_message ? reflog_message : "update by push")) < 0)
goto on_error;
giterr_clear();
fire_callback = 0;
}
if (fire_callback && push->remote->callbacks.update_tips) {
error = push->remote->callbacks.update_tips(git_buf_cstr(&remote_ref_name),
&push_spec->roid, &push_spec->loid, push->remote->callbacks.payload);
if (error < 0)
goto on_error;
}
}
error = 0;
......@@ -677,9 +689,7 @@ void git_push_status_free(push_status *status)
if (status == NULL)
return;
if (status->msg)
git__free(status->msg);
git__free(status->msg);
git__free(status->ref);
git__free(status);
}
......
......@@ -663,7 +663,7 @@ int git_remote_connect(git_remote *remote, git_direction direction)
return error;
if (t->set_callbacks &&
(error = t->set_callbacks(t, remote->callbacks.progress, NULL, remote->callbacks.payload)) < 0)
(error = t->set_callbacks(t, remote->callbacks.sideband_progress, NULL, remote->callbacks.payload)) < 0)
goto on_error;
if (!remote->check_cert)
......@@ -1246,7 +1246,7 @@ int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *cal
if (remote->transport && remote->transport->set_callbacks)
return remote->transport->set_callbacks(remote->transport,
remote->callbacks.progress,
remote->callbacks.sideband_progress,
NULL,
remote->callbacks.payload);
......
......@@ -472,7 +472,7 @@ on_error:
typedef struct foreach_data {
git_transfer_progress *stats;
git_transfer_progress_callback progress_cb;
git_transfer_progress_cb progress_cb;
void *progress_payload;
git_odb_writepack *writepack;
} foreach_data;
......@@ -489,7 +489,7 @@ static int local_download_pack(
git_transport *transport,
git_repository *repo,
git_transfer_progress *stats,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload)
{
transport_local *t = (transport_local*)transport;
......
......@@ -167,7 +167,7 @@ int git_smart__download_pack(
git_transport *transport,
git_repository *repo,
git_transfer_progress *stats,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb progress_cb,
void *progress_payload);
/* smart.c */
......
......@@ -153,7 +153,7 @@ static int data_pkt(git_pkt **out, const char *line, size_t len)
return 0;
}
static int progress_pkt(git_pkt **out, const char *line, size_t len)
static int sideband_progress_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_progress *pkt;
......@@ -403,7 +403,7 @@ int git_pkt_parse_line(
if (*line == GIT_SIDE_BAND_DATA)
ret = data_pkt(head, line, len);
else if (*line == GIT_SIDE_BAND_PROGRESS)
ret = progress_pkt(head, line, len);
ret = sideband_progress_pkt(head, line, len);
else if (*line == GIT_SIDE_BAND_ERROR)
ret = sideband_error_pkt(head, line, len);
else if (!git__prefixcmp(line, "ACK"))
......
......@@ -450,7 +450,7 @@ static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack,
struct network_packetsize_payload
{
git_transfer_progress_callback callback;
git_transfer_progress_cb callback;
void *payload;
git_transfer_progress *stats;
size_t last_fired_bytes;
......@@ -478,7 +478,7 @@ int git_smart__download_pack(
git_transport *transport,
git_repository *repo,
git_transfer_progress *stats,
git_transfer_progress_callback progress_cb,
git_transfer_progress_cb transfer_progress_cb,
void *progress_payload)
{
transport_smart *t = (transport_smart *)transport;
......@@ -490,8 +490,8 @@ int git_smart__download_pack(
memset(stats, 0, sizeof(git_transfer_progress));
if (progress_cb) {
npp.callback = progress_cb;
if (transfer_progress_cb) {
npp.callback = transfer_progress_cb;
npp.payload = progress_payload;
npp.stats = stats;
t->packetsize_cb = &network_packetsize;
......@@ -504,7 +504,7 @@ int git_smart__download_pack(
}
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0))
((error = git_odb_write_pack(&writepack, odb, transfer_progress_cb, progress_payload)) != 0))
goto done;
/*
......@@ -518,7 +518,7 @@ int git_smart__download_pack(
}
do {
git_pkt *pkt;
git_pkt *pkt = NULL;
/* Check cancellation before network call */
if (t->cancelled.val) {
......@@ -527,40 +527,34 @@ int git_smart__download_pack(
goto done;
}
if ((error = recv_pkt(&pkt, buf)) < 0)
goto done;
/* Check cancellation after network call */
if (t->cancelled.val) {
giterr_clear();
error = GIT_EUSER;
goto done;
if ((error = recv_pkt(&pkt, buf)) >= 0) {
/* Check cancellation after network call */
if (t->cancelled.val) {
giterr_clear();
error = GIT_EUSER;
} else if (pkt->type == GIT_PKT_PROGRESS) {
if (t->progress_cb) {
git_pkt_progress *p = (git_pkt_progress *) pkt;
error = t->progress_cb(p->data, p->len, t->message_cb_payload);
}
} else if (pkt->type == GIT_PKT_DATA) {
git_pkt_data *p = (git_pkt_data *) pkt;
error = writepack->append(writepack, p->data, p->len, stats);
} else if (pkt->type == GIT_PKT_FLUSH) {
/* A flush indicates the end of the packfile */
git__free(pkt);
break;
}
}
if (pkt->type == GIT_PKT_PROGRESS) {
if (t->progress_cb) {
git_pkt_progress *p = (git_pkt_progress *) pkt;
error = t->progress_cb(p->data, p->len, t->message_cb_payload);
if (error)
goto done;
}
git__free(pkt);
} else if (pkt->type == GIT_PKT_DATA) {
git_pkt_data *p = (git_pkt_data *) pkt;
error = writepack->append(writepack, p->data, p->len, stats);
git__free(pkt);
if (error < 0)
goto done;
git__free(pkt);
if (error != 0)
goto done;
} else if (pkt->type == GIT_PKT_FLUSH) {
/* A flush indicates the end of the packfile */
git__free(pkt);
break;
}
} while (1);
/*
* Trailing execution of progress_cb, if necessary...
* Trailing execution of transfer_progress_cb, if necessary...
* Only the callback through the npp datastructure currently
* updates the last_fired_bytes value. It is possible that
* progress has already been reported with the correct
......@@ -579,7 +573,7 @@ int git_smart__download_pack(
done:
if (writepack)
writepack->free(writepack);
if (progress_cb) {
if (transfer_progress_cb) {
t->packetsize_cb = NULL;
t->packetsize_payload = NULL;
}
......@@ -634,7 +628,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
switch (pkt->type) {
case GIT_PKT_OK:
status = git__calloc(1, sizeof(push_status));
status = git__calloc(sizeof(push_status), 1);
GITERR_CHECK_ALLOC(status);
status->msg = NULL;
status->ref = git__strdup(((git_pkt_ok *)pkt)->ref);
......@@ -696,10 +690,11 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
return 0;
}
static int parse_report(gitno_buffer *buf, git_push *push)
static int parse_report(transport_smart *transport, git_push *push)
{
git_pkt *pkt = NULL;
const char *line_end = NULL;
gitno_buffer *buf = &transport->buffer;
int error, recvd;
for (;;) {
......@@ -738,6 +733,10 @@ static int parse_report(gitno_buffer *buf, git_push *push)
error = -1;
break;
case GIT_PKT_PROGRESS:
if (transport->progress_cb) {
git_pkt_progress *p = (git_pkt_progress *) pkt;
error = transport->progress_cb(p->data, p->len, transport->message_cb_payload);
}
break;
default:
error = add_push_report_pkt(push, pkt);
......@@ -883,10 +882,7 @@ static int stream_thunk(void *buf, size_t size, void *data)
if ((current_time - payload->last_progress_report_time) >= MIN_PROGRESS_UPDATE_INTERVAL) {
payload->last_progress_report_time = current_time;
if (payload->cb(payload->pb->nr_written, payload->pb->nr_objects, payload->last_bytes, payload->cb_payload)) {
giterr_clear();
error = GIT_EUSER;
}
error = payload->cb(payload->pb->nr_written, payload->pb->nr_objects, payload->last_bytes, payload->cb_payload);
}
}
......@@ -953,12 +949,19 @@ int git_smart__push(git_transport *transport, git_push *push)
* we consider the pack to have been unpacked successfully */
if (!push->specs.length || !push->report_status)
push->unpack_ok = 1;
else if ((error = parse_report(&t->buffer, push)) < 0)
else if ((error = parse_report(t, push)) < 0)
goto done;
/* If progress is being reported write the final report */
if (push->transfer_progress_cb) {
push->transfer_progress_cb(push->pb->nr_written, push->pb->nr_objects, packbuilder_payload.last_bytes, push->transfer_progress_cb_payload);
error = push->transfer_progress_cb(
push->pb->nr_written,
push->pb->nr_objects,
packbuilder_payload.last_bytes,
push->transfer_progress_cb_payload);
if (error < 0)
goto done;
}
if (push->status.length) {
......
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