Implement "stg refresh --edit" again
[stgit] / stgit / commands / coalesce.py
index e3e1629..ef8e912 100644 (file)
@@ -17,15 +17,16 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-from optparse import make_option
+from stgit.argparse import opt
 from stgit.out import *
-from stgit import utils
+from stgit import argparse, utils
 from stgit.commands import common
 from stgit.lib import git, transaction
 
-help = 'coalesce two or more patches into one'
-usage = """%prog [options] <patches>
-
+help = 'Coalesce two or more patches into one'
+kind = 'stack'
+usage = ['[options] <patches>']
+description = """
 Coalesce two or more patches, creating one big patch that contains all
 their changes.
 
@@ -33,14 +34,17 @@ If there are conflicts when reordering the patches to match the order
 you specify, you will have to resolve them manually just as if you had
 done a sequence of pushes and pops yourself."""
 
+options = [opt('-n', '--name', short = 'Name of coalesced patch')
+           ] + argparse.message_options(save_template = True)
+
 directory = common.DirectoryHasRepositoryLib()
-options = [make_option('-n', '--name', help = 'name of coalesced patch'),
-           make_option('-m', '--message',
-                       help = 'commit message of coalesced patch')]
 
-def _coalesce_patches(trans, patches, msg):
+class SaveTemplateDone(Exception):
+    pass
+
+def _coalesce_patches(trans, patches, msg, save_template):
     cd = trans.patches[patches[0]].data
-    cd = git.Commitdata(tree = cd.tree, parents = cd.parents)
+    cd = git.CommitData(tree = cd.tree, parents = cd.parents)
     for pn in patches[1:]:
         c = trans.patches[pn]
         tree = trans.stack.repository.simple_merge(
@@ -53,12 +57,16 @@ def _coalesce_patches(trans, patches, msg):
         msg = '\n\n'.join('%s\n\n%s' % (pn.ljust(70, '-'),
                                         trans.patches[pn].data.message)
                           for pn in patches)
-        msg = utils.edit_string(msg, '.stgit-coalesce.txt').strip()
+        if save_template:
+            save_template(msg)
+            raise SaveTemplateDone()
+        else:
+            msg = utils.edit_string(msg, '.stgit-coalesce.txt').strip()
     cd = cd.set_message(msg)
 
     return cd
 
-def _coalesce(stack, iw, name, msg, patches):
+def _coalesce(stack, iw, name, msg, save_template, patches):
 
     # If a name was supplied on the command line, make sure it's OK.
     def bad_name(pn):
@@ -73,10 +81,11 @@ def _coalesce(stack, iw, name, msg, patches):
         trans.patches[name] = stack.repository.commit(new_commit_data)
         trans.unapplied.insert(0, name)
 
-    trans = transaction.StackTransaction(stack, 'stg coalesce')
+    trans = transaction.StackTransaction(stack, 'coalesce',
+                                         allow_conflicts = True)
     push_new_patch = bool(set(patches) & set(trans.applied))
-    new_commit_data = _coalesce_patches(trans, patches, msg)
     try:
+        new_commit_data = _coalesce_patches(trans, patches, msg, save_template)
         if new_commit_data:
             # We were able to construct the coalesced commit
             # automatically. So just delete its constituent patches.
@@ -88,7 +97,8 @@ def _coalesce(stack, iw, name, msg, patches):
             to_push = trans.pop_patches(lambda pn: pn in patches)
             for pn in patches:
                 trans.push_patch(pn, iw)
-            new_commit_data = _coalesce_patches(trans, patches, msg)
+            new_commit_data = _coalesce_patches(trans, patches, msg,
+                                                save_template)
             assert not trans.delete_patches(lambda pn: pn in patches)
         make_coalesced_patch(trans, new_commit_data)
 
@@ -98,15 +108,17 @@ def _coalesce(stack, iw, name, msg, patches):
             trans.push_patch(get_name(new_commit_data), iw)
         for pn in to_push:
             trans.push_patch(pn, iw)
+    except SaveTemplateDone:
+        trans.abort(iw)
+        return
     except transaction.TransactionHalted:
         pass
-    trans.run(iw)
+    return trans.run(iw)
 
 def func(parser, options, args):
     stack = directory.repository.current_stack
-    patches = common.parse_patches(args, (list(stack.patchorder.applied)
-                                          + list(stack.patchorder.unapplied)))
+    patches = common.parse_patches(args, list(stack.patchorder.all))
     if len(patches) < 2:
         raise common.CmdException('Need at least two patches')
-    _coalesce(stack, stack.repository.default_iw(),
-              options.name, options.message, patches)
+    return _coalesce(stack, stack.repository.default_iw, options.name,
+                     options.message, options.save_template, patches)