summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-05-07 13:44:28 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-05-13 10:56:37 +0200
commit4a5b781a48a5c4371b6b634d1161390c2d593812 (patch)
treea594ecfc66776ea6ff5e4d10f439c2c009b01af6
parent81c0fb08bd9185927722ffe0e851119500cb6ced (diff)
downloadlibgit2-4a5b781a48a5c4371b6b634d1161390c2d593812.tar.gz
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.
-rw-r--r--src/transports/local.c73
1 files 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;