]> git.proxmox.com Git - libgit2.git/commitdiff
local: use the packbuilder to push
authorCarlos Martín Nieto <cmn@dwim.me>
Thu, 7 May 2015 11:44:28 +0000 (13:44 +0200)
committerCarlos Martín Nieto <cmn@dwim.me>
Wed, 13 May 2015 08:56:37 +0000 (10:56 +0200)
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

index 51e65402596498db0f1c619cdc97c71ee454d71e..bb9719c66e4516e4f9c499940467b28ed6b6db29 100644 (file)
@@ -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;