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 = 'send patches deeper down the stack'
-usage = """%prog [-t <target patch>] [-n] [<patches>]
-
-Pop all patches (or all patches including <target patch>), then
-push the specified <patches> (the current patch by default), and
-then push back into place the formerly-applied patches (unless -n
-is also given)."""
-
-directory = DirectoryGotoToplevel()
-options = [make_option('-n', '--nopush',
- help = 'do not push the patches back after sinking',
- action = 'store_true'),
- make_option('-t', '--to', metavar = 'TARGET',
- help = 'sink patches below TARGET patch')]
+from stgit.argparse import opt
+from stgit.commands import common
+from stgit.lib import transaction
+from stgit import argparse
+
+help = 'Send patches deeper down the stack'
+kind = 'stack'
+usage = ['[-t <target patch>] [-n] [<patches>]']
+description = """
+This is the opposite operation of linkstg:float[]: move the specified
+patches down the stack. It is for example useful to group stable
+patches near the bottom of the stack, where they are less likely to be
+impacted by the push of another patch, and from where they can be more
+easily committed or pushed.
+
+If no patch is specified on command-line, the current patch gets sunk.
+By default patches are sunk to the bottom of the stack, but the '--to'
+option allows to place them under any applied patch.
+
+Sinking internally involves popping all patches (or all patches
+including <target patch>), then pushing the patches to sink, and then
+(unless '--nopush' is also given) pushing back into place the
+formerly-applied patches."""
+
+args = [argparse.patch_range(argparse.applied_patches,
+ argparse.unapplied_patches)]
+options = [
+ opt('-n', '--nopush', action = 'store_true',
+ short = 'Do not push the patches back after sinking', long = """
+ Do not push back on the stack the formerly-applied patches.
+ Only the patches to sink are pushed."""),
+ opt('-t', '--to', metavar = 'TARGET', args = [argparse.applied_patches],
+ short = 'Sink patches below the TARGET patch', long = """
+ Specify a target patch to place the patches below, instead of
+ sinking them to the bottom of the stack.""")
+ ] + argparse.keep_option()
+
+directory = common.DirectoryHasRepositoryLib()
def func(parser, options, args):
"""Sink patches down the stack.
"""
+ stack = directory.repository.current_stack
- check_local_changes()
- check_conflicts()
- check_head_top_equal(crt_series)
+ if options.to and not options.to in stack.patchorder.applied:
+ raise common.CmdException('Cannot sink below %s since it is not applied'
+ % options.to)
- oldapplied = crt_series.get_applied()
- unapplied = crt_series.get_unapplied()
- all = unapplied + oldapplied
+ if len(args) > 0:
+ patches = common.parse_patches(args, stack.patchorder.all)
+ else:
+ # current patch
+ patches = list(stack.patchorder.applied[-1:])
- if options.to and not options.to in oldapplied:
- raise CmdException('Cannot sink below %s, since it is not applied'
- % options.to)
+ if not patches:
+ raise common.CmdException('No patches to sink')
+ if options.to and options.to in patches:
+ raise common.CmdException('Cannot have a sinked patch as target')
- if len(args) > 0:
- patches = parse_patches(args, all)
+ applied = [p for p in stack.patchorder.applied if p not in patches]
+ if options.to:
+ insert_idx = applied.index(options.to)
else:
- current = crt_series.get_current()
- if not current:
- raise CmdException('No patch applied')
- patches = [current]
-
- if oldapplied:
- crt_series.pop_patch(options.to or oldapplied[0])
- push_patches(crt_series, patches)
-
- if not options.nopush:
- newapplied = crt_series.get_applied()
- def not_reapplied_yet(p):
- return not p in newapplied
- push_patches(crt_series, filter(not_reapplied_yet, oldapplied))
+ insert_idx = 0
+ applied = applied[:insert_idx] + patches + applied[insert_idx:]
+ unapplied = [p for p in stack.patchorder.unapplied if p not in patches]
+
+ iw = stack.repository.default_iw
+ clean_iw = (not options.keep and iw) or None
+ trans = transaction.StackTransaction(stack, 'sink',
+ check_clean_iw = clean_iw)
+
+ try:
+ trans.reorder_patches(applied, unapplied, iw = iw)
+ except transaction.TransactionHalted:
+ pass
+ return trans.run(iw)