chiark / gitweb /
Fix the branch protect/unprotect message
[stgit] / stgit / commands / branch.py
CommitLineData
7b1ba1a6
CL
1"""Branch command
2"""
3
4__copyright__ = """
5Copyright (C) 2005, Chuck Lever <cel@netapp.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License version 2 as
9published by the Free Software Foundation.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19"""
20
21import sys, os
22from optparse import OptionParser, make_option
23
24from stgit.commands.common import *
25from stgit.utils import *
26from stgit import stack, git
27
28
29help = 'manage development branches'
30usage = """%prog [options] branch-name [commit-id]
31
32Create, list, switch between, rename, or delete development branches
33within a git repository. By default, a single branch called 'master'
34is always created in a new repository. This subcommand allows you to
35manage several patch series in the same repository.
36
37When displaying the branches, the names can be prefixed with
38's' (StGIT managed) or 'p' (protected)."""
39
40options = [make_option('-c', '--create',
41 help = 'create a new development branch',
42 action = 'store_true'),
43 make_option('--delete',
44 help = 'delete an existing development branch',
45 action = 'store_true'),
46 make_option('--force',
47 help = 'force a delete when the series is not empty',
48 action = 'store_true'),
49 make_option('-l', '--list',
50 help = 'list branches contained in this repository',
51 action = 'store_true'),
0b4b9499
CL
52 make_option('-p', '--protect',
53 help = 'prevent "stg pull" from modifying this branch',
54 action = 'store_true'),
7b1ba1a6
CL
55 make_option('-r', '--rename',
56 help = 'rename an existing development branch',
0b4b9499
CL
57 action = 'store_true'),
58 make_option('-u', '--unprotect',
59 help = 'allow "stg pull" to modify this branch',
7b1ba1a6
CL
60 action = 'store_true')]
61
62
63def is_current_branch(branch_name):
64 return git.get_head_file() == branch_name
65
66def print_branch(branch_name):
67 initialized = ' '
68 current = ' '
0b4b9499 69 protected = ' '
7b1ba1a6
CL
70 if os.path.isdir(os.path.join(git.base_dir, 'patches', branch_name)):
71 initialized = 's'
72 if is_current_branch(branch_name):
73 current = '>'
0b4b9499
CL
74 if stack.Series(branch_name).get_protected():
75 protected = 'p'
c1fe1f99
CL
76 print '%s %s%s\t%s\t%s' % (current, initialized, protected, branch_name, \
77 stack.Series(branch_name).get_description())
7b1ba1a6
CL
78
79def delete_branch(doomed_name, force = False):
0b4b9499
CL
80 if stack.Series(doomed_name).get_protected():
81 raise CmdException, 'This branch is protected. Delete is not permitted'
82
7b1ba1a6
CL
83 if is_current_branch(doomed_name) and doomed_name != 'master':
84 git.switch_branch('master')
85
86 stack.Series(doomed_name).delete(force)
87
88 if doomed_name != 'master':
89 git.delete_branch(doomed_name)
90
91 print 'Branch "%s" has been deleted.' % doomed_name
92
93def rename_branch(from_name, to_name):
94 if from_name == 'master':
95 raise CmdException, 'Renaming the master branch is not allowed'
96
97 to_patchdir = os.path.join(git.base_dir, 'patches', to_name)
98 if os.path.isdir(to_patchdir):
99 raise CmdException, '"%s" already exists' % to_patchdir
100 to_base = os.path.join(git.base_dir, 'refs', 'bases', to_name)
101 if os.path.isfile(to_base):
102 raise CmdException, '"%s" already exists' % to_base
103
104 git.rename_branch(from_name, to_name)
105
106 from_patchdir = os.path.join(git.base_dir, 'patches', from_name)
107 if os.path.isdir(from_patchdir):
108 os.rename(from_patchdir, to_patchdir)
109 from_base = os.path.join(git.base_dir, 'refs', 'bases', from_name)
110 if os.path.isfile(from_base):
111 os.rename(from_base, to_base)
112
113 print 'Renamed branch "%s" as "%s".' % (from_name, to_name)
114
115def func(parser, options, args):
116
117 if options.create:
118
119 if len(args) == 0 or len(args) > 2:
120 parser.error('incorrect number of arguments')
121 tree_id = None
122 if len(args) == 2:
123 tree_id = args[1]
124
125 git.create_branch(args[0], tree_id)
126 stack.Series(args[0]).init()
127
128 print 'Branch "%s" created.' % args[0]
129 return
130
131 elif options.delete:
132
133 if len(args) != 1:
134 parser.error('incorrect number of arguments')
135 delete_branch(args[0], options.force)
136 return
137
138 elif options.list:
139
140 if len(args) != 0:
141 parser.error('incorrect number of arguments')
142
143 branches = os.listdir(os.path.join(git.base_dir, 'refs', 'heads'))
144 branches.sort()
145
146 print 'Available branches:'
147 for i in branches:
148 print_branch(i)
149 return
150
0b4b9499
CL
151 elif options.protect:
152
153 if len(args) == 0:
154 branch = git.get_head_file()
155 elif len(args) == 1:
156 branch = args[0]
157 else:
158 parser.error('incorrect number of arguments')
159
160 base = os.path.join(git.base_dir, 'refs', 'bases', branch)
161 if not os.path.isfile(base):
162 raise CmdException, 'Branch "%s" is not controlled by StGit' % branch
163
fa08ec08
CM
164 print 'Protecting branch "%s"...' % branch,
165 sys.stdout.flush()
0b4b9499 166 stack.Series(branch).protect()
fa08ec08
CM
167 print 'done'
168
0b4b9499
CL
169 return
170
7b1ba1a6
CL
171 elif options.rename:
172
173 if len(args) != 2:
174 parser.error('incorrect number of arguments')
175 rename_branch(args[0], args[1])
176 return
177
0b4b9499
CL
178 elif options.unprotect:
179
180 if len(args) == 0:
181 branch = git.get_head_file()
182 elif len(args) == 1:
183 branch = args[0]
184 else:
185 parser.error('incorrect number of arguments')
186
187 base = os.path.join(git.base_dir, 'refs', 'bases', branch)
188 if not os.path.isfile(base):
189 raise CmdException, 'Branch "%s" is not controlled by StGit' % branch
190
fa08ec08
CM
191 print 'Unprotecting branch "%s"...' % branch,
192 sys.stdout.flush()
0b4b9499 193 stack.Series(branch).unprotect()
fa08ec08
CM
194 print 'done'
195
0b4b9499
CL
196 return
197
7b1ba1a6
CL
198 elif len(args) == 1:
199
200 print 'Switching to branch "%s"...' % args[0],
201 sys.stdout.flush()
202
203 git.switch_branch(args[0])
204
205 print 'done'
206 return
207
208 # default action: print the current branch
209 if len(args) != 0:
210 parser.error('incorrect number of arguments')
211
212 print git.get_head_file()