Track the files conflict history
[stgit] / stgit / stack.py
index 69fa03b..2ae4dd5 100644 (file)
@@ -392,7 +392,7 @@ class Series(StgitObject):
             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)
@@ -534,7 +534,11 @@ class Series(StgitObject):
     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)
 
@@ -542,8 +546,14 @@ class Series(StgitObject):
         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(),
@@ -555,7 +565,7 @@ class Series(StgitObject):
                                  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
@@ -684,7 +694,7 @@ class Series(StgitObject):
         # 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():
@@ -923,7 +933,7 @@ class Series(StgitObject):
 
                 # 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". ' \
@@ -949,6 +959,11 @@ class Series(StgitObject):
                     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
@@ -966,7 +981,7 @@ class Series(StgitObject):
         # 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)