Use __run instead of os.system() in git.merge()
[stgit] / stgit / commands / push.py
index 6fbd779..f6f4003 100644 (file)
@@ -54,9 +54,19 @@ options = [make_option('-a', '--all',
                        action = 'store_true')]
 
 
+def is_patch_appliable(p):
+    """See if patch exists, or is already applied.
+    """
+    if p in applied:
+        raise CmdException, 'Patch "%s" is already applied.' % p
+    if p not in unapplied:
+        raise CmdException, 'Patch "%s" does not exist.' % p
+
 def func(parser, options, args):
     """Pushes the given patch or all onto the series
     """
+    global applied, unapplied
+
     # If --undo is passed, do the work and exit
     if options.undo:
         patch = crt_series.get_current()
@@ -66,8 +76,10 @@ def func(parser, options, args):
         print 'Undoing the "%s" push...' % patch,
         sys.stdout.flush()
         resolved_all()
-        crt_series.undo_push()
-        print 'done'
+        if crt_series.undo_push():
+            print 'done'
+        else:
+            print 'done (patch unchanged)'
         print_crt_patch()
 
         return
@@ -76,6 +88,7 @@ def func(parser, options, args):
     check_conflicts()
     check_head_top_equal()
 
+    applied = crt_series.get_applied()
     unapplied = crt_series.get_unapplied()
     if not unapplied:
         raise CmdException, 'No more patches to push'
@@ -83,14 +96,11 @@ def func(parser, options, args):
     if options.to:
         boundaries = options.to.split(':')
         if len(boundaries) == 1:
-            if boundaries[0] not in unapplied:
-                raise CmdException, 'Patch "%s" not unapplied' % boundaries[0]
+            is_patch_appliable(boundaries[0])
             patches = unapplied[:unapplied.index(boundaries[0])+1]
         elif len(boundaries) == 2:
-            if boundaries[0] not in unapplied:
-                raise CmdException, 'Patch "%s" not unapplied' % boundaries[0]
-            if boundaries[1] not in unapplied:
-                raise CmdException, 'Patch "%s" not unapplied' % boundaries[1]
+            is_patch_appliable(boundaries[0])
+            is_patch_appliable(boundaries[1])
             lb = unapplied.index(boundaries[0])
             hb = unapplied.index(boundaries[1])
             if lb > hb:
@@ -106,7 +116,8 @@ def func(parser, options, args):
     elif len(args) == 0:
         patches = [unapplied[0]]
     elif len(args) == 1:
-        patches = [args[0]]
+        patches = args
+        is_patch_appliable(patches[0])
     else:
         parser.error('incorrect number of arguments')
 
@@ -116,9 +127,15 @@ def func(parser, options, args):
     if options.reverse:
         patches.reverse()
 
-    for p in patches:
-        if p not in unapplied:
-            raise CmdException, 'Patch "%s" not unapplied' % p
+    forwarded = crt_series.forward_patches(patches)
+    if forwarded > 1:
+        print 'Fast-forwarded patches "%s" - "%s"' % (patches[0],
+                                                      patches[forwarded - 1])
+    elif forwarded == 1:
+        print 'Fast-forwarded patch "%s"' % patches[0]
+
+    for p in patches[forwarded:]:
+        is_patch_appliable(p)
 
         print 'Pushing patch "%s"...' % p,
         sys.stdout.flush()