self.__applied_file = os.path.join(self._dir(), 'applied')
self.__unapplied_file = os.path.join(self._dir(), 'unapplied')
+ self.__hidden_file = os.path.join(self._dir(), 'hidden')
self.__current_file = os.path.join(self._dir(), 'current')
self.__descr_file = os.path.join(self._dir(), 'description')
f.close()
return names
+ def get_hidden(self):
+ if not os.path.isfile(self.__hidden_file):
+ return []
+ f = file(self.__hidden_file)
+ names = [line.strip() for line in f.readlines()]
+ f.close()
+ return names
+
def get_base_file(self):
self.__begin_stack_check()
return self.__base_file
os.remove(protect_file)
def get_description(self):
- return self._get_field('description')
+ return self._get_field('description') or ''
def set_description(self, line):
self._set_field('description', line)
"""
return name in self.get_unapplied()
+ def patch_hidden(self, name):
+ """Return true if the patch is hidden.
+ """
+ return name in self.get_hidden()
+
def patch_exists(self, name):
"""Return true if there is a patch with the given name, false
otherwise."""
def clone(self, target_series):
"""Clones a series
"""
- base = read_string(self.get_base_file())
+ try:
+ # allow cloning of branches not under StGIT control
+ base = read_string(self.get_base_file())
+ except:
+ base = git.get_head()
Series(target_series).init(create_at = base)
new_series = Series(target_series)
new_series.set_description('clone of "%s"' % self.__name)
# clone self's entire series as unapplied patches
- patches = self.get_applied() + self.get_unapplied()
- patches.reverse()
+ try:
+ # allow cloning of branches not under StGIT control
+ applied = self.get_applied()
+ unapplied = self.get_unapplied()
+ patches = applied + unapplied
+ patches.reverse()
+ except:
+ patches = applied = unapplied = []
for p in patches:
patch = self.get_patch(p)
new_series.new_patch(p, message = patch.get_description(),
author_date = patch.get_authdate())
# fast forward the cloned series to self's top
- new_series.forward_patches(self.get_applied())
+ new_series.forward_patches(applied)
def delete(self, force = False):
"""Deletes an stgit series
os.remove(self.__applied_file)
if os.path.exists(self.__unapplied_file):
os.remove(self.__unapplied_file)
+ if os.path.exists(self.__hidden_file):
+ os.remove(self.__hidden_file)
if os.path.exists(self.__current_file):
os.remove(self.__current_file)
if os.path.exists(self.__descr_file):
# old_bottom is different, there wasn't any previous 'refresh'
# command (probably only a 'push')
if old_bottom != patch.get_bottom() or old_top == patch.get_top():
- raise StackException, 'No refresh undo information available'
+ raise StackException, 'No undo information available'
git.reset(tree_id = old_top, check_out = False)
if patch.restore_old_boundaries():
f = file(self.__unapplied_file, 'w+')
f.writelines([line + '\n' for line in unapplied])
f.close()
+
+ if self.patch_hidden(name):
+ self.unhide_patch(name)
+
self.__begin_stack_check()
def forward_patches(self, names):
# merge can fail but the patch needs to be pushed
try:
- git.merge(bottom, head, top)
+ git.merge(bottom, head, top, recursive = True)
except git.GitException, ex:
print >> sys.stderr, \
'The merge failed during "push". ' \
log = 'push'
self.refresh_patch(cache_update = False, log = log)
else:
+ # we store the correctly merged files only for
+ # tracking the conflict history. Note that the
+ # git.merge() operations shouls always leave the index
+ # in a valid state (i.e. only stage 0 files)
+ self.refresh_patch(cache_update = False, log = 'push(c)')
raise StackException, str(ex)
return modified
# modified by 'refresh'). If they are both unchanged, there
# was a fast forward
if old_bottom == patch.get_bottom() and old_top != patch.get_top():
- raise StackException, 'No push undo information available'
+ raise StackException, 'No undo information available'
git.reset()
self.pop_patch(name)
if newname in applied or newname in unapplied:
raise StackException, 'Patch "%s" already exists' % newname
+ if self.patch_hidden(oldname):
+ self.unhide_patch(oldname)
+ self.hide_patch(newname)
+
if oldname in unapplied:
Patch(oldname, self.__patch_dir, self.__refs_dir).rename(newname)
unapplied[unapplied.index(oldname)] = newname
cache_update = False, tree_id = top.get_tree(),
allowempty = True)
patch.set_log(log)
+
+ def hide_patch(self, name):
+ """Add the patch to the hidden list.
+ """
+ if not self.patch_exists(name):
+ raise StackException, 'Unknown patch "%s"' % name
+ elif self.patch_hidden(name):
+ raise StackException, 'Patch "%s" already hidden' % name
+
+ append_string(self.__hidden_file, name)
+
+ def unhide_patch(self, name):
+ """Add the patch to the hidden list.
+ """
+ if not self.patch_exists(name):
+ raise StackException, 'Unknown patch "%s"' % name
+ hidden = self.get_hidden()
+ if not name in hidden:
+ raise StackException, 'Patch "%s" not hidden' % name
+
+ hidden.remove(name)
+
+ f = file(self.__hidden_file, 'w+')
+ f.writelines([line + '\n' for line in hidden])
+ f.close()