From 3ded7f28c7bb1ad326fda82a6ea55ddb5dc7b8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 16 Dec 2014 10:05:49 +0100 Subject: [PATCH 1/2] local: add failing test for sideband information We do not currently generate any messages when we're counting the objects, as might be expected from a local upload-pack. Assert that we do call the function when working. --- tests/network/fetchlocal.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/network/fetchlocal.c b/tests/network/fetchlocal.c index 736261b31..b78253dc3 100644 --- a/tests/network/fetchlocal.c +++ b/tests/network/fetchlocal.c @@ -162,3 +162,37 @@ void test_network_fetchlocal__multi_remotes(void) git_remote_free(test); git_remote_free(test2); } + +static int sideband_cb(const char *str, int len, void *payload) +{ + int *count = (int *) payload; + + GIT_UNUSED(str); + GIT_UNUSED(len); + + (*count)++; + return 0; +} + +void test_network_fetchlocal__call_progress(void) +{ + git_repository *repo; + git_remote *remote; + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; + int callcount = 0; + + cl_git_pass(git_repository_init(&repo, "foo.git", true)); + cl_set_cleanup(cleanup_local_repo, "foo.git"); + + cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/heads/*")); + + callbacks.sideband_progress = sideband_cb; + callbacks.payload = &callcount; + cl_git_pass(git_remote_set_callbacks(remote, &callbacks)); + + cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); + cl_assert(callcount != 0); + + git_remote_free(remote); + git_repository_free(repo); +} From 4fd2bda9ff3130496c079cd0a7232ff5252a9842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 16 Dec 2014 10:25:45 +0100 Subject: [PATCH 2/2] local: send 'counting objects' output Pretend we have a git process at the other end by creating a similar progress output when inserting objects into the packbuilder. --- src/transports/local.c | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/transports/local.c b/src/transports/local.c index 3846f06d0..d698e0129 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -35,6 +35,9 @@ typedef struct { int flags; git_atomic cancelled; git_repository *repo; + git_transport_message_cb progress_cb; + git_transport_message_cb error_cb; + void *message_cb_payload; git_vector refs; unsigned connected : 1, have_refs : 1; @@ -494,6 +497,8 @@ static int foreach_cb(void *buf, size_t len, void *payload) return data->writepack->append(data->writepack, buf, len, data->stats); } +static const char *counting_objects_fmt = "Counting objects %d\r"; + static int local_download_pack( git_transport *transport, git_repository *repo, @@ -510,6 +515,7 @@ static int local_download_pack( git_packbuilder *pack = NULL; git_odb_writepack *writepack = NULL; git_odb *odb = NULL; + git_buf progress_info = GIT_BUF_INIT; if ((error = git_revwalk_new(&walk, t->repo)) < 0) goto cleanup; @@ -540,6 +546,13 @@ static int local_download_pack( git_object_free(obj); } + if ((error = git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack))) < 0) + goto cleanup; + + if (t->progress_cb && + (error = t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload)) < 0) + goto cleanup; + /* Walk the objects, building a packfile */ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) goto cleanup; @@ -561,9 +574,28 @@ static int local_download_pack( } git_commit_free(commit); + + git_buf_clear(&progress_info); + if ((error = git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack))) < 0) + goto cleanup; + + if (t->progress_cb && + (error = t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload)) < 0) + goto cleanup; + } } + /* One last one with the newline */ + git_buf_clear(&progress_info); + git_buf_printf(&progress_info, counting_objects_fmt, git_packbuilder_object_count(pack)); + if ((error = git_buf_putc(&progress_info, '\n')) < 0) + goto cleanup; + + if (t->progress_cb && + (error = t->progress_cb(git_buf_cstr(&progress_info), git_buf_len(&progress_info), t->message_cb_payload)) < 0) + goto cleanup; + if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0) goto cleanup; @@ -582,11 +614,30 @@ static int local_download_pack( cleanup: if (writepack) writepack->free(writepack); + git_buf_free(&progress_info); git_packbuilder_free(pack); git_revwalk_free(walk); return error; } +static int local_set_callbacks( + git_transport *transport, + git_transport_message_cb progress_cb, + git_transport_message_cb error_cb, + git_transport_certificate_check_cb certificate_check_cb, + void *message_cb_payload) +{ + transport_local *t = (transport_local *)transport; + + GIT_UNUSED(certificate_check_cb); + + t->progress_cb = progress_cb; + t->error_cb = error_cb; + t->message_cb_payload = message_cb_payload; + + return 0; +} + static int local_is_connected(git_transport *transport) { transport_local *t = (transport_local *)transport; @@ -656,6 +707,7 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param) GITERR_CHECK_ALLOC(t); t->parent.version = GIT_TRANSPORT_VERSION; + t->parent.set_callbacks = local_set_callbacks; t->parent.connect = local_connect; t->parent.negotiate_fetch = local_negotiate_fetch; t->parent.download_pack = local_download_pack;