git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Karl Hasselström" <kha@treskal.com>
To: Catalin Marinas <catalin.marinas@gmail.com>
Cc: git@vger.kernel.org, "David Kågedal" <davidk@lysator.liu.se>
Subject: [StGit PATCH 5/5] Make "stg commit" fancier
Date: Fri, 14 Dec 2007 07:32:36 +0100	[thread overview]
Message-ID: <20071214063236.29290.77674.stgit@yoghurt> (raw)
In-Reply-To: <20071214062618.29290.70792.stgit@yoghurt>

Allow the user to commit any patch. Changed behavior: with no
parameters, commit one applied patch, not all applied patches -- this
is what uncommit does.

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 stgit/commands/commit.py   |   87 +++++++++++++++++++++++++++++++++-----------
 stgit/commands/uncommit.py |    2 +
 stgit/lib/transaction.py   |    3 +-
 t/t1300-uncommit.sh        |   12 +++---
 4 files changed, 74 insertions(+), 30 deletions(-)


diff --git a/stgit/commands/commit.py b/stgit/commands/commit.py
index f822181..1d741b3 100644
--- a/stgit/commands/commit.py
+++ b/stgit/commands/commit.py
@@ -15,39 +15,82 @@ 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.commands import common
 from stgit.lib import transaction
 from stgit.out import *
 
 help = 'permanently store the applied patches into stack base'
-usage = """%prog [options]
+usage = """%prog [<patchnames>] | -n NUM | --all
 
-Merge the applied patches into the base of the current stack and
-remove them from the series while advancing the base.
+Merge one or more patches into the base of the current stack and
+remove them from the series while advancing the base. This is the
+opposite of 'stg uncommit'. Use this command if you no longer want to
+manage a patch with StGIT.
 
-Use this command only if you want to permanently store the applied
-patches and no longer manage them with StGIT."""
+By default, the bottommost patch is committed. If patch names are
+given, the stack is rearranged so that those patches are at the
+bottom, and then they are committed.
 
-directory = common.DirectoryHasRepositoryLib()
-options = []
+The -n/--number option specifies the number of applied patches to
+commit (counting from the bottom of the stack). If -a/--all is given,
+all applied patches are committed."""
 
+directory = common.DirectoryHasRepositoryLib()
+options = [make_option('-n', '--number', type = 'int',
+                       help = 'commit the specified number of patches'),
+           make_option('-a', '--all', action = 'store_true',
+                       help = 'commit all applied patches')]
 
 def func(parser, options, args):
-    """Merge the applied patches into the base of the current stack
-       and remove them from the series while advancing the base
-    """
-    if len(args) != 0:
-        parser.error('incorrect number of arguments')
-
+    """Commit a number of patches."""
     stack = directory.repository.current_stack
-    patches = stack.patchorder.applied
+    args = common.parse_patches(args, (list(stack.patchorder.applied)
+                                       + list(stack.patchorder.unapplied)))
+    if len([x for x in [args, options.number != None, options.all] if x]) > 1:
+        parser.error('too many options')
+    if args:
+        patches = [pn for pn in (stack.patchorder.applied
+                                 + stack.patchorder.unapplied) if pn in args]
+        bad = set(args) - set(patches)
+        if bad:
+            raise common.CmdException('Bad patch names: %s'
+                                      % ', '.join(sorted(bad)))
+    elif options.number != None:
+        if options.number <= len(stack.patchorder.applied):
+            patches = stack.patchorder.applied[:options.number]
+        else:
+            raise common.CmdException('There are not that many applied patches')
+    elif options.all:
+        patches = stack.patchorder.applied
+    else:
+        patches = stack.patchorder.applied[:1]
     if not patches:
-        raise CmdException('No patches to commit')
-    out.start('Committing %d patches' % len(patches))
+        raise common.CmdException('No patches to commit')
+
+    iw = stack.repository.default_iw()
     trans = transaction.StackTransaction(stack, 'stg commit')
-    for pn in patches:
-        trans.patches[pn] = None
-    trans.applied = []
-    trans.base = stack.head
-    trans.run()
-    out.done()
+    try:
+        common_prefix = 0
+        for i in xrange(min(len(stack.patchorder.applied), len(patches))):
+            if stack.patchorder.applied[i] == patches[i]:
+                common_prefix += 1
+        if common_prefix < len(patches):
+            to_push = trans.pop_patches(
+                lambda pn: pn in stack.patchorder.applied[common_prefix:])
+            for pn in patches[common_prefix:]:
+                trans.push_patch(pn, iw)
+        else:
+            to_push = []
+        new_base = trans.patches[patches[-1]]
+        for pn in patches:
+            trans.patches[pn] = None
+        trans.applied = [pn for pn in trans.applied if pn not in patches]
+        trans.base = new_base
+        out.info('Committed %d patch%s' % (len(patches),
+                                           ['es', ''][len(patches) == 1]))
+        for pn in to_push:
+            trans.push_patch(pn, iw)
+    except transaction.TransactionHalted:
+        pass
+    return trans.run(iw)
diff --git a/stgit/commands/uncommit.py b/stgit/commands/uncommit.py
index 8422952..933ec60 100644
--- a/stgit/commands/uncommit.py
+++ b/stgit/commands/uncommit.py
@@ -28,7 +28,7 @@ usage = """%prog [<patchnames>] | -n NUM [<prefix>]] | -t <committish> [-x]
 
 Take one or more git commits at the base of the current stack and turn
 them into StGIT patches. The new patches are created as applied patches
-at the bottom of the stack. This is the exact opposite of 'stg commit'.
+at the bottom of the stack. This is the opposite of 'stg commit'.
 
 By default, the number of patches to uncommit is determined by the
 number of patch names provided on the command line. First name is used
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index a7c4f7e..a60c5ff 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -51,7 +51,8 @@ class StackTransaction(object):
         self.__unapplied = list(val)
     unapplied = property(lambda self: self.__unapplied, __set_unapplied)
     def __set_base(self, val):
-        assert not self.__applied
+        assert (not self.__applied
+                or self.patches[self.applied[0]].data.parent == val)
         self.__base = val
     base = property(lambda self: self.__base, __set_base)
     def __checkout(self, tree, iw):
diff --git a/t/t1300-uncommit.sh b/t/t1300-uncommit.sh
index 85408fd..d86e579 100755
--- a/t/t1300-uncommit.sh
+++ b/t/t1300-uncommit.sh
@@ -35,7 +35,7 @@ test_expect_success \
 test_expect_success \
 	'Commit the patches' \
 	'
-	stg commit
+	stg commit --all
 	'
 
 test_expect_success \
@@ -43,7 +43,7 @@ test_expect_success \
 	'
 	stg uncommit bar foo &&
 	[ "$(stg id foo//top)" = "$(stg id bar//bottom)" ] &&
-	stg commit
+	stg commit --all
 	'
 
 test_expect_success \
@@ -51,7 +51,7 @@ test_expect_success \
 	'
 	stg uncommit --number=2 foobar &&
 	[ "$(stg id foobar1//top)" = "$(stg id foobar2//bottom)" ] &&
-	stg commit
+	stg commit --all
 	'
 
 test_expect_success \
@@ -59,7 +59,7 @@ test_expect_success \
 	'
 	stg uncommit --number=2 &&
 	[ "$(stg id foo-patch//top)" = "$(stg id bar-patch//bottom)" ] &&
-	stg commit
+	stg commit --all
 	'
 
 test_expect_success \
@@ -68,14 +68,14 @@ test_expect_success \
 	stg uncommit &&
 	stg uncommit &&
 	[ "$(stg id foo-patch//top)" = "$(stg id bar-patch//bottom)" ] &&
-	stg commit
+	stg commit --all
 	'
 
 test_expect_success \
     'Uncommit the patches with --to' '
     stg uncommit --to HEAD^ &&
     [ "$(stg id foo-patch//top)" = "$(stg id bar-patch//bottom)" ] &&
-    stg commit
+    stg commit --all
 '
 
 test_done

      parent reply	other threads:[~2007-12-14  6:33 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-14  6:32 [StGit PATCH 0/5] More experimental patches Karl Hasselström
2007-12-14  6:32 ` [StGit PATCH 1/5] Expose transaction abort function Karl Hasselström
2007-12-14  6:32 ` [StGit PATCH 2/5] stg coalesce: Support --file and --save-template Karl Hasselström
2007-12-14  6:32 ` [StGit PATCH 3/5] Set exit code to 3 on merge conflict Karl Hasselström
2007-12-14  6:32 ` [StGit PATCH 4/5] Convert "stg commit" to new infrastructure Karl Hasselström
2007-12-14  6:32 ` Karl Hasselström [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071214063236.29290.77674.stgit@yoghurt \
    --to=kha@treskal.com \
    --cc=catalin.marinas@gmail.com \
    --cc=davidk@lysator.liu.se \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).