"""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):
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."""
def update_index(self, files):
self.run(['git', 'update-index', '--remove', '-z', '--stdin']
).input_nulterm(files).discard_output()
+
+class Branch(object):
+ """Represents a 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)
+ repository.run(['git', 'branch', create_at.sha1]).discard_output()
+
+ return cls(repository, name)
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)."""
+ __repo_subdir = 'patches'
+
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:
git.Repository.__init__(self, *args, **kwargs)
self.__stacks = {} # name -> Stack
@property
- def current_branch(self):
- return utils.strip_leading('refs/heads/', self.head_ref)
- @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]