Remove the resolved command
[stgit] / stgit / commands / push.py
index c3d553d..d5e02e0 100644 (file)
@@ -16,12 +16,10 @@ 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 stgit.commands import common
+from stgit.lib import transaction
+from stgit import argparse
 from stgit.argparse import opt
-from stgit.commands.common import *
-from stgit.utils import *
-from stgit.out import *
-from stgit import stack, git
 
 help = 'Push one or more patches onto the stack'
 kind = 'stack'
@@ -29,15 +27,16 @@ 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
-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."""
 
+args = [argparse.patch_range(argparse.unapplied_patches)]
 options = [
     opt('-a', '--all', action = 'store_true',
         short = 'Push all the unapplied patches'),
@@ -45,56 +44,59 @@ options = [
         short = 'Push the specified number of patches'),
     opt('--reverse', action = 'store_true',
         short = 'Push the patches in reverse order'),
-    opt('-m', '--merged', action = 'store_true',
-        short = 'Check for patches merged upstream'),
-    opt('--undo', action = 'store_true',
-        short = 'Undo the last patch pushing')]
+    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.
 
-directory = DirectoryGotoToplevel(log = True)
+        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):
-    """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'
-
-        out.start('Undoing push of "%s"' % patch)
-        resolved_all()
-        if crt_series.undo_push():
-            out.done()
-        else:
-            out.done('patch unchanged')
-        print_crt_patch(crt_series)
-
-        return
-
-    check_local_changes()
-    check_conflicts()
-    check_head_top_equal(crt_series)
-
-    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:
-        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()
 
-    push_patches(crt_series, patches, options.merged)
-
-    print_crt_patch(crt_series)
+    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)