diff --git a/docs/remotes.rst b/docs/remotes.rst index dfa8804..933637f 100644 --- a/docs/remotes.rst +++ b/docs/remotes.rst @@ -2,10 +2,14 @@ Remotes ********************************************************************** - .. autoattribute:: pygit2.Repository.remotes .. automethod:: pygit2.Repository.create_remote +The remote collection +========================== + +.. autoclass:: pygit2.remote.RemoteCollection + :members: The Remote type ==================== diff --git a/pygit2/remote.py b/pygit2/remote.py index c69578c..88d875d 100644 --- a/pygit2/remote.py +++ b/pygit2/remote.py @@ -494,3 +494,66 @@ def get_credentials(fn, url, username, allowed): check_error(err) return ccred + +class RemoteCollection(object): + """Collection of configured remotes + + You can use this class to look up and manage the remotes configured + in a repository. You can access repositories using index + access. E.g. to look up the "origin" remote, you can use + + >>> repo.remotes["origin"] + """ + + def __init__(self, repo): + self._repo = repo; + + def __len__(self): + names = ffi.new('git_strarray *') + + try: + err = C.git_remote_list(names, self._repo._repo) + check_error(err) + + return names.count + finally: + C.git_strarray_free(names) + + def __iter__(self): + names = ffi.new('git_strarray *') + + try: + err = C.git_remote_list(names, self._repo._repo) + check_error(err) + + cremote = ffi.new('git_remote **') + for i in range(names.count): + err = C.git_remote_load(cremote, self._repo._repo, names.strings[i]) + check_error(err) + + yield Remote(self._repo, cremote[0]) + finally: + C.git_strarray_free(names) + + def __getitem__(self, name): + if isinstance(name, int): + return list(self)[name] + + cremote = ffi.new('git_remote **') + err = C.git_remote_load(cremote, self._repo._repo, to_bytes(name)) + check_error(err) + + return Remote(self._repo, cremote[0]) + + def create(self, name, url): + """create(name, url) -> Remote + + Create a new remote with the given name and url. + """ + + cremote = ffi.new('git_remote **') + + err = C.git_remote_create(cremote, self._repo._repo, to_bytes(name), to_bytes(url)) + check_error(err) + + return Remote(self._repo, cremote[0]) diff --git a/pygit2/repository.py b/pygit2/repository.py index d9c1eed..d31e03e 100644 --- a/pygit2/repository.py +++ b/pygit2/repository.py @@ -48,7 +48,7 @@ from .config import Config from .errors import check_error from .ffi import ffi, C from .index import Index -from .remote import Remote +from .remote import Remote, RemoteCollection from .blame import Blame from .utils import to_bytes, is_string @@ -58,6 +58,8 @@ class Repository(_Repository): def __init__(self, *args, **kwargs): super(Repository, self).__init__(*args, **kwargs) + self._remotes = RemoteCollection(self) + # Get the pointer as the contents of a buffer and store it for # later access repo_cptr = ffi.new('git_repository **') @@ -90,36 +92,17 @@ class Repository(_Repository): """create_remote(name, url) -> Remote Creates a new remote. + + This method is deprecated, please use Remote.remotes.create() """ - cremote = ffi.new('git_remote **') - - err = C.git_remote_create(cremote, self._repo, to_bytes(name), - to_bytes(url)) - check_error(err) - - return Remote(self, cremote[0]) + return self.remotes.create(name, url) @property def remotes(self): - """Returns all configured remotes""" + """The collection of configured remotes""" - names = ffi.new('git_strarray *') - - try: - err = C.git_remote_list(names, self._repo) - check_error(err) - - l = [None] * names.count - cremote = ffi.new('git_remote **') - for i in range(names.count): - err = C.git_remote_load(cremote, self._repo, names.strings[i]) - check_error(err) - - l[i] = Remote(self, cremote[0]) - return l - finally: - C.git_strarray_free(names) + return self._remotes # # Configuration diff --git a/test/test_remote.py b/test/test_remote.py index e0b9fae..ee28743 100644 --- a/test/test_remote.py +++ b/test/test_remote.py @@ -167,6 +167,19 @@ class RepositoryTest(utils.RepoTestCase): remote = self.repo.create_remote(name, url) self.assertTrue(remote.name in [x.name for x in self.repo.remotes]) + def test_remote_collection(self): + remote = self.repo.remotes['origin'] + self.assertEqual(REMOTE_NAME, remote.name) + self.assertEqual(REMOTE_URL, remote.url) + + with self.assertRaises(KeyError): + self.repo.remotes['upstream'] + + name = 'upstream' + url = 'git://github.com/libgit2/pygit2.git' + remote = self.repo.remotes.create(name, url) + self.assertTrue(remote.name in [x.name for x in self.repo.remotes]) + def test_remote_save(self): remote = self.repo.remotes[0]