summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/push.h32
-rw-r--r--src/pack-objects.c7
-rw-r--r--src/push.c21
-rw-r--r--src/push.h3
-rw-r--r--tests-clar/online/push.c5
5 files changed, 66 insertions, 2 deletions
diff --git a/include/git2/push.h b/include/git2/push.h
index 6e07f368e..8caf9a4ed 100644
--- a/include/git2/push.h
+++ b/include/git2/push.h
@@ -19,6 +19,26 @@
GIT_BEGIN_DECL
/**
+ * Controls the behavior of a git_push object.
+ */
+typedef struct {
+ unsigned int version;
+
+ /**
+ * If the transport being used to push to the remote requires the creation
+ * of a pack file, this controls the number of worker threads used by
+ * the packbuilder when creating that pack file to be sent to the remote.
+ *
+ * If set to 0, the packbuilder will auto-detect the number of threads
+ * to create. The default value is 1.
+ */
+ unsigned int pb_parallelism;
+} git_push_options;
+
+#define GIT_PUSH_OPTIONS_VERSION 1
+#define GIT_PUSH_OPTIONS_INIT { GIT_PUSH_OPTIONS_VERSION }
+
+/**
* Create a new push object
*
* @param out New push object
@@ -29,6 +49,18 @@ GIT_BEGIN_DECL
GIT_EXTERN(int) git_push_new(git_push **out, git_remote *remote);
/**
+ * Set options on a push object
+ *
+ * @param push The push object
+ * @param opts The options to set on the push object
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_push_set_options(
+ git_push *push,
+ const git_push_options *opts);
+
+/**
* Add a refspec to be pushed
*
* @param push The push object
diff --git a/src/pack-objects.c b/src/pack-objects.c
index a76f8a111..e4b67192d 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -144,7 +144,14 @@ on_error:
unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n)
{
assert(pb);
+
+#ifdef GIT_THREADS
pb->nr_threads = n;
+#else
+ GIT_UNUSED(n);
+ assert(1 == pb->nr_threads);
+#endif
+
return pb->nr_threads;
}
diff --git a/src/push.c b/src/push.c
index 64aaead6e..628df7ac4 100644
--- a/src/push.c
+++ b/src/push.c
@@ -40,6 +40,7 @@ int git_push_new(git_push **out, git_remote *remote)
p->repo = remote->repo;
p->remote = remote;
p->report_status = 1;
+ p->pb_parallelism = 1;
if (git_vector_init(&p->specs, 0, push_spec_rref_cmp) < 0) {
git__free(p);
@@ -56,6 +57,18 @@ int git_push_new(git_push **out, git_remote *remote)
return 0;
}
+int git_push_set_options(git_push *push, const git_push_options *opts)
+{
+ if (!push || !opts)
+ return -1;
+
+ GITERR_CHECK_VERSION(opts, GIT_PUSH_OPTIONS_VERSION, "git_push_options");
+
+ push->pb_parallelism = opts->pb_parallelism;
+
+ return 0;
+}
+
static void free_refspec(push_spec *spec)
{
if (spec == NULL)
@@ -449,8 +462,12 @@ static int do_push(git_push *push)
* objects. In this case the client MUST send an empty pack-file.
*/
- if ((error = git_packbuilder_new(&push->pb, push->repo)) < 0 ||
- (error = calculate_work(push)) < 0 ||
+ if ((error = git_packbuilder_new(&push->pb, push->repo)) < 0)
+ goto on_error;
+
+ git_packbuilder_set_threads(push->pb, push->pb_parallelism);
+
+ if ((error = calculate_work(push)) < 0 ||
(error = queue_objects(push)) < 0 ||
(error = transport->push(transport, push)) < 0)
goto on_error;
diff --git a/src/push.h b/src/push.h
index 0ac8ef947..629583189 100644
--- a/src/push.h
+++ b/src/push.h
@@ -36,6 +36,9 @@ struct git_push {
/* report-status */
bool unpack_ok;
git_vector status;
+
+ /* options */
+ unsigned pb_parallelism;
};
#endif
diff --git a/tests-clar/online/push.c b/tests-clar/online/push.c
index 56183473a..907d6d29f 100644
--- a/tests-clar/online/push.c
+++ b/tests-clar/online/push.c
@@ -349,13 +349,18 @@ static void do_push(const char *refspecs[], size_t refspecs_len,
expected_ref expected_refs[], size_t expected_refs_len, int expected_ret)
{
git_push *push;
+ git_push_options opts = GIT_PUSH_OPTIONS_INIT;
size_t i;
int ret;
if (_remote) {
+ /* Auto-detect the number of threads to use */
+ opts.pb_parallelism = 0;
+
cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH));
cl_git_pass(git_push_new(&push, _remote));
+ cl_git_pass(git_push_set_options(push, &opts));
for (i = 0; i < refspecs_len; i++)
cl_git_pass(git_push_add_refspec(push, refspecs[i]));