5 Copyright (C) 2005, Chuck Lever <cel@netapp.com>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 from optparse import OptionParser, make_option
24 from stgit.commands.common import *
25 from stgit.utils import *
26 from stgit import stack, git
29 help = 'manage development branches'
30 usage = """%prog [options] branch-name [commit-id]
32 Create, clone, switch between, rename, or delete development branches
33 within a git repository. By default, a single branch called 'master'
34 is always created in a new repository. This subcommand allows you to
35 manage several patch series in the same repository via GIT branches.
37 When displaying the branches, the names can be prefixed with
38 's' (StGIT managed) or 'p' (protected).
40 If not given any options, switch to the named branch."""
42 options = [make_option('-c', '--create',
43 help = 'create a new development branch',
44 action = 'store_true'),
45 make_option('--clone',
46 help = 'clone the contents of the current branch',
47 action = 'store_true'),
48 make_option('--convert',
49 help = 'switch between old and new format branches',
50 action = 'store_true'),
51 make_option('--delete',
52 help = 'delete an existing development branch',
53 action = 'store_true'),
54 make_option('--force',
55 help = 'force a delete when the series is not empty',
56 action = 'store_true'),
57 make_option('-l', '--list',
58 help = 'list branches contained in this repository',
59 action = 'store_true'),
60 make_option('-p', '--protect',
61 help = 'prevent "stg pull" from modifying this branch',
62 action = 'store_true'),
63 make_option('-r', '--rename',
64 help = 'rename an existing development branch',
65 action = 'store_true'),
66 make_option('-u', '--unprotect',
67 help = 'allow "stg pull" to modify this branch',
68 action = 'store_true')]
71 def __is_current_branch(branch_name):
72 return crt_series.get_branch() == branch_name
74 def __print_branch(branch_name, length):
79 branch = stack.Series(branch_name)
81 if branch.is_initialised():
83 if __is_current_branch(branch_name):
85 if branch.get_protected():
87 print current + ' ' + initialized + protected + '\t' + \
88 branch_name.ljust(length) + ' | ' + branch.get_description()
90 def __delete_branch(doomed_name, force = False):
91 doomed = stack.Series(doomed_name)
93 if doomed.get_protected():
94 raise CmdException, 'This branch is protected. Delete is not permitted'
96 print 'Deleting branch "%s"...' % doomed_name,
99 if __is_current_branch(doomed_name):
100 check_local_changes()
102 check_head_top_equal()
104 if doomed_name != 'master':
105 git.switch_branch('master')
109 if doomed_name != 'master':
110 git.delete_branch(doomed_name)
114 def func(parser, options, args):
118 if len(args) == 0 or len(args) > 2:
119 parser.error('incorrect number of arguments')
121 check_local_changes()
123 check_head_top_equal()
129 git.create_branch(args[0], tree_id)
130 stack.Series(args[0]).init()
132 print 'Branch "%s" created.' % args[0]
138 clone = crt_series.get_branch() + \
139 time.strftime('-%C%y%m%d-%H%M%S')
143 parser.error('incorrect number of arguments')
145 check_local_changes()
147 check_head_top_equal()
149 print 'Cloning current branch to "%s"...' % clone,
151 crt_series.clone(clone)
156 elif options.convert:
159 parser.error('incorrect number of arguments')
167 parser.error('incorrect number of arguments')
168 __delete_branch(args[0], options.force)
174 parser.error('incorrect number of arguments')
176 branches = os.listdir(os.path.join(git.get_base_dir(), 'refs', 'heads'))
178 max_len = max([len(i) for i in branches])
180 print 'Available branches:'
182 __print_branch(i, max_len)
185 elif options.protect:
188 branch_name = crt_series.get_branch()
190 branch_name = args[0]
192 parser.error('incorrect number of arguments')
193 branch = stack.Series(branch_name)
195 if not branch.is_initialised():
196 raise CmdException, 'Branch "%s" is not controlled by StGIT' \
199 print 'Protecting branch "%s"...' % branch_name,
209 parser.error('incorrect number of arguments')
211 if __is_current_branch(args[0]):
212 raise CmdException, 'Renaming the current branch is not supported'
214 stack.Series(args[0]).rename(args[1])
216 print 'Renamed branch "%s" as "%s".' % (args[0], args[1])
220 elif options.unprotect:
223 branch_name = crt_series.get_branch()
225 branch_name = args[0]
227 parser.error('incorrect number of arguments')
228 branch = stack.Series(branch_name)
230 if not branch.is_initialised():
231 raise CmdException, 'Branch "%s" is not controlled by StGIT' \
234 print 'Unprotecting branch "%s"...' % branch_name,
243 if __is_current_branch(args[0]):
244 raise CmdException, 'Branch "%s" is already the current branch' \
247 check_local_changes()
249 check_head_top_equal()
251 print 'Switching to branch "%s"...' % args[0],
254 git.switch_branch(args[0])
259 # default action: print the current branch
261 parser.error('incorrect number of arguments')
263 print crt_series.get_branch()