Commit | Line | Data |
---|---|---|
de7a79c4 YD |
1 | |
2 | __copyright__ = """ | |
3 | Copyright (C) 2007, Yann Dirson <ydirson@altern.org> | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License version 2 as | |
7 | published by the Free Software Foundation. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software | |
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 | """ | |
18 | ||
19 | import sys, os | |
575bbdae | 20 | from stgit.argparse import opt |
de7a79c4 YD |
21 | from stgit.commands.common import * |
22 | from stgit.utils import * | |
6c8a90e1 | 23 | from stgit import argparse, stack, git |
de7a79c4 | 24 | |
575bbdae | 25 | help = 'Send patches deeper down the stack' |
33ff9cdd | 26 | kind = 'stack' |
575bbdae KH |
27 | usage = ['[-t <target patch>] [-n] [<patches>]'] |
28 | description = """ | |
29 | This is the opposite operation of stglink:float[]: move the specified | |
30 | patches down the stack. It is for example useful to group stable | |
31 | patches near the bottom of the stack, where they are less likely to be | |
32 | impacted by the push of another patch, and from where they can be more | |
33 | easily committed or pushed. | |
34 | ||
35 | If no patch is specified on command-line, the current patch gets sunk. | |
36 | By default patches are sunk to the bottom of the stack, but the '--to' | |
37 | option allows to place them under any applied patch. | |
de7a79c4 | 38 | |
575bbdae KH |
39 | Sinking internally involves popping all patches (or all patches |
40 | including <target patch>), then pushing the patches to sink, and then | |
41 | (unless '--nopush' is also given) pushing back into place the | |
42 | formerly-applied patches.""" | |
de7a79c4 | 43 | |
6c8a90e1 KH |
44 | args = [argparse.patch_range(argparse.applied_patches, |
45 | argparse.unapplied_patches)] | |
575bbdae KH |
46 | options = [ |
47 | opt('-n', '--nopush', action = 'store_true', | |
48 | short = 'Do not push the patches back after sinking', long = """ | |
49 | Do not push back on the stack the formerly-applied patches. | |
50 | Only the patches to sink are pushed."""), | |
6c8a90e1 | 51 | opt('-t', '--to', metavar = 'TARGET', args = [argparse.applied_patches], |
575bbdae KH |
52 | short = 'Sink patches below the TARGET patch', long = """ |
53 | Specify a target patch to place the patches below, instead of | |
54 | sinking them to the bottom of the stack.""")] | |
de7a79c4 | 55 | |
117ed129 | 56 | directory = DirectoryGotoToplevel(log = True) |
de7a79c4 YD |
57 | |
58 | def func(parser, options, args): | |
6f1c5e3c | 59 | """Sink patches down the stack. |
de7a79c4 YD |
60 | """ |
61 | ||
62 | check_local_changes() | |
63 | check_conflicts() | |
6972fd6b | 64 | check_head_top_equal(crt_series) |
de7a79c4 YD |
65 | |
66 | oldapplied = crt_series.get_applied() | |
67 | unapplied = crt_series.get_unapplied() | |
8bcdcdc9 | 68 | all = oldapplied + unapplied |
de7a79c4 | 69 | |
74477393 KH |
70 | if options.to and not options.to in oldapplied: |
71 | raise CmdException('Cannot sink below %s, since it is not applied' | |
72 | % options.to) | |
73 | ||
de7a79c4 YD |
74 | if len(args) > 0: |
75 | patches = parse_patches(args, all) | |
76 | else: | |
cd65a83b KH |
77 | current = crt_series.get_current() |
78 | if not current: | |
79 | raise CmdException('No patch applied') | |
80 | patches = [current] | |
de7a79c4 | 81 | |
8bcdcdc9 CM |
82 | before_patches = after_patches = [] |
83 | ||
84 | # pop necessary patches | |
cd65a83b | 85 | if oldapplied: |
8bcdcdc9 CM |
86 | if options.to: |
87 | pop_idx = oldapplied.index(options.to) | |
88 | else: | |
89 | pop_idx = 0 | |
90 | after_patches = [p for p in oldapplied[pop_idx:] if p not in patches] | |
91 | ||
92 | # find the deepest patch to pop | |
93 | sink_applied = [p for p in oldapplied if p in patches] | |
94 | if sink_applied: | |
95 | sinked_idx = oldapplied.index(sink_applied[0]) | |
96 | if sinked_idx < pop_idx: | |
97 | # this is the case where sink brings patches forward | |
98 | before_patches = [p for p in oldapplied[sinked_idx:pop_idx] | |
99 | if p not in patches] | |
100 | pop_idx = sinked_idx | |
101 | ||
102 | crt_series.pop_patch(oldapplied[pop_idx]) | |
103 | ||
104 | push_patches(crt_series, before_patches) | |
6972fd6b | 105 | push_patches(crt_series, patches) |
de7a79c4 | 106 | if not options.nopush: |
8bcdcdc9 | 107 | push_patches(crt_series, after_patches) |