Merge pull request #3103 from libgit2/cmn/local-push-message Use the packbuilder in local push
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
diff --git a/src/transports/local.c b/src/transports/local.c
index 9dd4486..3b031a5 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);
@@ -398,22 +362,24 @@ 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.");
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;
diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c
index 21cb93c..9d96184 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);