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 options = [make_option('-c', '--create',
41 help = 'create a new development branch',
42 action = 'store_true'),
43 make_option('--clone',
44 help = 'clone the contents of the current branch',
45 action = 'store_true'),
46 make_option('--delete',
47 help = 'delete an existing development branch',
48 action = 'store_true'),
49 make_option('--force',
50 help = 'force a delete when the series is not empty',
51 action = 'store_true'),
52 make_option('-l', '--list',
53 help = 'list branches contained in this repository',
54 action = 'store_true'),
55 make_option('-p', '--protect',
56 help = 'prevent "stg pull" from modifying this branch',
57 action = 'store_true'),
58 make_option('-r', '--rename',
59 help = 'rename an existing development branch',
60 action = 'store_true'),
61 make_option('-u', '--unprotect',
62 help = 'allow "stg pull" to modify this branch',
63 action = 'store_true')]
66 def __is_current_branch(branch_name):
67 return crt_series.get_branch() == branch_name
69 def __print_branch(branch_name, length):
74 branch = stack.Series(branch_name)
76 if branch.is_initialised():
78 if __is_current_branch(branch_name):
80 if branch.get_protected():
82 print current + ' ' + initialized + protected + '\t' + \
83 branch_name.ljust(length) + ' | ' + branch.get_description()
85 def __delete_branch(doomed_name, force = False):
86 doomed = stack.Series(doomed_name)
88 if doomed.get_protected():
89 raise CmdException, 'This branch is protected. Delete is not permitted'
91 print 'Deleting branch "%s"...' % doomed_name,
94 if __is_current_branch(doomed_name):
97 check_head_top_equal()
99 if doomed_name != 'master':
100 git.switch_branch('master')
104 if doomed_name != 'master':
105 git.delete_branch(doomed_name)
109 def func(parser, options, args):
113 if len(args) == 0 or len(args) > 2:
114 parser.error('incorrect number of arguments')
116 check_local_changes()
118 check_head_top_equal()
124 git.create_branch(args[0], tree_id)
125 stack.Series(args[0]).init()
127 print 'Branch "%s" created.' % args[0]
133 clone = crt_series.get_branch() + \
134 time.strftime('-%C%y%m%d-%H%M%S')
138 parser.error('incorrect number of arguments')
140 check_local_changes()
142 check_head_top_equal()
144 print 'Cloning current branch to "%s"...' % clone,
146 crt_series.clone(clone)
154 parser.error('incorrect number of arguments')
155 __delete_branch(args[0], options.force)
161 parser.error('incorrect number of arguments')
163 branches = os.listdir(os.path.join(git.get_base_dir(), 'refs', 'heads'))
165 max_len = max([len(i) for i in branches])
167 print 'Available branches:'
169 __print_branch(i, max_len)
172 elif options.protect:
175 branch_name = crt_series.get_branch()
177 branch_name = args[0]
179 parser.error('incorrect number of arguments')
180 branch = stack.Series(branch_name)
182 if not branch.is_initialised():
183 raise CmdException, 'Branch "%s" is not controlled by StGIT' \
186 print 'Protecting branch "%s"...' % branch_name,
196 parser.error('incorrect number of arguments')
198 if __is_current_branch(args[0]):
199 raise CmdException, 'Renaming the current branch is not supported'
201 stack.Series(args[0]).rename(args[1])
203 print 'Renamed branch "%s" as "%s".' % (args[0], args[1])
207 elif options.unprotect:
210 branch_name = crt_series.get_branch()
212 branch_name = args[0]
214 parser.error('incorrect number of arguments')
215 branch = stack.Series(branch_name)
217 if not branch.is_initialised():
218 raise CmdException, 'Branch "%s" is not controlled by StGIT' \
221 print 'Unprotecting branch "%s"...' % branch_name,
230 if __is_current_branch(args[0]):
231 raise CmdException, 'Branch "%s" is already the current branch' \
234 check_local_changes()
236 check_head_top_equal()
238 print 'Switching to branch "%s"...' % args[0],
241 git.switch_branch(args[0])
246 # default action: print the current branch
248 parser.error('incorrect number of arguments')
250 print crt_series.get_branch()