improve "usage" strings to include optional "--"
[stgit] / stgit / commands / delete.py
index 1696cb9..b656a87 100644 (file)
@@ -16,67 +16,63 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-import sys, os
-from optparse import OptionParser, make_option
-
-from stgit.commands.common import *
-from stgit.utils import *
-from stgit.out import *
-from stgit import stack, git
-
-
-help = 'delete patches'
-usage = """%prog [options] <patch1> [<patch2>] [<patch3>..<patch4>]
-
-Delete the patches passed as arguments. If an applied patch is to be
-deleted, all other patches applied on top of it must be deleted too,
-and they must be explicitly specified, since this command will not try
-to delete a patch unless you explicitly ask it to. If any applied
-patches are deleted, they are popped from the stack.
-
-Note that the 'delete' operation is irreversible."""
-
-directory = DirectoryGotoToplevel()
-options = [make_option('-b', '--branch',
-                       help = 'use BRANCH instead of the default one')]
+from stgit.argparse import opt
+from stgit.commands import common
+from stgit.lib import transaction
+from stgit import argparse
+
+help = 'Delete patches'
+kind = 'patch'
+usage = ['[options] [--] <patch1> [<patch2>] [<patch3>..<patch4>]']
+description = """
+Delete the patches passed as arguments."""
+
+args = [argparse.patch_range(argparse.applied_patches,
+                             argparse.unapplied_patches)]
+options = [
+    opt('--spill', action = 'store_true',
+        short = 'Spill patch contents to worktree and index', long = """
+        Delete the patches, but do not touch the index and worktree.
+        This only works with applied patches at the top of the stack.
+        The effect is to "spill" the patch contents into the index and
+        worktree. This can be useful e.g. if you want to split a patch
+        into several smaller pieces."""),
+    opt('-b', '--branch', args = [argparse.stg_branches],
+        short = 'Use BRANCH instead of the default branch')]
+
+directory = common.DirectoryHasRepositoryLib()
 
 def func(parser, options, args):
-    """Deletes one or more patches.
-    """
-    applied_patches = crt_series.get_applied()
-    unapplied_patches = crt_series.get_unapplied()
-    all_patches = applied_patches + unapplied_patches
-
+    """Delete one or more patches."""
+    stack = directory.repository.get_stack(options.branch)
+    if options.branch:
+        iw = None # can't use index/workdir to manipulate another branch
+    else:
+        iw = stack.repository.default_iw
     if args:
-        patches = parse_patches(args, all_patches, len(applied_patches))
+        patches = set(common.parse_patches(args, list(stack.patchorder.all),
+                                           len(stack.patchorder.applied)))
     else:
         parser.error('No patches specified')
 
-    applied = []
+    if options.spill:
+        if set(stack.patchorder.applied[-len(patches):]) != patches:
+            parser.error('Can only spill topmost applied patches')
+        iw = None # don't touch index+worktree
 
-    # find the applied patches to be deleted. We can only delete
-    # consecutive patches in the applied range
-    for patch in applied_patches[::-1]:
-        if patch in patches:
-            applied.append(patch)
-            patches.remove(patch)
+    def allow_conflicts(trans):
+        # Allow conflicts if the topmost patch stays the same.
+        if stack.patchorder.applied:
+            return (trans.applied
+                    and trans.applied[-1] == stack.patchorder.applied[-1])
         else:
-            break
-
-    # any applied patches to be deleted but not in consecutive order?
-    for patch in patches:
-        if patch in applied_patches:
-            raise CmdException, 'Cannot delete the applied patch "%s"' % patch
-
-    if applied and not options.branch:
-        check_local_changes()
-        check_conflicts()
-        check_head_top_equal(crt_series)
-
-    # delete the patches
-    for patch in applied + patches:
-        crt_series.delete_patch(patch)
-        out.info('Patch "%s" successfully deleted' % patch)
-
-    if not options.branch:
-        print_crt_patch(crt_series)
+            return not trans.applied
+    trans = transaction.StackTransaction(stack, 'delete',
+                                         allow_conflicts = allow_conflicts)
+    try:
+        to_push = trans.delete_patches(lambda pn: pn in patches)
+        for pn in to_push:
+            trans.push_patch(pn, iw)
+    except transaction.TransactionHalted:
+        pass
+    return trans.run(iw)