Commit 6a0ffe84 by Ben Straub

Merge pull request #1333 from phkelley/push_options

Add git_push_options, to set packbuilder parallelism
parents fbe67de9 b8b897bb
...@@ -19,6 +19,26 @@ ...@@ -19,6 +19,26 @@
GIT_BEGIN_DECL 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 * Create a new push object
* *
* @param out New push object * @param out New push object
...@@ -29,6 +49,18 @@ GIT_BEGIN_DECL ...@@ -29,6 +49,18 @@ GIT_BEGIN_DECL
GIT_EXTERN(int) git_push_new(git_push **out, git_remote *remote); 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 * Add a refspec to be pushed
* *
* @param push The push object * @param push The push object
......
...@@ -144,7 +144,14 @@ on_error: ...@@ -144,7 +144,14 @@ on_error:
unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n) unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n)
{ {
assert(pb); assert(pb);
#ifdef GIT_THREADS
pb->nr_threads = n; pb->nr_threads = n;
#else
GIT_UNUSED(n);
assert(1 == pb->nr_threads);
#endif
return pb->nr_threads; return pb->nr_threads;
} }
......
...@@ -40,6 +40,7 @@ int git_push_new(git_push **out, git_remote *remote) ...@@ -40,6 +40,7 @@ int git_push_new(git_push **out, git_remote *remote)
p->repo = remote->repo; p->repo = remote->repo;
p->remote = remote; p->remote = remote;
p->report_status = 1; p->report_status = 1;
p->pb_parallelism = 1;
if (git_vector_init(&p->specs, 0, push_spec_rref_cmp) < 0) { if (git_vector_init(&p->specs, 0, push_spec_rref_cmp) < 0) {
git__free(p); git__free(p);
...@@ -56,6 +57,18 @@ int git_push_new(git_push **out, git_remote *remote) ...@@ -56,6 +57,18 @@ int git_push_new(git_push **out, git_remote *remote)
return 0; 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) static void free_refspec(push_spec *spec)
{ {
if (spec == NULL) if (spec == NULL)
...@@ -449,8 +462,12 @@ static int do_push(git_push *push) ...@@ -449,8 +462,12 @@ static int do_push(git_push *push)
* objects. In this case the client MUST send an empty pack-file. * objects. In this case the client MUST send an empty pack-file.
*/ */
if ((error = git_packbuilder_new(&push->pb, push->repo)) < 0 || if ((error = git_packbuilder_new(&push->pb, push->repo)) < 0)
(error = calculate_work(push)) < 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 = queue_objects(push)) < 0 ||
(error = transport->push(transport, push)) < 0) (error = transport->push(transport, push)) < 0)
goto on_error; goto on_error;
......
...@@ -36,6 +36,9 @@ struct git_push { ...@@ -36,6 +36,9 @@ struct git_push {
/* report-status */ /* report-status */
bool unpack_ok; bool unpack_ok;
git_vector status; git_vector status;
/* options */
unsigned pb_parallelism;
}; };
#endif #endif
...@@ -349,13 +349,18 @@ static void do_push(const char *refspecs[], size_t refspecs_len, ...@@ -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) expected_ref expected_refs[], size_t expected_refs_len, int expected_ret)
{ {
git_push *push; git_push *push;
git_push_options opts = GIT_PUSH_OPTIONS_INIT;
size_t i; size_t i;
int ret; int ret;
if (_remote) { 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_remote_connect(_remote, GIT_DIRECTION_PUSH));
cl_git_pass(git_push_new(&push, _remote)); cl_git_pass(git_push_new(&push, _remote));
cl_git_pass(git_push_set_options(push, &opts));
for (i = 0; i < refspecs_len; i++) for (i = 0; i < refspecs_len; i++)
cl_git_pass(git_push_add_refspec(push, refspecs[i])); cl_git_pass(git_push_add_refspec(push, refspecs[i]));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment