From 81c0fb08bd9185927722ffe0e851119500cb6ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 7 May 2015 13:28:51 +0200 Subject: local: add clarification for non-bare push restriction --- src/transports/local.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/transports/local.c b/src/transports/local.c index 305c71bf0..51e654025 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -398,7 +398,10 @@ static int local_push( /* We don't currently support pushing locally to non-bare repos. Proper non-bare repo push support would require checking configs to see if - we should override the default 'don't let this happen' behavior */ + we should override the default 'don't let this happen' behavior. + + Note that this is only an issue when pushing to the current branch, + but we forbid all pushes just in case */ if (!remote_repo->is_bare) { error = GIT_EBAREREPO; giterr_set(GITERR_INVALID, "Local push doesn't (yet) support pushing to non-bare repos."); -- cgit v1.2.1 From 4a5b781a48a5c4371b6b634d1161390c2d593812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 7 May 2015 13:44:28 +0200 Subject: local: use the packbuilder to push Instead of copying each object individually, as we'd been doing, use the packbuilder which should be faster and give us some feedback. While performing this change, we can hook up the packbuilder's writing to the push progress so the caller knows how far along we are. --- src/transports/local.c | 73 +++++++++++++------------------------------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/src/transports/local.c b/src/transports/local.c index 51e654025..bb9719c66 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -289,50 +289,6 @@ static int local_negotiate_fetch( return 0; } -static int local_push_copy_object( - git_odb *local_odb, - git_odb *remote_odb, - git_pobject *obj) -{ - int error = 0; - git_odb_object *odb_obj = NULL; - git_odb_stream *odb_stream; - size_t odb_obj_size; - git_otype odb_obj_type; - git_oid remote_odb_obj_oid; - - /* Object already exists in the remote ODB; do nothing and return 0*/ - if (git_odb_exists(remote_odb, &obj->id)) - return 0; - - if ((error = git_odb_read(&odb_obj, local_odb, &obj->id)) < 0) - return error; - - odb_obj_size = git_odb_object_size(odb_obj); - odb_obj_type = git_odb_object_type(odb_obj); - - if ((error = git_odb_open_wstream(&odb_stream, remote_odb, - odb_obj_size, odb_obj_type)) < 0) - goto on_error; - - if (git_odb_stream_write(odb_stream, (char *)git_odb_object_data(odb_obj), - odb_obj_size) < 0 || - git_odb_stream_finalize_write(&remote_odb_obj_oid, odb_stream) < 0) { - error = -1; - } else if (git_oid__cmp(&obj->id, &remote_odb_obj_oid) != 0) { - giterr_set(GITERR_ODB, "Error when writing object to remote odb " - "during local push operation. Remote odb object oid does not " - "match local oid."); - error = -1; - } - - git_odb_stream_free(odb_stream); - -on_error: - git_odb_object_free(odb_obj); - return error; -} - static int local_push_update_remote_ref( git_repository *remote_repo, const char *lref, @@ -363,21 +319,29 @@ static int local_push_update_remote_ref( return error; } +static int transfer_to_push_transfer(const git_transfer_progress *stats, void *payload) +{ + const git_remote_callbacks *cbs = payload; + + if (!cbs || !cbs->push_transfer_progress) + return 0; + + return cbs->push_transfer_progress(stats->received_objects, stats->total_objects, stats->received_bytes, + cbs->payload); +} + static int local_push( git_transport *transport, git_push *push, const git_remote_callbacks *cbs) { transport_local *t = (transport_local *)transport; - git_odb *remote_odb = NULL; - git_odb *local_odb = NULL; git_repository *remote_repo = NULL; push_spec *spec; char *url = NULL; const char *path; - git_buf buf = GIT_BUF_INIT; + git_buf buf = GIT_BUF_INIT, odb_path = GIT_BUF_INIT; int error; - unsigned int i; size_t j; GIT_UNUSED(cbs); @@ -408,15 +372,14 @@ static int local_push( goto on_error; } - if ((error = git_repository_odb__weakptr(&remote_odb, remote_repo)) < 0 || - (error = git_repository_odb__weakptr(&local_odb, push->repo)) < 0) + if ((error = git_buf_joinpath(&odb_path, git_repository_path(remote_repo), "objects/pack")) < 0) goto on_error; - for (i = 0; i < push->pb->nr_objects; i++) { - if ((error = local_push_copy_object(local_odb, remote_odb, - &push->pb->object_list[i])) < 0) - goto on_error; - } + error = git_packbuilder_write(push->pb, odb_path.ptr, 0, transfer_to_push_transfer, (void *) cbs); + git_buf_free(&odb_path); + + if (error < 0) + goto on_error; push->unpack_ok = 1; -- cgit v1.2.1 From 0bc3d56dde896483a65855adbeac016cf792f532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 7 May 2015 16:12:36 +0200 Subject: tests: don't push to our resources A couple of tests use the wrong remote to push to. We did not notice up to now because the local push would copy individual objects, and those already existed, so it became a no-op. Once we made local push create the packfile, it became noticeable that there was a new packfile where it didn't belong. --- tests/network/remote/local.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c index 21cb93c57..9d96184a2 100644 --- a/tests/network/remote/local.c +++ b/tests/network/remote/local.c @@ -217,7 +217,7 @@ void test_network_remote_local__push_to_bare_remote(void) cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL)); /* Try to push */ - cl_git_pass(git_remote_upload(remote, &push_array, NULL)); + cl_git_pass(git_remote_upload(localremote, &push_array, NULL)); /* Clean up */ git_remote_free(localremote); @@ -256,7 +256,7 @@ void test_network_remote_local__push_to_bare_remote_with_file_url(void) cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL)); /* Try to push */ - cl_git_pass(git_remote_upload(remote, &push_array, NULL)); + cl_git_pass(git_remote_upload(localremote, &push_array, NULL)); /* Clean up */ git_remote_free(localremote); -- cgit v1.2.1