Merge branch 'stable'
[stgit] / stgit / commands / pop.py
CommitLineData
fcee87cf
CM
1
2__copyright__ = """
3Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License version 2 as
7published by the Free Software Foundation.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17"""
18
19import sys, os
575bbdae 20from stgit.argparse import opt
fcee87cf
CM
21from stgit.commands.common import *
22from stgit.utils import *
6c8a90e1 23from stgit import argparse, stack, git
fcee87cf 24
575bbdae 25help = 'Pop one or more patches from the stack'
33ff9cdd 26kind = 'stack'
575bbdae
KH
27usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
28description = """
d1368d81
CM
29Pop the topmost patch or a range of patches from the stack. The
30command fails if there are conflicts or local changes (and --keep was
31not specified).
32
33A series of pop and push operations are performed so that only the
34patches passed on the command line are popped from the stack. Some of
625e8de7 35the push operations may fail because of conflicts ("stg undo" would
d1368d81 36revert the last push operation)."""
fcee87cf 37
6c8a90e1 38args = [argparse.patch_range(argparse.applied_patches)]
575bbdae
KH
39options = [
40 opt('-a', '--all', action = 'store_true',
41 short = 'Pop all the applied patches'),
42 opt('-n', '--number', type = 'int',
43 short = 'Pop the specified number of patches'),
44 opt('-k', '--keep', action = 'store_true',
45 short = 'Keep the local changes')]
fcee87cf 46
117ed129 47directory = DirectoryGotoToplevel(log = True)
fcee87cf
CM
48
49def func(parser, options, args):
50 """Pop the topmost patch from the stack
51 """
e45af3d4 52 check_conflicts()
6972fd6b 53 check_head_top_equal(crt_series)
e45af3d4 54
f46f4413
CM
55 if not options.keep:
56 check_local_changes()
fcee87cf
CM
57
58 applied = crt_series.get_applied()
59 if not applied:
60 raise CmdException, 'No patches applied'
fcee87cf 61
6b1e0111
CM
62 if options.all:
63 patches = applied
fcee87cf 64 elif options.number:
d1368d81
CM
65 # reverse it twice to also work with negative or bigger than
66 # the length numbers
67 patches = applied[::-1][:options.number][::-1]
68 elif len(args) == 0:
69 patches = [applied[-1]]
fcee87cf 70 else:
d1368d81 71 patches = parse_patches(args, applied, ordered = True)
fcee87cf 72
d1368d81 73 if not patches:
fcee87cf
CM
74 raise CmdException, 'No patches to pop'
75
d1368d81
CM
76 # pop to the most distant popped patch
77 topop = applied[applied.index(patches[0]):]
78 # push those not in the popped range
79 topush = [p for p in topop if p not in patches]
80
81 if options.keep and topush:
82 raise CmdException, 'Cannot pop arbitrary patches with --keep'
83
84 topop.reverse()
6972fd6b 85 pop_patches(crt_series, topop, options.keep)
d1368d81 86 if topush:
6972fd6b 87 push_patches(crt_series, topush)
fcee87cf 88
6972fd6b 89 print_crt_patch(crt_series)