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('--delete',
49 help = 'delete an existing development branch',
50 action
= 'store_true'),
51 make_option('--force',
52 help = 'force a delete when the series is not empty',
53 action
= 'store_true'),
54 make_option('-l', '--list',
55 help = 'list branches contained in this repository',
56 action
= 'store_true'),
57 make_option('-p', '--protect',
58 help = 'prevent "stg pull" from modifying this branch',
59 action
= 'store_true'),
60 make_option('-r', '--rename',
61 help = 'rename an existing development branch',
62 action
= 'store_true'),
63 make_option('-u', '--unprotect',
64 help = 'allow "stg pull" to modify this branch',
65 action
= 'store_true')]
68 def __is_current_branch(branch_name
):
69 return crt_series
.get_branch() == branch_name
71 def __print_branch(branch_name
, length
):
76 branch
= stack
.Series(branch_name
)
78 if branch
.is_initialised():
80 if __is_current_branch(branch_name
):
82 if branch
.get_protected():
84 print current
+ ' ' + initialized
+ protected
+ '\t' + \
85 branch_name
.ljust(length
) + ' | ' + branch
.get_description()
87 def __delete_branch(doomed_name
, force
= False):
88 doomed
= stack
.Series(doomed_name
)
90 if doomed
.get_protected():
91 raise CmdException
, 'This branch is protected. Delete is not permitted'
93 print 'Deleting branch "%s"...' % doomed_name
,
96 if __is_current_branch(doomed_name
):
99 check_head_top_equal()
101 if doomed_name
!= 'master':
102 git
.switch_branch('master')
106 if doomed_name
!= 'master':
107 git
.delete_branch(doomed_name
)
111 def func(parser
, options
, args
):
115 if len(args
) == 0 or len(args
) > 2:
116 parser
.error('incorrect number of arguments')
118 check_local_changes()
120 check_head_top_equal()
126 git
.create_branch(args
[0], tree_id
)
127 stack
.Series(args
[0]).init()
129 print 'Branch "%s" created.' % args
[0]
135 clone
= crt_series
.get_branch() + \
136 time
.strftime('-%C%y%m%d-%H%M%S')
140 parser
.error('incorrect number of arguments')
142 check_local_changes()
144 check_head_top_equal()
146 print 'Cloning current branch to "%s"...' % clone
,
148 crt_series
.clone(clone
)
156 parser
.error('incorrect number of arguments')
157 __delete_branch(args
[0], options
.force
)
163 parser
.error('incorrect number of arguments')
165 branches
= os
.listdir(os
.path
.join(git
.get_base_dir(), 'refs', 'heads'))
167 max_len
= max([len(i
) for i
in branches
])
169 print 'Available branches:'
171 __print_branch(i
, max_len
)
174 elif options
.protect
:
177 branch_name
= crt_series
.get_branch()
179 branch_name
= args
[0]
181 parser
.error('incorrect number of arguments')
182 branch
= stack
.Series(branch_name
)
184 if not branch
.is_initialised():
185 raise CmdException
, 'Branch "%s" is not controlled by StGIT' \
188 print 'Protecting branch "%s"...' % branch_name
,
198 parser
.error('incorrect number of arguments')
200 if __is_current_branch(args
[0]):
201 raise CmdException
, 'Renaming the current branch is not supported'
203 stack
.Series(args
[0]).rename(args
[1])
205 print 'Renamed branch "%s" as "%s".' %
(args
[0], args
[1])
209 elif options
.unprotect
:
212 branch_name
= crt_series
.get_branch()
214 branch_name
= args
[0]
216 parser
.error('incorrect number of arguments')
217 branch
= stack
.Series(branch_name
)
219 if not branch
.is_initialised():
220 raise CmdException
, 'Branch "%s" is not controlled by StGIT' \
223 print 'Unprotecting branch "%s"...' % branch_name
,
232 if __is_current_branch(args
[0]):
233 raise CmdException
, 'Branch "%s" is already the current branch' \
236 check_local_changes()
238 check_head_top_equal()
240 print 'Switching to branch "%s"...' % args
[0],
243 git
.switch_branch(args
[0])
248 # default action: print the current branch
250 parser
.error('incorrect number of arguments')
252 print crt_series
.get_branch()