This class deals with Git-specific branch commands. The Stack class is a direct child of Branch and some of its functionality was moved to the new class. Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxxxx> --- stgit/lib/git.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ stgit/lib/stack.py | 25 ++++--------------------- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/stgit/lib/git.py b/stgit/lib/git.py index fd66f6d..6393af2 100644 --- a/stgit/lib/git.py +++ b/stgit/lib/git.py @@ -28,6 +28,9 @@ class RepositoryException(exception.StgException): """Base class for all exceptions due to failed L{Repository} operations.""" +class BranchException(exception.StgException): + """Exception raised by failed L{Branch} operations.""" + class DateException(exception.StgException): """Exception raised when a date+time string could not be parsed.""" def __init__(self, string, type): @@ -379,6 +382,10 @@ class Repository(RunWithEnv): except run.RunException: raise RepositoryException('Cannot find git repository') @property + def current_branch_name(self): + """Return the name of the current branch.""" + return utils.strip_leading('refs/heads/', self.head_ref) + @property def default_index(self): """An L{Index} object representing the default index file for the repository.""" @@ -619,3 +626,47 @@ class IndexAndWorktree(RunWithEnvCwd): def update_index(self, files): self.run(['git', 'update-index', '--remove', '-z', '--stdin'] ).input_nulterm(files).discard_output() + +class Branch(object): + """Represents Git branch.""" + def __init__(self, repository, name): + self._repository = repository + self._name = name + try: + self.head + except KeyError: + raise BranchException('%s: no such branch' % name) + + name = property(lambda self: self._name) + repository = property(lambda self: self._repository) + + def __ref(self): + return 'refs/heads/%s' % self._name + @property + def head(self): + return self._repository.refs.get(self.__ref()) + def set_head(self, commit, msg): + self._repository.refs.set(self.__ref(), commit, msg) + + def set_parent_remote(self, name): + value = config.set('branch.%s.remote' % self._name, name) + def set_parent_branch(self, name): + if config.get('branch.%s.remote' % self._name): + # Never set merge if remote is not set to avoid + # possibly-erroneous lookups into 'origin' + config.set('branch.%s.merge' % self._name, name) + + @classmethod + def create(cls, repository, name, create_at = None): + """Create a new Git branch and return the corresponding L{Branch} object.""" + try: + branch = cls(repository, name) + except BranchException: + branch = None + if branch: + raise BranchException('%s: branch already exists' % name) + + cmd = ['git', 'branch'] + if create_at: + cmd.append(create_at.sha1) + self._repository.run(['git', 'branch', create_at.sha1]).discard_output() diff --git a/stgit/lib/stack.py b/stgit/lib/stack.py index bdd21b1..aca7a36 100644 --- a/stgit/lib/stack.py +++ b/stgit/lib/stack.py @@ -130,34 +130,20 @@ class Patches(object): self.__patches[name] = p return p -class Stack(object): +class Stack(git.Branch): """Represents an StGit stack (that is, a git branch with some extra metadata).""" def __init__(self, repository, name): - self.__repository = repository - self.__name = name - try: - self.head - except KeyError: - raise exception.StgException('%s: no such branch' % name) + git.Branch.__init__(self, repository, name) self.__patchorder = PatchOrder(self) self.__patches = Patches(self) if not stackupgrade.update_to_current_format_version(repository, name): raise exception.StgException('%s: branch not initialized' % name) - name = property(lambda self: self.__name) - repository = property(lambda self: self.__repository) patchorder = property(lambda self: self.__patchorder) patches = property(lambda self: self.__patches) @property def directory(self): - return os.path.join(self.__repository.directory, 'patches', self.__name) - def __ref(self): - return 'refs/heads/%s' % self.__name - @property - def head(self): - return self.__repository.refs.get(self.__ref()) - def set_head(self, commit, msg): - self.__repository.refs.set(self.__ref(), commit, msg) + return os.path.join(self._repository.directory, self.__repo_subdir, self._name) @property def base(self): if self.patchorder.applied: @@ -177,14 +163,11 @@ class Repository(git.Repository): git.Repository.__init__(self, *args, **kwargs) self.__stacks = {} # name -> Stack @property - def current_branch(self): - return utils.strip_leading('refs/heads/', self.head) - @property def current_stack(self): return self.get_stack() def get_stack(self, name = None): if not name: - name = self.current_branch + name = self.current_branch_name if not name in self.__stacks: self.__stacks[name] = Stack(self, name) return self.__stacks[name] -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html