Skip to content

Commit

Permalink
Add tutorial chapter on remote repositories.
Browse files Browse the repository at this point in the history
  • Loading branch information
jelmer committed Jan 4, 2012
1 parent e07e02e commit 57cf9e7
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/tutorial/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ Tutorial
introduction
repo
object-store
remote
conclusion

83 changes: 83 additions & 0 deletions docs/tutorial/remote.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,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")
>>> 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 ``StringIO`` object::

>>> from cStringIO import StringIO
>>> f = StringIO()
>>> 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 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 show down the server now that all tests have been run::

>>> dul_server.shutdown()
1 change: 1 addition & 0 deletions dulwich/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def tutorial_test_suite():
'introduction',
'repo',
'object-store',
'remote',
'conclusion',
]
tutorial_files = ["../../docs/tutorial/%s.txt" % name for name in tutorial]
Expand Down

0 comments on commit 57cf9e7

Please sign in to comment.