Skip to content

Commit

Permalink
Enable multi-threaded pack file creation
Browse files Browse the repository at this point in the history
libgit2 supports creating pack files using multiple threads, which can
significantly speed up a push operation.  Enable Remote.push() to take
advantage of that capability by adding a relevant keyword argument whose
value gets passed to git_remote_push().
  • Loading branch information
kempniu committed Feb 17, 2025
1 parent d0879d8 commit de2b4e5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
12 changes: 11 additions & 1 deletion pygit2/remotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def push_refspecs(self):
check_error(err)
return strarray_to_strings(specs)

def push(self, specs, callbacks=None, proxy=None, push_options=None):
def push(self, specs, callbacks=None, proxy=None, push_options=None, threads=1):
"""
Push the given refspec to the remote. Raises ``GitError`` on protocol
error or unpack failure.
Expand All @@ -263,9 +263,19 @@ def push(self, specs, callbacks=None, proxy=None, push_options=None):
push_options : [str]
Push options to send to the server, which passes them to the
pre-receive as well as the post-receive hook.
threads : int
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.
"""
with git_push_options(callbacks) as payload:
opts = payload.push_options
opts.pb_parallelism = threads
self.__set_proxy(opts.proxy_opts, proxy)
with StrArray(specs) as refspecs, StrArray(push_options) as pushopts:
pushopts.assign_to(opts.remote_push_options)
Expand Down
16 changes: 16 additions & 0 deletions test/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,3 +466,19 @@ def test_push_options(origin, clone, remote):
remote_push_options = callbacks.push_options.remote_push_options
assert remote_push_options.count == 2
# strings pointed to by remote_push_options.strings[] are already freed


def test_push_threads(origin, clone, remote):
from pygit2 import RemoteCallbacks

callbacks = RemoteCallbacks()
remote.push(['refs/heads/master'], callbacks)
assert callbacks.push_options.pb_parallelism == 1

callbacks = RemoteCallbacks()
remote.push(['refs/heads/master'], callbacks, threads=0)
assert callbacks.push_options.pb_parallelism == 0

callbacks = RemoteCallbacks()
remote.push(['refs/heads/master'], callbacks, threads=1)
assert callbacks.push_options.pb_parallelism == 1

0 comments on commit de2b4e5

Please sign in to comment.