[PATCH 2/2] Add 'stg uncommit' command
authorKarl Hasselstr\\Ã\\¶m <kha@treskal.com>
Sun, 19 Feb 2006 10:27:01 +0000 (10:27 +0000)
committerCatalin Marinas <catalin.marinas@gmail.com>
Sun, 19 Feb 2006 10:41:45 +0000 (10:41 +0000)
Add an uncommit command, which is exactly the opposite of 'stg
commit'.

Signed-off-by: Karl Hasselström <kha@treskal.com>
stgit/commands/uncommit.py [new file with mode: 0644]
stgit/main.py
stgit/stack.py

diff --git a/stgit/commands/uncommit.py b/stgit/commands/uncommit.py
new file mode 100644 (file)
index 0000000..7011ed6
--- /dev/null
@@ -0,0 +1,80 @@
+__copyright__ = """
+Copyright (C) 2006, Karl Hasselström <kha@treskal.com>
+
+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 = 'turn regular git commits into StGIT patches'
+usage = """%prog [options] <patchname1> [<patchname2> ... ]
+
+Takes one or more git commits at the base of the current stack, and
+turns them into StGIT patches. These new patches are alreay applied,
+at the bottom of the stack. This is the exact opposite of 'stg
+commit'.
+
+You can either give one patch name for each commit you wish to
+uncommit, or use the --number option and exactly one patch name; StGIT
+will then create numbered patches with the given patch name as prefix.
+
+Only commits with exactly one parent can be uncommitted; in other
+words, you can't uncommmit a merge."""
+
+options = [make_option('-n', '--number', type = 'int',
+                       help = 'uncommit the specified number of commits')]
+
+def func(parser, options, args):
+    if len(args) == 0:
+        parser.error('you must specify at least one patch name')
+    if options.number:
+        if len(args) != 1:
+            parser.error('when using --number, specify exactly one patch name')
+        patchnames = ['%s%d' % (args[0], i)
+                      for i in xrange(options.number - 1, -1, -1)]
+    else:
+        patchnames = args
+
+    if crt_series.get_protected():
+        raise CmdException, 'This branch is protected. Uncommit is not permitted'
+
+    print 'Uncommitting %d patches...' % len(patchnames),
+    sys.stdout.flush()
+
+    for patchname in patchnames:
+        base_file = crt_series.get_base_file()
+        commit_id = read_string(base_file)
+        commit = git.Commit(commit_id)
+        try:
+            parent, = commit.get_parents()
+        except ValueError:
+            raise CmdException, ('Commit %s does not have exactly one parent'
+                                 % commit_id)
+        author_name, author_email, author_date = name_email_date(
+            commit.get_author())
+        crt_series.new_patch(patchname,
+                             can_edit = False, before_existing = True,
+                             top = commit_id, bottom = parent,
+                             message = commit.get_log(),
+                             author_name = author_name,
+                             author_email = author_email,
+                             author_date = author_date)
+        write_string(base_file, parent)
+
+    print 'done'
index 6d86ee4..4a48668 100644 (file)
@@ -57,6 +57,7 @@ import stgit.commands.series
 import stgit.commands.status
 import stgit.commands.top
 import stgit.commands.unapplied
+import stgit.commands.uncommit
 
 
 #
@@ -92,6 +93,7 @@ commands = {
     'status':   stgit.commands.status,
     'top':      stgit.commands.top,
     'unapplied':stgit.commands.unapplied,
+    'uncommit': stgit.commands.uncommit,
     }
 
 def print_help():
index 9ccbb1e..e1c55f0 100644 (file)
@@ -629,7 +629,8 @@ class Series:
                   unapplied = False, show_patch = False,
                   top = None, bottom = None,
                   author_name = None, author_email = None, author_date = None,
-                  committer_name = None, committer_email = None):
+                  committer_name = None, committer_email = None,
+                  before_existing = False):
         """Creates a new patch
         """
         if self.__patch_applied(name) or self.__patch_unapplied(name):
@@ -672,8 +673,13 @@ class Series:
             f.writelines([line + '\n' for line in patches])
             f.close()
         else:
-            append_string(self.__applied_file, patch.get_name())
-            self.__set_current(name)
+            if before_existing:
+                insert_string(self.__applied_file, patch.get_name())
+                if not self.get_current():
+                    self.__set_current(name)
+            else:
+                append_string(self.__applied_file, patch.get_name())
+                self.__set_current(name)
 
     def delete_patch(self, name):
         """Deletes a patch