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
|
.. _tutorial-remote:
Most of the tests in this file require a Dulwich server, so let's start one:
>>> from dulwich.repo import Repo
>>> from dulwich.server import DictBackend, TCPGitServer
>>> import threading
>>> repo = Repo.init("remote", mkdir=True)
>>> cid = repo.do_commit("message", committer="Jelmer <jelmer@samba.org>")
>>> backend = DictBackend({'/': repo})
>>> dul_server = TCPGitServer(backend, 'localhost', 0)
>>> threading.Thread(target=dul_server.serve).start()
>>> server_address, server_port = dul_server.socket.getsockname()
Remote repositories
===================
The interface for remote Git repositories is different from that
for local repositories.
The Git smart server protocol provides three basic operations:
* upload-pack - provides a pack with objects requested by the client
* receive-pack - imports a pack with objects provided by the client
* upload-archive - provides a tarball with the contents of a specific revision
The smart server protocol can be accessed over either plain TCP (git://),
SSH (git+ssh://) or tunneled over HTTP (http://).
Dulwich provides support for accessing remote repositories in
``dulwich.client``. To create a new client, you can either construct
one manually::
>>> from dulwich.client import TCPGitClient
>>> client = TCPGitClient(server_address, server_port)
Retrieving raw pack files
-------------------------
The client object can then be used to retrieve a pack. The ``fetch_pack``
method takes a ``determine_wants`` callback argument, which allows the
client to determine which objects it wants to end up with::
>>> def determine_wants(refs):
... # retrieve all objects
... return refs.values()
Another required object is a "graph walker", which is used to determine
which objects that the client already has should not be sent again
by the server. Here in the tutorial we'll just use a dummy graph walker
which claims that the client doesn't have any objects::
>>> class DummyGraphWalker(object):
... def ack(self, sha): pass
... def next(self): pass
With the ``determine_wants`` function in place, we can now fetch a pack,
which we will write to a ``BytesIO`` object::
>>> from io import BytesIO
>>> f = BytesIO()
>>> remote_refs = client.fetch_pack("/", determine_wants,
... DummyGraphWalker(), pack_data=f.write)
``f`` will now contain a full pack file::
>>> f.getvalue()[:4]
'PACK'
Fetching objects into a local repository
----------------------------------------
It is also possible to fetch from a remote repository into a local repository,
in which case Dulwich takes care of providing the right graph walker, and
importing the received pack file into the local repository::
>>> from dulwich.repo import Repo
>>> local = Repo.init("local", mkdir=True)
>>> remote_refs = client.fetch("/", local)
Let's shut down the server now that all tests have been run::
>>> dul_server.shutdown()
|