Remove the resolved command
[stgit] / stgit / commands / push.py
index a636ad2..d5e02e0 100644 (file)
@@ -16,88 +16,87 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
 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 import stack, git
-
-
-help = 'push one or more patches onto of the stack'
-usage = """%prog [options] [<patch1>] [<patch2>] [<patch3>..<patch4>]
-
+from stgit.commands import common
+from stgit.lib import transaction
+from stgit import argparse
+from stgit.argparse import opt
+
+help = 'Push one or more patches onto the stack'
+kind = 'stack'
+usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
+description = """
 Push one or more patches (defaulting to the first unapplied one) onto
 the stack. The 'push' operation allows patch reordering by commuting
 Push one or more patches (defaulting to the first unapplied one) onto
 the stack. The 'push' operation allows patch reordering by commuting
-them with the three-way merge algorithm. If the result of the 'push'
-operation is not acceptable or if there are too many conflicts, the
-'--undo' option can be used to revert the last pushed patch. Conflicts
-raised during the push operation have to be fixed and the 'resolved'
-command run.
+them with the three-way merge algorithm. If there are conflicts while
+pushing a patch, those conflicts are written to the work tree, and the
+command halts. Conflicts raised during the push operation have to be
+fixed and the 'git add --update' command run (alternatively, you may
+undo the conflicting push with 'stg undo').
 
 The command also notifies when the patch becomes empty (fully merged
 upstream) or is modified (three-way merged) by the 'push' operation."""
 
 
 The command also notifies when the patch becomes empty (fully merged
 upstream) or is modified (three-way merged) by the 'push' operation."""
 
-options = [make_option('-a', '--all',
-                       help = 'push all the unapplied patches',
-                       action = 'store_true'),
-           make_option('-n', '--number', type = 'int',
-                       help = 'push the specified number of patches'),
-           make_option('--reverse',
-                       help = 'push the patches in reverse order',
-                       action = 'store_true'),
-           make_option('-m', '--merged',
-                       help = 'check for patches merged upstream',
-                       action = 'store_true'),
-           make_option('--undo',
-                       help = 'undo the last patch pushing',
-                       action = 'store_true')]
-
+args = [argparse.patch_range(argparse.unapplied_patches)]
+options = [
+    opt('-a', '--all', action = 'store_true',
+        short = 'Push all the unapplied patches'),
+    opt('-n', '--number', type = 'int',
+        short = 'Push the specified number of patches'),
+    opt('--reverse', action = 'store_true',
+        short = 'Push the patches in reverse order'),
+    opt('--set-tree', action = 'store_true',
+        short = 'Push the patch with the original tree', long = """
+        Push the patches, but don't perform a merge. Instead, the
+        resulting tree will be identical to the tree that the patch
+        previously created.
+
+        This can be useful when splitting a patch by first popping the
+        patch and creating a new patch with some of the
+        changes. Pushing the original patch with '--set-tree' will
+        avoid conflicts and only the remaining changes will be in the
+        patch.""")
+    ] + argparse.keep_option() + argparse.merged_option()
+
+directory = common.DirectoryHasRepositoryLib()
 
 def func(parser, options, args):
 
 def func(parser, options, args):
-    """Pushes the given patch or all onto the series
-    """
-
-    # If --undo is passed, do the work and exit
-    if options.undo:
-        patch = crt_series.get_current()
-        if not patch:
-            raise CmdException, 'No patch to undo'
-
-        print 'Undoing the "%s" push...' % patch,
-        sys.stdout.flush()
-        resolved_all()
-        if crt_series.undo_push():
-            print 'done'
-        else:
-            print 'done (patch unchanged)'
-        print_crt_patch()
-
-        return
-
-    check_local_changes()
-    check_conflicts()
-    check_head_top_equal()
-
-    unapplied = crt_series.get_unapplied()
-    if not unapplied:
-        raise CmdException, 'No more patches to push'
-
-    if options.number:
-        patches = unapplied[:options.number]
-    elif options.all:
-        patches = unapplied
-    elif len(args) == 0:
-        patches = [unapplied[0]]
+    """Pushes the given patches or the first unapplied onto the stack."""
+    stack = directory.repository.current_stack
+    iw = stack.repository.default_iw
+    clean_iw = (not options.keep and iw) or None
+    trans = transaction.StackTransaction(stack, 'pop',
+                                         check_clean_iw = clean_iw)
+
+    if not trans.unapplied:
+        raise common.CmdException('No patches to push')
+
+    if options.all:
+        patches = list(trans.unapplied)
+    elif options.number:
+        patches = trans.unapplied[:options.number]
+    elif not args:
+        patches = [trans.unapplied[0]]
     else:
     else:
-        patches = parse_patches(args, unapplied)
+        patches = common.parse_patches(args, trans.unapplied)
 
 
-    if patches == []:
-        raise CmdException, 'No patches to push'
+    if not patches:
+        raise common.CmdException('No patches to push')
 
     if options.reverse:
         patches.reverse()
 
 
     if options.reverse:
         patches.reverse()
 
-    push_patches(patches, options.merged)
-
-    print_crt_patch()
+    if options.set_tree:
+        for pn in patches:
+            trans.push_tree(pn)
+    else:
+        try:
+            if options.merged:
+                merged = set(trans.check_merged(patches))
+            else:
+                merged = set()
+            for pn in patches:
+                trans.push_patch(pn, iw, allow_interactive = True,
+                                 already_merged = pn in merged)
+        except transaction.TransactionHalted:
+            pass
+    return trans.run(iw)