"""
import sys, os
-from optparse import OptionParser, make_option
-
+from stgit.argparse import opt
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)."""
-
-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 import argparse, stack, git
+
+help = 'Send patches deeper down the stack'
+kind = 'stack'
+usage = ['[-t <target patch>] [-n] [<patches>]']
+description = """
+This is the opposite operation of stglink: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.""")]
+
+directory = DirectoryGotoToplevel(log = True)
def func(parser, options, args):
"""Sink patches down the stack.
check_local_changes()
check_conflicts()
- check_head_top_equal()
+ check_head_top_equal(crt_series)
oldapplied = crt_series.get_applied()
unapplied = crt_series.get_unapplied()
- all = unapplied + oldapplied
+ all = oldapplied + unapplied
+
+ if options.to and not options.to in oldapplied:
+ raise CmdException('Cannot sink below %s, since it is not applied'
+ % options.to)
if len(args) > 0:
patches = parse_patches(args, all)
else:
- patches = [ crt_series.get_current() ]
-
- crt_series.pop_patch(options.to or oldapplied[0])
- push_patches(patches)
-
+ current = crt_series.get_current()
+ if not current:
+ raise CmdException('No patch applied')
+ patches = [current]
+
+ before_patches = after_patches = []
+
+ # pop necessary patches
+ if oldapplied:
+ if options.to:
+ pop_idx = oldapplied.index(options.to)
+ else:
+ pop_idx = 0
+ after_patches = [p for p in oldapplied[pop_idx:] if p not in patches]
+
+ # find the deepest patch to pop
+ sink_applied = [p for p in oldapplied if p in patches]
+ if sink_applied:
+ sinked_idx = oldapplied.index(sink_applied[0])
+ if sinked_idx < pop_idx:
+ # this is the case where sink brings patches forward
+ before_patches = [p for p in oldapplied[sinked_idx:pop_idx]
+ if p not in patches]
+ pop_idx = sinked_idx
+
+ crt_series.pop_patch(oldapplied[pop_idx])
+
+ push_patches(crt_series, before_patches)
+ 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(filter(not_reapplied_yet, oldapplied))
+ push_patches(crt_series, after_patches)