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

Fire progress and update tips callbacks also for pushes.
This commit is contained in:
Vicent Marti 2014-04-25 02:10:19 -07:00
commit 8443ed6c1d
20 changed files with 183 additions and 122 deletions

View File

@ -97,7 +97,7 @@ int fetch(git_repository *repo, int argc, char **argv)
// Set up the callbacks (only update_tips for now) // Set up the callbacks (only update_tips for now)
callbacks.update_tips = &update_cb; callbacks.update_tips = &update_cb;
callbacks.progress = &progress_cb; callbacks.sideband_progress = &progress_cb;
callbacks.credentials = cred_acquire_cb; callbacks.credentials = cred_acquire_cb;
git_remote_set_callbacks(remote, &callbacks); git_remote_set_callbacks(remote, &callbacks);

View File

@ -32,7 +32,7 @@ GIT_EXTERN(int) git_indexer_new(
const char *path, const char *path,
unsigned int mode, unsigned int mode,
git_odb *odb, git_odb *odb,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_cb_payload); void *progress_cb_payload);
/** /**

View File

@ -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_EXTERN(int) git_odb_write_pack(
git_odb_writepack **out, git_odb_writepack **out,
git_odb *db, git_odb *db,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload); void *progress_payload);
/** /**

View File

@ -140,7 +140,7 @@ GIT_EXTERN(int) git_packbuilder_write(
git_packbuilder *pb, git_packbuilder *pb,
const char *path, const char *path,
unsigned int mode, unsigned int mode,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_cb_payload); void *progress_cb_payload);
/** /**

View File

@ -457,7 +457,7 @@ struct git_remote_callbacks {
* progress side-band will be passed to this function (this is * progress side-band will be passed to this function (this is
* the 'counting objects' output. * 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 * 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 * Returning GIT_PASSTHROUGH will make libgit2 behave as
* though this field isn't set. * 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 * During the download of new data, this will be regularly
* called with the current count of progress done by the * called with the current count of progress done by the
* indexer. * 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 * Each time a reference is updated locally, this function

View File

@ -81,7 +81,7 @@ struct git_odb_backend {
int (* writepack)( int (* writepack)(
git_odb_writepack **, git_odb_backend *, git_odb *odb, 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 *); void (* free)(git_odb_backend *);
}; };

View File

@ -287,7 +287,7 @@ struct git_transport {
git_transport *transport, git_transport *transport,
git_repository *repo, git_repository *repo,
git_transfer_progress *stats, git_transfer_progress *stats,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload); void *progress_payload);
/* Checks to see if the transport is connected */ /* Checks to see if the transport is connected */

View File

@ -241,7 +241,7 @@ typedef struct git_transfer_progress {
* @param stats Structure containing information about the state of the transfer * @param stats Structure containing information about the state of the transfer
* @param payload Payload provided by caller * @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. * Opaque structure representing a submodule.

View File

@ -17,7 +17,7 @@ int git_fetch__download_pack(
git_transport *t, git_transport *t,
git_repository *repo, git_repository *repo,
git_transfer_progress *stats, git_transfer_progress *stats,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload); void *progress_payload);
int git_fetch_setup_walk(git_revwalk **out, git_repository *repo); int git_fetch_setup_walk(git_revwalk **out, git_repository *repo);

View File

@ -45,7 +45,7 @@ struct git_indexer {
unsigned int fanout[256]; unsigned int fanout[256];
git_hash_ctx hash_ctx; git_hash_ctx hash_ctx;
git_oid hash; git_oid hash;
git_transfer_progress_callback progress_cb; git_transfer_progress_cb progress_cb;
void *progress_payload; void *progress_payload;
char objbuf[8*1024]; char objbuf[8*1024];
@ -120,7 +120,7 @@ int git_indexer_new(
const char *prefix, const char *prefix,
unsigned int mode, unsigned int mode,
git_odb *odb, git_odb *odb,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload) void *progress_payload)
{ {
git_indexer *idx; git_indexer *idx;

View File

@ -1051,7 +1051,7 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
return error; 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; size_t i, writes = 0;
int error = GIT_ERROR; int error = GIT_ERROR;

View File

@ -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, static int pack_backend__writepack(struct git_odb_writepack **out,
git_odb_backend *_backend, git_odb_backend *_backend,
git_odb *odb, git_odb *odb,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload) void *progress_payload)
{ {
struct pack_backend *backend; struct pack_backend *backend;

View File

@ -1288,7 +1288,7 @@ int git_packbuilder_write(
git_packbuilder *pb, git_packbuilder *pb,
const char *path, const char *path,
unsigned int mode, unsigned int mode,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_cb_payload) void *progress_cb_payload)
{ {
git_indexer *indexer; git_indexer *indexer;

View File

@ -208,9 +208,7 @@ int git_push_update_tips(
int error = 0; int error = 0;
git_vector_foreach(&push->status, i, status) { git_vector_foreach(&push->status, i, status) {
/* If this ref update was successful (ok, not ng), it will have an empty message */ int fire_callback = 1;
if (status->msg)
continue;
/* Find the corresponding remote ref */ /* Find the corresponding remote ref */
fetch_spec = git_remote__matching_refspec(push->remote, status->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) if (j == push->specs.length)
continue; continue;
/* If this ref update was successful (ok, not ng), it will have an empty message */
if (status->msg == NULL) {
/* Update the remote ref */ /* Update the remote ref */
if (git_oid_iszero(&push_spec->loid)) { if (git_oid_iszero(&push_spec->loid)) {
error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name)); error = git_reference_lookup(&remote_ref, push->remote->repo, git_buf_cstr(&remote_ref_name));
if (!error) { if (error >= 0) {
if ((error = git_reference_delete(remote_ref)) < 0) { error = git_reference_delete(remote_ref);
git_reference_free(remote_ref); git_reference_free(remote_ref);
}
} 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;
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; goto on_error;
} }
git_reference_free(remote_ref);
} else if (error == GIT_ENOTFOUND)
giterr_clear();
else
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;
} }
error = 0; error = 0;
@ -677,9 +689,7 @@ void git_push_status_free(push_status *status)
if (status == NULL) if (status == NULL)
return; return;
if (status->msg)
git__free(status->msg); git__free(status->msg);
git__free(status->ref); git__free(status->ref);
git__free(status); git__free(status);
} }

View File

@ -663,7 +663,7 @@ int git_remote_connect(git_remote *remote, git_direction direction)
return error; return error;
if (t->set_callbacks && 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; goto on_error;
if (!remote->check_cert) 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) if (remote->transport && remote->transport->set_callbacks)
return remote->transport->set_callbacks(remote->transport, return remote->transport->set_callbacks(remote->transport,
remote->callbacks.progress, remote->callbacks.sideband_progress,
NULL, NULL,
remote->callbacks.payload); remote->callbacks.payload);

View File

@ -472,7 +472,7 @@ on_error:
typedef struct foreach_data { typedef struct foreach_data {
git_transfer_progress *stats; git_transfer_progress *stats;
git_transfer_progress_callback progress_cb; git_transfer_progress_cb progress_cb;
void *progress_payload; void *progress_payload;
git_odb_writepack *writepack; git_odb_writepack *writepack;
} foreach_data; } foreach_data;
@ -489,7 +489,7 @@ static int local_download_pack(
git_transport *transport, git_transport *transport,
git_repository *repo, git_repository *repo,
git_transfer_progress *stats, git_transfer_progress *stats,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload) void *progress_payload)
{ {
transport_local *t = (transport_local*)transport; transport_local *t = (transport_local*)transport;

View File

@ -167,7 +167,7 @@ int git_smart__download_pack(
git_transport *transport, git_transport *transport,
git_repository *repo, git_repository *repo,
git_transfer_progress *stats, git_transfer_progress *stats,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb progress_cb,
void *progress_payload); void *progress_payload);
/* smart.c */ /* smart.c */

View File

@ -153,7 +153,7 @@ static int data_pkt(git_pkt **out, const char *line, size_t len)
return 0; 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; git_pkt_progress *pkt;
@ -403,7 +403,7 @@ int git_pkt_parse_line(
if (*line == GIT_SIDE_BAND_DATA) if (*line == GIT_SIDE_BAND_DATA)
ret = data_pkt(head, line, len); ret = data_pkt(head, line, len);
else if (*line == GIT_SIDE_BAND_PROGRESS) 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) else if (*line == GIT_SIDE_BAND_ERROR)
ret = sideband_error_pkt(head, line, len); ret = sideband_error_pkt(head, line, len);
else if (!git__prefixcmp(line, "ACK")) else if (!git__prefixcmp(line, "ACK"))

View File

@ -450,7 +450,7 @@ static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack,
struct network_packetsize_payload struct network_packetsize_payload
{ {
git_transfer_progress_callback callback; git_transfer_progress_cb callback;
void *payload; void *payload;
git_transfer_progress *stats; git_transfer_progress *stats;
size_t last_fired_bytes; size_t last_fired_bytes;
@ -478,7 +478,7 @@ int git_smart__download_pack(
git_transport *transport, git_transport *transport,
git_repository *repo, git_repository *repo,
git_transfer_progress *stats, git_transfer_progress *stats,
git_transfer_progress_callback progress_cb, git_transfer_progress_cb transfer_progress_cb,
void *progress_payload) void *progress_payload)
{ {
transport_smart *t = (transport_smart *)transport; transport_smart *t = (transport_smart *)transport;
@ -490,8 +490,8 @@ int git_smart__download_pack(
memset(stats, 0, sizeof(git_transfer_progress)); memset(stats, 0, sizeof(git_transfer_progress));
if (progress_cb) { if (transfer_progress_cb) {
npp.callback = progress_cb; npp.callback = transfer_progress_cb;
npp.payload = progress_payload; npp.payload = progress_payload;
npp.stats = stats; npp.stats = stats;
t->packetsize_cb = &network_packetsize; t->packetsize_cb = &network_packetsize;
@ -504,7 +504,7 @@ int git_smart__download_pack(
} }
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 || 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; goto done;
/* /*
@ -518,7 +518,7 @@ int git_smart__download_pack(
} }
do { do {
git_pkt *pkt; git_pkt *pkt = NULL;
/* Check cancellation before network call */ /* Check cancellation before network call */
if (t->cancelled.val) { if (t->cancelled.val) {
@ -527,40 +527,34 @@ int git_smart__download_pack(
goto done; goto done;
} }
if ((error = recv_pkt(&pkt, buf)) < 0) if ((error = recv_pkt(&pkt, buf)) >= 0) {
goto done;
/* Check cancellation after network call */ /* Check cancellation after network call */
if (t->cancelled.val) { if (t->cancelled.val) {
giterr_clear(); giterr_clear();
error = GIT_EUSER; error = GIT_EUSER;
goto done; } else if (pkt->type == GIT_PKT_PROGRESS) {
}
if (pkt->type == GIT_PKT_PROGRESS) {
if (t->progress_cb) { if (t->progress_cb) {
git_pkt_progress *p = (git_pkt_progress *) pkt; git_pkt_progress *p = (git_pkt_progress *) pkt;
error = t->progress_cb(p->data, p->len, t->message_cb_payload); 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) { } else if (pkt->type == GIT_PKT_DATA) {
git_pkt_data *p = (git_pkt_data *) pkt; git_pkt_data *p = (git_pkt_data *) pkt;
error = writepack->append(writepack, p->data, p->len, stats); error = writepack->append(writepack, p->data, p->len, stats);
git__free(pkt);
if (error != 0)
goto done;
} else if (pkt->type == GIT_PKT_FLUSH) { } else if (pkt->type == GIT_PKT_FLUSH) {
/* A flush indicates the end of the packfile */ /* A flush indicates the end of the packfile */
git__free(pkt); git__free(pkt);
break; break;
} }
}
git__free(pkt);
if (error < 0)
goto done;
} while (1); } 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 * Only the callback through the npp datastructure currently
* updates the last_fired_bytes value. It is possible that * updates the last_fired_bytes value. It is possible that
* progress has already been reported with the correct * progress has already been reported with the correct
@ -579,7 +573,7 @@ int git_smart__download_pack(
done: done:
if (writepack) if (writepack)
writepack->free(writepack); writepack->free(writepack);
if (progress_cb) { if (transfer_progress_cb) {
t->packetsize_cb = NULL; t->packetsize_cb = NULL;
t->packetsize_payload = NULL; t->packetsize_payload = NULL;
} }
@ -634,7 +628,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
switch (pkt->type) { switch (pkt->type) {
case GIT_PKT_OK: case GIT_PKT_OK:
status = git__calloc(1, sizeof(push_status)); status = git__calloc(sizeof(push_status), 1);
GITERR_CHECK_ALLOC(status); GITERR_CHECK_ALLOC(status);
status->msg = NULL; status->msg = NULL;
status->ref = git__strdup(((git_pkt_ok *)pkt)->ref); 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; 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; git_pkt *pkt = NULL;
const char *line_end = NULL; const char *line_end = NULL;
gitno_buffer *buf = &transport->buffer;
int error, recvd; int error, recvd;
for (;;) { for (;;) {
@ -738,6 +733,10 @@ static int parse_report(gitno_buffer *buf, git_push *push)
error = -1; error = -1;
break; break;
case GIT_PKT_PROGRESS: 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; break;
default: default:
error = add_push_report_pkt(push, pkt); 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) { if ((current_time - payload->last_progress_report_time) >= MIN_PROGRESS_UPDATE_INTERVAL) {
payload->last_progress_report_time = current_time; payload->last_progress_report_time = current_time;
if (payload->cb(payload->pb->nr_written, payload->pb->nr_objects, payload->last_bytes, payload->cb_payload)) { error = payload->cb(payload->pb->nr_written, payload->pb->nr_objects, payload->last_bytes, payload->cb_payload);
giterr_clear();
error = GIT_EUSER;
}
} }
} }
@ -953,12 +949,19 @@ int git_smart__push(git_transport *transport, git_push *push)
* we consider the pack to have been unpacked successfully */ * we consider the pack to have been unpacked successfully */
if (!push->specs.length || !push->report_status) if (!push->specs.length || !push->report_status)
push->unpack_ok = 1; push->unpack_ok = 1;
else if ((error = parse_report(&t->buffer, push)) < 0) else if ((error = parse_report(t, push)) < 0)
goto done; goto done;
/* If progress is being reported write the final report */ /* If progress is being reported write the final report */
if (push->transfer_progress_cb) { 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) { if (push->status.length) {

View File

@ -254,7 +254,6 @@ static void verify_tracking_branches(git_remote *remote, expected_ref expected_r
} }
failed: failed:
if (failed) if (failed)
cl_fail(git_buf_cstr(&msg)); cl_fail(git_buf_cstr(&msg));
@ -264,7 +263,52 @@ failed:
git_vector_free(&actual_refs); git_vector_free(&actual_refs);
git_buf_free(&msg); git_buf_free(&msg);
git_buf_free(&ref_name); git_buf_free(&ref_name);
return; }
static void verify_update_tips_callback(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len)
{
git_refspec *fetch_spec;
git_buf msg = GIT_BUF_INIT;
git_buf ref_name = GIT_BUF_INIT;
updated_tip *tip = NULL;
size_t i, j;
int failed = 0;
for (i = 0; i < expected_refs_len; ++i) {
/* Convert remote reference name into tracking branch name.
* If the spec is not under refs/heads/, then skip.
*/
fetch_spec = git_remote__matching_refspec(remote, expected_refs[i].name);
if (!fetch_spec)
continue;
cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name));
/* Find matching update_tip entry */
git_vector_foreach(&_record_cbs_data.updated_tips, j, tip) {
if (!strcmp(git_buf_cstr(&ref_name), tip->name))
break;
}
if (j == _record_cbs_data.updated_tips.length) {
git_buf_printf(&msg, "Did not find expected updated tip entry for branch '%s'.", git_buf_cstr(&ref_name));
failed = 1;
goto failed;
}
if (git_oid_cmp(expected_refs[i].oid, tip->new_oid) != 0) {
git_buf_printf(&msg, "Updated tip ID does not match expected ID");
failed = 1;
goto failed;
}
}
failed:
if (failed)
cl_fail(git_buf_cstr(&msg));
git_buf_free(&ref_name);
git_buf_free(&msg);
} }
void test_online_push__initialize(void) void test_online_push__initialize(void)
@ -409,7 +453,7 @@ static void do_push(
const char *refspecs[], size_t refspecs_len, const char *refspecs[], size_t refspecs_len,
push_status expected_statuses[], size_t expected_statuses_len, push_status expected_statuses[], size_t expected_statuses_len,
expected_ref expected_refs[], size_t expected_refs_len, expected_ref expected_refs[], size_t expected_refs_len,
int expected_ret, int check_progress_cb) int expected_ret, int check_progress_cb, int check_update_tips_cb)
{ {
git_push *push; git_push *push;
git_push_options opts = GIT_PUSH_OPTIONS_INIT; git_push_options opts = GIT_PUSH_OPTIONS_INIT;
@ -461,6 +505,9 @@ static void do_push(
cl_git_pass(git_push_update_tips(push, pusher, "test push")); cl_git_pass(git_push_update_tips(push, pusher, "test push"));
verify_tracking_branches(_remote, expected_refs, expected_refs_len); verify_tracking_branches(_remote, expected_refs, expected_refs_len);
if (check_update_tips_cb)
verify_update_tips_callback(_remote, expected_refs, expected_refs_len);
git_push_free(push); git_push_free(push);
git_remote_disconnect(_remote); git_remote_disconnect(_remote);
@ -472,7 +519,7 @@ static void do_push(
/* Call push_finish() without ever calling git_push_add_refspec() */ /* Call push_finish() without ever calling git_push_add_refspec() */
void test_online_push__noop(void) void test_online_push__noop(void)
{ {
do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0); do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1);
} }
void test_online_push__b1(void) void test_online_push__b1(void)
@ -482,7 +529,7 @@ void test_online_push__b1(void)
expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } }; expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__b2(void) void test_online_push__b2(void)
@ -492,7 +539,7 @@ void test_online_push__b2(void)
expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } }; expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__b3(void) void test_online_push__b3(void)
@ -502,7 +549,7 @@ void test_online_push__b3(void)
expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } }; expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__b4(void) void test_online_push__b4(void)
@ -512,7 +559,7 @@ void test_online_push__b4(void)
expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } }; expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__b5(void) void test_online_push__b5(void)
@ -522,13 +569,13 @@ void test_online_push__b5(void)
expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } }; expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__b5_cancel(void) void test_online_push__b5_cancel(void)
{ {
const char *specs[] = { "refs/heads/b5:refs/heads/b5" }; const char *specs[] = { "refs/heads/b5:refs/heads/b5" };
do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1); do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1, 1);
} }
void test_online_push__multi(void) void test_online_push__multi(void)
@ -559,7 +606,7 @@ void test_online_push__multi(void)
}; };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1")); cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1"));
entry = git_reflog_entry_byindex(log, 0); entry = git_reflog_entry_byindex(log, 0);
@ -586,10 +633,10 @@ void test_online_push__implicit_tgt(void)
do_push(specs1, ARRAY_SIZE(specs1), do_push(specs1, ARRAY_SIZE(specs1),
exp_stats1, ARRAY_SIZE(exp_stats1), exp_stats1, ARRAY_SIZE(exp_stats1),
exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1); exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1);
do_push(specs2, ARRAY_SIZE(specs2), do_push(specs2, ARRAY_SIZE(specs2),
exp_stats2, ARRAY_SIZE(exp_stats2), exp_stats2, ARRAY_SIZE(exp_stats2),
exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0); exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0, 0);
} }
void test_online_push__fast_fwd(void) void test_online_push__fast_fwd(void)
@ -611,19 +658,19 @@ void test_online_push__fast_fwd(void)
do_push(specs_init, ARRAY_SIZE(specs_init), do_push(specs_init, ARRAY_SIZE(specs_init),
exp_stats_init, ARRAY_SIZE(exp_stats_init), exp_stats_init, ARRAY_SIZE(exp_stats_init),
exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1); exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1, 1);
do_push(specs_ff, ARRAY_SIZE(specs_ff), do_push(specs_ff, ARRAY_SIZE(specs_ff),
exp_stats_ff, ARRAY_SIZE(exp_stats_ff), exp_stats_ff, ARRAY_SIZE(exp_stats_ff),
exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0); exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0);
do_push(specs_reset, ARRAY_SIZE(specs_reset), do_push(specs_reset, ARRAY_SIZE(specs_reset),
exp_stats_init, ARRAY_SIZE(exp_stats_init), exp_stats_init, ARRAY_SIZE(exp_stats_init),
exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0); exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0, 0);
do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force), do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force),
exp_stats_ff, ARRAY_SIZE(exp_stats_ff), exp_stats_ff, ARRAY_SIZE(exp_stats_ff),
exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0); exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0);
} }
void test_online_push__tag_commit(void) void test_online_push__tag_commit(void)
@ -633,7 +680,7 @@ void test_online_push__tag_commit(void)
expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } }; expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__tag_tree(void) void test_online_push__tag_tree(void)
@ -643,7 +690,7 @@ void test_online_push__tag_tree(void)
expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } }; expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__tag_blob(void) void test_online_push__tag_blob(void)
@ -653,7 +700,7 @@ void test_online_push__tag_blob(void)
expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } }; expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__tag_lightweight(void) void test_online_push__tag_lightweight(void)
@ -663,7 +710,7 @@ void test_online_push__tag_lightweight(void)
expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } }; expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
} }
void test_online_push__tag_to_tag(void) void test_online_push__tag_to_tag(void)
@ -673,7 +720,7 @@ void test_online_push__tag_to_tag(void)
expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } }; expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } };
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 0); exp_refs, ARRAY_SIZE(exp_refs), 0, 0, 0);
} }
void test_online_push__force(void) void test_online_push__force(void)
@ -690,16 +737,17 @@ void test_online_push__force(void)
do_push(specs1, ARRAY_SIZE(specs1), do_push(specs1, ARRAY_SIZE(specs1),
exp_stats1, ARRAY_SIZE(exp_stats1), exp_stats1, ARRAY_SIZE(exp_stats1),
exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1); exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1);
do_push(specs2, ARRAY_SIZE(specs2), do_push(specs2, ARRAY_SIZE(specs2),
NULL, 0, NULL, 0,
exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0); exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0, 0);
/* Non-fast-forward update with force should pass. */ /* Non-fast-forward update with force should pass. */
record_callbacks_data_clear(&_record_cbs_data);
do_push(specs2_force, ARRAY_SIZE(specs2_force), do_push(specs2_force, ARRAY_SIZE(specs2_force),
exp_stats2_force, ARRAY_SIZE(exp_stats2_force), exp_stats2_force, ARRAY_SIZE(exp_stats2_force),
exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1); exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1, 1);
} }
void test_online_push__delete(void) void test_online_push__delete(void)
@ -730,7 +778,7 @@ void test_online_push__delete(void)
do_push(specs1, ARRAY_SIZE(specs1), do_push(specs1, ARRAY_SIZE(specs1),
exp_stats1, ARRAY_SIZE(exp_stats1), exp_stats1, ARRAY_SIZE(exp_stats1),
exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1); exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1);
/* When deleting a non-existent branch, the git client sends zero for both /* When deleting a non-existent branch, the git client sends zero for both
* the old and new commit id. This should succeed on the server with the * the old and new commit id. This should succeed on the server with the
@ -740,23 +788,23 @@ void test_online_push__delete(void)
*/ */
do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake), do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake),
exp_stats_fake, 1, exp_stats_fake, 1,
exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0); exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0);
do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force), do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force),
exp_stats_fake, 1, exp_stats_fake, 1,
exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0); exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0);
/* Delete one of the pushed branches. */ /* Delete one of the pushed branches. */
do_push(specs_delete, ARRAY_SIZE(specs_delete), do_push(specs_delete, ARRAY_SIZE(specs_delete),
exp_stats_delete, ARRAY_SIZE(exp_stats_delete), exp_stats_delete, ARRAY_SIZE(exp_stats_delete),
exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0); exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0);
/* Re-push branches and retry delete with force. */ /* Re-push branches and retry delete with force. */
do_push(specs1, ARRAY_SIZE(specs1), do_push(specs1, ARRAY_SIZE(specs1),
exp_stats1, ARRAY_SIZE(exp_stats1), exp_stats1, ARRAY_SIZE(exp_stats1),
exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0); exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0);
do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force), do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force),
exp_stats_delete, ARRAY_SIZE(exp_stats_delete), exp_stats_delete, ARRAY_SIZE(exp_stats_delete),
exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0); exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0);
} }
void test_online_push__bad_refspecs(void) void test_online_push__bad_refspecs(void)
@ -790,11 +838,11 @@ void test_online_push__expressions(void)
/* TODO: Find a more precise way of checking errors than a exit code of -1. */ /* TODO: Find a more precise way of checking errors than a exit code of -1. */
do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr), do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr),
NULL, 0, NULL, 0,
NULL, 0, -1, 0); NULL, 0, -1, 0, 0);
do_push(specs_right_expr, ARRAY_SIZE(specs_right_expr), do_push(specs_right_expr, ARRAY_SIZE(specs_right_expr),
exp_stats_right_expr, ARRAY_SIZE(exp_stats_right_expr), exp_stats_right_expr, ARRAY_SIZE(exp_stats_right_expr),
NULL, 0, 0, 1); NULL, 0, 0, 1, 1);
} }
void test_online_push__notes(void) void test_online_push__notes(void)
@ -814,7 +862,7 @@ void test_online_push__notes(void)
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0, 1); exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1);
git_signature_free(signature); git_signature_free(signature);
} }