chiark / gitweb /
Allow patch ranges for the 'pop' command
authorCatalin Marinas <catalin.marinas@gmail.com>
Wed, 6 Dec 2006 22:12:14 +0000 (22:12 +0000)
committerCatalin Marinas <catalin.marinas@gmail.com>
Wed, 6 Dec 2006 22:12:14 +0000 (22:12 +0000)
This patch is to make 'pop' accept patch ranges. Only the patches
specified in the range are now popped from the stack, the command
performing the necessary pop/push operations.

Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
stgit/commands/common.py
stgit/commands/pop.py
stgit/stack.py

index 723fc5b2692b48020f3d08fee914423d4d142b4d..8a625f82a25a3deb5cd30ec17ec49037bcb38181 100644 (file)
@@ -214,7 +214,7 @@ def pop_patches(patches, keep = False):
 
         print 'done'
 
-def parse_patches(patch_args, patch_list, boundary = 0):
+def parse_patches(patch_args, patch_list, boundary = 0, ordered = False):
     """Parse patch_args list for patch names in patch_list and return
     a list. The names can be individual patches and/or in the
     patch1..patch2 format.
@@ -271,6 +271,9 @@ def parse_patches(patch_args, patch_list, boundary = 0):
 
         patches += pl
 
+    if ordered:
+        patches = [p for p in patch_list if p in patches]
+
     return patches
 
 def name_email(address):
index 645eebd287ebc5951f1939972a1e817ebaed4698..0dfaad9f778e6585f28e1bd00446686689e76b6e 100644 (file)
@@ -25,12 +25,16 @@ from stgit import stack, git
 
 
 help = 'pop one or more patches from the stack'
-usage = """%prog [options] [<patch>]
+usage = """%prog [options] [<patch1>] [<patch2>] [<patch3>..<patch4>]
 
-Pop the topmost patch or a range of patches starting with the topmost
-one from the stack. The command fails if there are local changes or
-conflicts. If a patch name is given as argument, the command will pop
-all the patches up to the given one."""
+Pop the topmost patch or a range of patches from the stack. The
+command fails if there are conflicts or local changes (and --keep was
+not specified).
+
+A series of pop and push operations are performed so that only the
+patches passed on the command line are popped from the stack. Some of
+the push operations may fail because of conflicts (push --undo would
+revert the last push operation)."""
 
 options = [make_option('-a', '--all',
                        help = 'pop all the applied patches',
@@ -45,9 +49,6 @@ options = [make_option('-a', '--all',
 def func(parser, options, args):
     """Pop the topmost patch from the stack
     """
-    if len(args) > 1:
-        parser.error('incorrect number of arguments')
-
     check_conflicts()
     check_head_top_equal()
 
@@ -57,28 +58,32 @@ def func(parser, options, args):
     applied = crt_series.get_applied()
     if not applied:
         raise CmdException, 'No patches applied'
-    # the popping is done in reverse order
-    applied.reverse()
 
     if options.all:
         patches = applied
     elif options.number:
-        patches = applied[:options.number]
-    elif len(args) == 1:
-        upto_patch = args[0]
-        if upto_patch not in applied:
-            if upto_patch in crt_series.get_unapplied():
-                raise CmdException, 'Patch "%s" is not currently applied' \
-                      % upto_patch
-            else:
-                raise CmdException, 'Patch "%s" does not exist' % upto_patch
-        patches = applied[:applied.index(upto_patch)]
+        # reverse it twice to also work with negative or bigger than
+        # the length numbers
+        patches = applied[::-1][:options.number][::-1]
+    elif len(args) == 0:
+        patches = [applied[-1]]
     else:
-        patches = [applied[0]]
+        patches = parse_patches(args, applied, ordered = True)
 
-    if patches == []:
+    if not patches:
         raise CmdException, 'No patches to pop'
 
-    pop_patches(patches, options.keep)
+    # pop to the most distant popped patch
+    topop = applied[applied.index(patches[0]):]
+    # push those not in the popped range
+    topush = [p for p in topop if p not in patches]
+
+    if options.keep and topush:
+        raise CmdException, 'Cannot pop arbitrary patches with --keep'
+
+    topop.reverse()
+    pop_patches(topop, options.keep)
+    if topush:
+        push_patches(topush)
 
     print_crt_patch()
index 0a20f4b71e79b9ea1067506fd8d79dd17bcba39c..2200d33ddd98d7e4173016997f3b6eccc3ce3422 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)