X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/fcee87cf868f18a3d684c3ba71232574f92c7b11..2b4b9c29d1bc5d98eafdfdc82b99b57ebd4298d0:/stgit/commands/push.py diff --git a/stgit/commands/push.py b/stgit/commands/push.py index 65462b3..9924a78 100644 --- a/stgit/commands/push.py +++ b/stgit/commands/push.py @@ -25,7 +25,18 @@ from stgit import stack, git help = 'push a patch on top of the series' -usage = '%prog [options] []' +usage = """%prog [options] [] + +Push a patch (defaulting to the first unapplied one) or range of +patches to 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 patch and the +tree to the state before the operation. Conflicts raised during the +push operation have to be fixed and the 'resolved' command run. + +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', @@ -43,9 +54,19 @@ options = [make_option('-a', '--all', action = 'store_true')] +def is_patch_appliable(p): + """See if patch exists, or is already applied. + """ + if p in applied: + raise CmdException, 'Patch "%s" is already applied.' % p + if p not in unapplied: + raise CmdException, 'Patch "%s" does not exist.' % p + def func(parser, options, args): """Pushes the given patch or all onto the series """ + global applied, unapplied + # If --undo is passed, do the work and exit if options.undo: patch = crt_series.get_current() @@ -55,8 +76,10 @@ def func(parser, options, args): print 'Undoing the "%s" push...' % patch, sys.stdout.flush() resolved_all() - crt_series.undo_push() - print 'done' + if crt_series.undo_push(): + print 'done' + else: + print 'done (patch unchanged)' print_crt_patch() return @@ -65,6 +88,7 @@ def func(parser, options, args): check_conflicts() check_head_top_equal() + applied = crt_series.get_applied() unapplied = crt_series.get_unapplied() if not unapplied: raise CmdException, 'No more patches to push' @@ -72,14 +96,11 @@ def func(parser, options, args): if options.to: boundaries = options.to.split(':') if len(boundaries) == 1: - if boundaries[0] not in unapplied: - raise CmdException, 'Patch "%s" not unapplied' % boundaries[0] + is_patch_appliable(boundaries[0]) patches = unapplied[:unapplied.index(boundaries[0])+1] elif len(boundaries) == 2: - if boundaries[0] not in unapplied: - raise CmdException, 'Patch "%s" not unapplied' % boundaries[0] - if boundaries[1] not in unapplied: - raise CmdException, 'Patch "%s" not unapplied' % boundaries[1] + is_patch_appliable(boundaries[0]) + is_patch_appliable(boundaries[1]) lb = unapplied.index(boundaries[0]) hb = unapplied.index(boundaries[1]) if lb > hb: @@ -95,7 +116,8 @@ def func(parser, options, args): elif len(args) == 0: patches = [unapplied[0]] elif len(args) == 1: - patches = [args[0]] + patches = args + is_patch_appliable(patches[0]) else: parser.error('incorrect number of arguments') @@ -105,14 +127,25 @@ def func(parser, options, args): if options.reverse: patches.reverse() - for p in patches: + forwarded = crt_series.forward_patches(patches) + if forwarded > 1: + print 'Fast-forwarded patches "%s" - "%s"' % (patches[0], + patches[forwarded - 1]) + elif forwarded == 1: + print 'Fast-forwarded patch "%s"' % patches[0] + + for p in patches[forwarded:]: + is_patch_appliable(p) + print 'Pushing patch "%s"...' % p, sys.stdout.flush() - crt_series.push_patch(p) + modified = crt_series.push_patch(p) if crt_series.empty_patch(p): print 'done (empty patch)' + elif modified: + print 'done (modified)' else: print 'done' print_crt_patch()