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@xxxxxxxxxxx> --- 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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html