New command 'float' to move a patch to the top
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Tue, 17 Oct 2006 18:39:53 +0000 (19:39 +0100)
committerCatalin Marinas <catalin.marinas@gmail.com>
Tue, 17 Oct 2006 18:39:53 +0000 (19:39 +0100)
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
stgit/commands/float.py [new file with mode: 0644]
stgit/main.py
t/t1500-float.sh [new file with mode: 0755]

diff --git a/stgit/commands/float.py b/stgit/commands/float.py
new file mode 100644 (file)
index 0000000..c2d8190
--- /dev/null
@@ -0,0 +1,72 @@
+__copyright__ = """
+Copyright (C) 2006, Robin Rosenberg <robin.rosenberg@dewire.com>
+Modified by Catalin Marinas
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+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 import stack, git
+
+help = 'push patches to the top, even if applied'
+usage = """%prog [options] <patches>
+
+Push a patch or a range of patches to the top even if applied. The
+necessary pop and push operations will be performed to accomplish
+this."""
+
+options = []
+
+def func(parser, options, args):
+    """Pops and pushed to make the named patch the topmost patch
+    """
+    if len(args) == 0:
+        parser.error('incorrect number of arguments')
+
+    check_local_changes()
+    check_conflicts()
+    check_head_top_equal()
+
+    unapplied = crt_series.get_unapplied()
+    applied = crt_series.get_applied()
+    all = unapplied + applied
+
+    patches = parse_patches(args, all)
+    # working with "topush" patches in reverse order might be a bit
+    # more efficient for large series but the main reason is for the
+    # "topop != topush" comparison to work
+    patches.reverse()
+
+    topush = []
+    topop = []
+
+    for p in patches:
+        while p in applied:
+            top = applied.pop()
+            if not top in patches:
+                topush.append(top)
+            topop.append(top)
+    topush = patches + topush
+
+    # check whether the operation is really needed
+    if topop != topush:
+        if topop:
+            pop_patches(topop)
+        if topush:
+            topush.reverse()
+            push_patches(topush)
index f59bce6..e9cc6cd 100644 (file)
@@ -38,6 +38,7 @@ import stgit.commands.clone
 import stgit.commands.commit
 import stgit.commands.export
 import stgit.commands.files
+import stgit.commands.float
 import stgit.commands.fold
 import stgit.commands.goto
 import stgit.commands.id
@@ -77,6 +78,7 @@ commands = {
     'commit':   stgit.commands.commit,
     'export':   stgit.commands.export,
     'files':    stgit.commands.files,
+    'float':    stgit.commands.float,
     'fold':     stgit.commands.fold,
     'goto':     stgit.commands.goto,
     'id':       stgit.commands.id,
@@ -113,6 +115,7 @@ stackcommands = (
     'applied',
     'clean',
     'commit',
+    'float',
     'goto',
     'init',
     'pop',
diff --git a/t/t1500-float.sh b/t/t1500-float.sh
new file mode 100755 (executable)
index 0000000..dbcd8ce
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Robin Rosenberg
+#
+
+test_description='Test floating a number of patches to the top of the stack
+
+'
+
+. ./test-lib.sh
+
+test_expect_success \
+       'Initialize the StGIT repository' \
+       'stg init &&
+        stg new A -m "a" && echo A >a.txt && stg add a.txt && stg refresh &&
+        stg new B -m "b" && echo B >b.txt && stg add b.txt && stg refresh &&
+        stg new C -m "c" && echo C >c.txt && stg add c.txt && stg refresh &&
+        stg new D -m "d" && echo D >d.txt && stg add d.txt && stg refresh &&
+        stg new E -m "e" && echo E >e.txt && stg add e.txt && stg refresh &&
+        stg new F -m "f" && echo F >f.txt && stg add f.txt && stg refresh &&
+        stg new G -m "g" && echo G >g.txt && stg add g.txt && stg refresh &&
+        stg pop &&
+        test "`echo \`cat .git/patches/master/applied\``" = "A B C D E F"
+       '
+
+test_expect_success \
+       'Float A to top' \
+       'stg float A &&
+        test "`echo \`cat .git/patches/master/applied\``" = "B C D E F A"
+       '
+test_expect_success \
+       'Float A to top (noop)' \
+       'stg float A &&
+        test "`echo \`cat .git/patches/master/applied\``" = "B C D E F A"
+       '
+test_expect_success \
+       'Float B C to top' \
+       'stg float B C &&
+        test "`echo \`cat .git/patches/master/applied\``" = "D E F A B C"
+       '
+test_expect_success \
+       'Float E A to top' \
+       'stg float E A &&
+        test "`echo \`cat .git/patches/master/applied\``" = "D F B C E A"
+       '
+test_expect_success \
+       'Float E to top' \
+       'stg float E &&
+        test "`echo \`cat .git/patches/master/applied\``" = "D F B C A E"
+       '
+test_expect_success \
+       'Float G F to top' \
+       'stg float G F &&
+        test "`echo \`cat .git/patches/master/applied\``" = "D B C A E G F"
+       '
+test_done