X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/53f76663a55fc98d43d283dbef2306aac880d771..9ab06b9858bbb0196867506724a8d74c8f39e113:/stgit/commands/push.py diff --git a/stgit/commands/push.py b/stgit/commands/push.py index a636ad2..d5e02e0 100644 --- a/stgit/commands/push.py +++ b/stgit/commands/push.py @@ -16,88 +16,87 @@ 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 = 'push one or more patches onto of the stack' -usage = """%prog [options] [] [] [..] - +from stgit.commands import common +from stgit.lib import transaction +from stgit import argparse +from stgit.argparse import opt + +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.""" -options = [make_option('-a', '--all', - help = 'push all the unapplied patches', - action = 'store_true'), - make_option('-n', '--number', type = 'int', - help = 'push the specified number of patches'), - make_option('--reverse', - help = 'push the patches in reverse order', - action = 'store_true'), - make_option('-m', '--merged', - help = 'check for patches merged upstream', - action = 'store_true'), - make_option('--undo', - help = 'undo the last patch pushing', - action = 'store_true')] - +args = [argparse.patch_range(argparse.unapplied_patches)] +options = [ + opt('-a', '--all', action = 'store_true', + short = 'Push all the unapplied patches'), + opt('-n', '--number', type = 'int', + short = 'Push the specified number of patches'), + opt('--reverse', action = 'store_true', + short = 'Push the patches in reverse order'), + 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. + + 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' - - print 'Undoing the "%s" push...' % patch, - sys.stdout.flush() - resolved_all() - if crt_series.undo_push(): - print 'done' - else: - print 'done (patch unchanged)' - print_crt_patch() - - return - - check_local_changes() - check_conflicts() - check_head_top_equal() - - 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(patches, options.merged) - - print_crt_patch() + 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)