diff options
Diffstat (limited to 'lib/git/remote.py')
-rw-r--r-- | lib/git/remote.py | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/lib/git/remote.py b/lib/git/remote.py new file mode 100644 index 00000000..14d31a5d --- /dev/null +++ b/lib/git/remote.py @@ -0,0 +1,186 @@ +# remote.py +# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php +""" +Module implementing a remote object allowing easy access to git remotes +""" + +from git.utils import LazyMixin, Iterable +from refs import RemoteRef + +class _SectionConstrain(object): + """ + Constrains a ConfigParser to only option commands which are constrained to + always use the section we have been initialized with + """ + __slots__ = ( "_config", "_section_name" + _valid_attrs_ = ("get", "set", "getint", "getfloat", "getboolean") + + def __init__(self, config, section): + self._config = config + self._section_name = section + + def __getattr__(self, attr): + + + def get(option): + return self._config.get(self._section_name, option) + + def set(option, value): + return self._config.set(self._section_name, option, value) + + + +class Remote(LazyMixin, Iterable): + """ + Provides easy read and write access to a git remote. + + Everything not part of this interface is considered an option for the current + remote, allowing constructs like remote.pushurl to query the pushurl. + + NOTE: When querying configuration, the configuration accessor will be cached + to speed up subsequent accesses. + """ + + __slots__ = ( "repo", "name", "_config" ) + + def __init__(self, repo, name): + """ + Initialize a remote instance + + ``repo`` + The repository we are a remote of + + ``name`` + the name of the remote, i.e. 'origin' + """ + self.repo = repo + self.name = name + + def __getattr__(self, attr): + """ + Allows to call this instance like + remote.special( *args, **kwargs) to call git-remote special self.name + """ + return self._call_cmd(attr) + + def _set_cache_(self, attr): + if attr == "_config": + self._config = self.repo.config_reader + else: + super(Remote, self)._set_cache_(attr) + + + def __str__(self): + return self.name + + def __repr__(self): + return '<git.%s "%s">' % (self.__class__.__name__, self.name) + + def __eq__(self, other): + return self.name == other.name + + def __ne__(self, other): + return not ( self == other ) + + def __hash__(self): + return hash(self.name) + + @classmethod + def iter_items(cls, repo): + """ + Returns + Iterator yielding Remote objects of the given repository + """ + # parse them using refs, as their query can be faster as it is + # purely based on the file system + seen_remotes = set() + for ref in RemoteRef.iter_items(repo): + remote_name = ref.remote_name + if remote_name in seen_remotes: + continue + # END if remote done already + seen_remotes.add(remote_name) + yield Remote(repo, remote_name) + # END for each ref + + @property + def refs(self): + """ + Returns + List of RemoteRef objects + """ + out_refs = list() + for ref in RemoteRef.list_items(self.repo): + if ref.remote_name == self.name: + out_refs.append(ref) + # END if names match + # END for each ref + assert out_refs, "Remote %s did not have any references" % self.name + return out_refs + + @classmethod + def create(cls, repo, name, url, **kwargs): + """ + Create a new remote to the given repository + ``repo`` + Repository instance that is to receive the new remote + + ``name`` + Desired name of the remote + + ``url`` + URL which corresponds to the remote's name + + ``**kwargs`` + Additional arguments to be passed to the git-remote add command + + Returns + New Remote instance + + Raise + GitCommandError in case an origin with that name already exists + """ + self.repo.git.remote( "add", name, url, **kwargs ) + return cls(repo, name) + + # add is an alias + add = create + + @classmethod + def remove(cls, repo, name ): + """ + Remove the remote with the given name + """ + repo.git.remote("rm", name) + + def rename(self, new_name): + """ + Rename self to the given new_name + + Returns + self + """ + if self.name == new_name: + return self + + self.repo.git.remote("rename", self.name, new_name) + self.name = new_name + del(self._config) # it contains cached values, section names are different now + return self + + def update(self, **kwargs): + """ + Fetch all changes for this remote, including new branches + + ``kwargs`` + Additional arguments passed to git-remote update + + Returns + self + """ + self.repo.git.remote("update", self.name) + return self + |