Have only a single command in each test_expect_failure
[stgit] / stgit / stack.py
index d0b54eb..d9c4b99 100644 (file)
@@ -296,8 +296,6 @@ class Series(StgitObject):
         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')
 
         # where this series keeps its patches
         self.__patch_dir = os.path.join(self._dir(), 'patches')
@@ -326,11 +324,6 @@ class Series(StgitObject):
         """
         return self.__name
 
-    def __set_current(self, name):
-        """Sets the topmost patch
-        """
-        self._set_field('current', name)
-
     def get_patch(self, name):
         """Return a Patch object for the given name
         """
@@ -347,11 +340,16 @@ class Series(StgitObject):
     def get_current(self):
         """Return the name of the topmost patch, or None if there is
         no such patch."""
-        name = self._get_field('current')
-        if name == '':
+        try:
+            applied = self.get_applied()
+        except StackException:
+            # No "applied" file: branch is not initialized.
+            return None
+        try:
+            return applied[-1]
+        except IndexError:
+            # No patches applied.
             return None
-        else:
-            return name
 
     def get_applied(self):
         if not os.path.isfile(self.__applied_file):
@@ -408,11 +406,23 @@ class Series(StgitObject):
         if os.path.isfile(protect_file):
             os.remove(protect_file)
 
+    def __branch_descr(self):
+        return 'branch.%s.description' % self.get_branch()
+
     def get_description(self):
-        return self._get_field('description') or ''
+        # Fall back to the .git/patches/<branch>/description file if
+        # the config variable is unset.
+        return (config.get(self.__branch_descr())
+                or self._get_field('description') or '')
 
     def set_description(self, line):
-        self._set_field('description', line)
+        if line:
+            config.set(self.__branch_descr(), line)
+        else:
+            config.unset(self.__branch_descr())
+        # Delete the old .git/patches/<branch>/description file if it
+        # exists.
+        self._set_field('description', None)
 
     def get_parent_remote(self):
         value = config.get('branch.%s.remote' % self.__name)
@@ -451,10 +461,8 @@ class Series(StgitObject):
         config.set('branch.%s.stgit.parentbranch' % self.__name, name)
 
     def set_parent(self, remote, localbranch):
-        # policy: record local branches as remote='.'
-        recordremote = remote or '.'
         if localbranch:
-            self.__set_parent_remote(recordremote)
+            self.__set_parent_remote(remote)
             self.__set_parent_branch(localbranch)
         # We'll enforce this later
 #         else:
@@ -514,7 +522,6 @@ class Series(StgitObject):
 
         self.create_empty_field('applied')
         self.create_empty_field('unapplied')
-        self.create_empty_field('description')
         os.makedirs(os.path.join(self._dir(), 'patches'))
         os.makedirs(self.__refs_dir)
         self._set_field('orig-base', git.get_head())
@@ -614,7 +621,7 @@ class Series(StgitObject):
                 print "setting log to %s" %  patch.get_log()
                 newpatch.set_log(patch.get_log())
             else:
-                print "no log for %s" % patchname
+                print "no log for %s" % p
 
         # fast forward the cloned series to self's top
         new_series.forward_patches(applied)
@@ -656,13 +663,18 @@ class Series(StgitObject):
                 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):
-                os.remove(self.__descr_file)
             if os.path.exists(self._dir()+'/orig-base'):
                 os.remove(self._dir()+'/orig-base')
 
+            # Remove obsolete files that StGIT no longer uses, but
+            # that might still be around if this is an old repository.
+            for obsolete in ([os.path.join(self._dir(), fn)
+                              for fn in ['current', 'description']]
+                             + [os.path.join(self.__base_dir,
+                                             'refs', 'bases', self.__name)]):
+                if os.path.exists(obsolete):
+                    os.remove(obsolete)
+
             if not os.listdir(self.__patch_dir):
                 os.rmdir(self.__patch_dir)
             else:
@@ -786,20 +798,25 @@ class Series(StgitObject):
                   before_existing = False, refresh = True):
         """Creates a new patch
         """
-        self.__patch_name_valid(name)
 
-        if self.patch_applied(name) or self.patch_unapplied(name):
-            raise StackException, 'Patch "%s" already exists' % name
+        if name != None:
+            self.__patch_name_valid(name)
+            if self.patch_applied(name) or self.patch_unapplied(name):
+                raise StackException, 'Patch "%s" already exists' % name
 
         if not message and can_edit:
-            descr = edit_file(self, None, \
-                              'Please enter the description for patch "%s" ' \
-                              'above.' % name, show_patch)
+            descr = edit_file(
+                self, None,
+                'Please enter the description for the patch above.',
+                show_patch)
         else:
             descr = message
 
         head = git.get_head()
 
+        if name == None:
+            name = make_patch_name(descr, self.patch_exists)
+
         patch = Patch(name, self.__patch_dir, self.__refs_dir)
         patch.create()
 
@@ -831,11 +848,8 @@ class Series(StgitObject):
             self.log_patch(patch, 'new')
 
             insert_string(self.__applied_file, patch.get_name())
-            if not self.get_current():
-                self.__set_current(name)
         else:
             append_string(self.__applied_file, patch.get_name())
-            self.__set_current(name)
             if refresh:
                 self.refresh_patch(cache_update = False, log = 'new')
 
@@ -944,8 +958,6 @@ class Series(StgitObject):
         f.writelines([line + '\n' for line in unapplied])
         f.close()
 
-        self.__set_current(name)
-
         return forwarded
 
     def merged_patches(self, names):
@@ -1027,8 +1039,6 @@ class Series(StgitObject):
         f.writelines([line + '\n' for line in unapplied])
         f.close()
 
-        self.__set_current(name)
-
         # head == bottom case doesn't need to refresh the patch
         if empty or head != bottom:
             if not ex:
@@ -1081,12 +1091,13 @@ class Series(StgitObject):
 
         patch = Patch(name, self.__patch_dir, self.__refs_dir)
 
-        # only keep the local changes
-        if keep and not git.apply_diff(git.get_head(), patch.get_bottom()):
-            raise StackException, \
-                  'Failed to pop patches while preserving the local changes'
-
-        git.switch(patch.get_bottom(), keep)
+        if git.get_head_file() == self.get_branch():
+            if keep and not git.apply_diff(git.get_head(), patch.get_bottom()):
+                raise StackException(
+                    'Failed to pop patches while preserving the local changes')
+            git.switch(patch.get_bottom(), keep)
+        else:
+            git.set_branch(self.get_branch(), patch.get_bottom())
 
         # save the new applied list
         idx = applied.index(name) + 1
@@ -1106,11 +1117,6 @@ class Series(StgitObject):
         f.writelines([line + '\n' for line in applied])
         f.close()
 
-        if applied == []:
-            self.__set_current(None)
-        else:
-            self.__set_current(applied[-1])
-
     def empty_patch(self, name):
         """Returns True if the patch is empty
         """
@@ -1152,8 +1158,6 @@ class Series(StgitObject):
             f.close()
         elif oldname in applied:
             Patch(oldname, self.__patch_dir, self.__refs_dir).rename(newname)
-            if oldname == self.get_current():
-                self.__set_current(newname)
 
             applied[applied.index(oldname)] = newname