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
, basedir
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()
127 tree_id
= git_id(args
[1])
129 if git
.branch_exists(args
[0]):
130 raise CmdException
, 'Branch "%s" already exists' % args
[0]
132 stack
.Series(args
[0]).init()
133 git
.create_branch(args
[0], tree_id
)
135 print 'Branch "%s" created.' % args
[0]
141 clone
= crt_series
.get_branch() + \
142 time
.strftime('-%C%y%m%d-%H%M%S')
146 parser
.error('incorrect number of arguments')
148 check_local_changes()
150 check_head_top_equal()
152 print 'Cloning current branch to "%s"...' % clone
,
154 crt_series
.clone(clone
)
159 elif options
.convert
:
162 parser
.error('incorrect number of arguments')
170 parser
.error('incorrect number of arguments')
171 __delete_branch(args
[0], options
.force
)
177 parser
.error('incorrect number of arguments')
179 branches
= os
.listdir(os
.path
.join(basedir
.get(), 'refs', 'heads'))
181 max_len
= max([len(i
) for i
in branches
])
183 print 'Available branches:'
185 __print_branch(i
, max_len
)
188 elif options
.protect
:
191 branch_name
= crt_series
.get_branch()
193 branch_name
= args
[0]
195 parser
.error('incorrect number of arguments')
196 branch
= stack
.Series(branch_name
)
198 if not branch
.is_initialised():
199 raise CmdException
, 'Branch "%s" is not controlled by StGIT' \
202 print 'Protecting branch "%s"...' % branch_name
,
212 parser
.error('incorrect number of arguments')
214 if __is_current_branch(args
[0]):
215 raise CmdException
, 'Renaming the current branch is not supported'
217 stack
.Series(args
[0]).rename(args
[1])
219 print 'Renamed branch "%s" as "%s".' %
(args
[0], args
[1])
223 elif options
.unprotect
:
226 branch_name
= crt_series
.get_branch()
228 branch_name
= args
[0]
230 parser
.error('incorrect number of arguments')
231 branch
= stack
.Series(branch_name
)
233 if not branch
.is_initialised():
234 raise CmdException
, 'Branch "%s" is not controlled by StGIT' \
237 print 'Unprotecting branch "%s"...' % branch_name
,
246 if __is_current_branch(args
[0]):
247 raise CmdException
, 'Branch "%s" is already the current branch' \
250 check_local_changes()
252 check_head_top_equal()
254 print 'Switching to branch "%s"...' % args
[0],
257 git
.switch_branch(args
[0])
262 # default action: print the current branch
264 parser
.error('incorrect number of arguments')
266 print crt_series
.get_branch()