X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/575bbdaeb6b8fae0eef19672d288361282b83fb4..9ab06b9858bbb0196867506724a8d74c8f39e113:/stgit/commands/push.py diff --git a/stgit/commands/push.py b/stgit/commands/push.py index ee7b56e..d5e02e0 100644 --- a/stgit/commands/push.py +++ b/stgit/commands/push.py @@ -16,27 +16,27 @@ 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 stgit.commands import common +from stgit.lib import transaction +from stgit import argparse from stgit.argparse import opt -from stgit.commands.common import * -from stgit.utils import * -from stgit.out import * -from stgit import stack, git help = 'Push one or more patches onto the stack' +kind = 'stack' usage = ['[options] [] [] [..]'] description = """ Push one or more patches (defaulting to the first unapplied one) onto the stack. The 'push' operation allows patch reordering by commuting -them with the three-way merge algorithm. If the result of the 'push' -operation is not acceptable or if there are too many conflicts, the -'--undo' option can be used to revert the last pushed patch. Conflicts -raised during the push operation have to be fixed and the 'resolved' -command run. +them with the three-way merge algorithm. If there are conflicts while +pushing a patch, those conflicts are written to the work tree, and the +command halts. Conflicts raised during the push operation have to be +fixed and the 'git add --update' command run (alternatively, you may +undo the conflicting push with 'stg undo'). The command also notifies when the patch becomes empty (fully merged upstream) or is modified (three-way merged) by the 'push' operation.""" +args = [argparse.patch_range(argparse.unapplied_patches)] options = [ opt('-a', '--all', action = 'store_true', short = 'Push all the unapplied patches'), @@ -44,56 +44,59 @@ options = [ short = 'Push the specified number of patches'), opt('--reverse', action = 'store_true', short = 'Push the patches in reverse order'), - opt('-m', '--merged', action = 'store_true', - short = 'Check for patches merged upstream'), - opt('--undo', action = 'store_true', - short = 'Undo the last patch pushing')] + opt('--set-tree', action = 'store_true', + short = 'Push the patch with the original tree', long = """ + Push the patches, but don't perform a merge. Instead, the + resulting tree will be identical to the tree that the patch + previously created. -directory = DirectoryGotoToplevel() + This can be useful when splitting a patch by first popping the + patch and creating a new patch with some of the + changes. Pushing the original patch with '--set-tree' will + avoid conflicts and only the remaining changes will be in the + patch.""") + ] + argparse.keep_option() + argparse.merged_option() + +directory = common.DirectoryHasRepositoryLib() def func(parser, options, args): - """Pushes the given patch or all onto the series - """ - - # If --undo is passed, do the work and exit - if options.undo: - patch = crt_series.get_current() - if not patch: - raise CmdException, 'No patch to undo' - - out.start('Undoing push of "%s"' % patch) - resolved_all() - if crt_series.undo_push(): - out.done() - else: - out.done('patch unchanged') - print_crt_patch(crt_series) - - return - - check_local_changes() - check_conflicts() - check_head_top_equal(crt_series) - - unapplied = crt_series.get_unapplied() - if not unapplied: - raise CmdException, 'No more patches to push' - - if options.number: - patches = unapplied[:options.number] - elif options.all: - patches = unapplied - elif len(args) == 0: - patches = [unapplied[0]] + """Pushes the given patches or the first unapplied onto the stack.""" + stack = directory.repository.current_stack + iw = stack.repository.default_iw + clean_iw = (not options.keep and iw) or None + trans = transaction.StackTransaction(stack, 'pop', + check_clean_iw = clean_iw) + + if not trans.unapplied: + raise common.CmdException('No patches to push') + + if options.all: + patches = list(trans.unapplied) + elif options.number: + patches = trans.unapplied[:options.number] + elif not args: + patches = [trans.unapplied[0]] else: - patches = parse_patches(args, unapplied) + patches = common.parse_patches(args, trans.unapplied) - if patches == []: - raise CmdException, 'No patches to push' + if not patches: + raise common.CmdException('No patches to push') if options.reverse: patches.reverse() - push_patches(crt_series, patches, options.merged) - - print_crt_patch(crt_series) + if options.set_tree: + for pn in patches: + trans.push_tree(pn) + else: + try: + if options.merged: + merged = set(trans.check_merged(patches)) + else: + merged = set() + for pn in patches: + trans.push_patch(pn, iw, allow_interactive = True, + already_merged = pn in merged) + except transaction.TransactionHalted: + pass + return trans.run(iw)