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, list, 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.
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('--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'),
52 make_option('-r', '--rename',
53 help = 'rename an existing development branch',
54 action = 'store_true')]
57 def is_current_branch(branch_name):
58 return git.get_head_file() == branch_name
60 def print_branch(branch_name):
63 if os.path.isdir(os.path.join(git.base_dir, 'patches', branch_name)):
65 if is_current_branch(branch_name):
67 print '%s %s\t%s' % (current, initialized, branch_name)
69 def delete_branch(doomed_name, force = False):
70 if is_current_branch(doomed_name) and doomed_name != 'master':
71 git.switch_branch('master')
73 stack.Series(doomed_name).delete(force)
75 if doomed_name != 'master':
76 git.delete_branch(doomed_name)
78 print 'Branch "%s" has been deleted.' % doomed_name
80 def rename_branch(from_name, to_name):
81 if from_name == 'master':
82 raise CmdException, 'Renaming the master branch is not allowed'
84 to_patchdir = os.path.join(git.base_dir, 'patches', to_name)
85 if os.path.isdir(to_patchdir):
86 raise CmdException, '"%s" already exists' % to_patchdir
87 to_base = os.path.join(git.base_dir, 'refs', 'bases', to_name)
88 if os.path.isfile(to_base):
89 raise CmdException, '"%s" already exists' % to_base
91 git.rename_branch(from_name, to_name)
93 from_patchdir = os.path.join(git.base_dir, 'patches', from_name)
94 if os.path.isdir(from_patchdir):
95 os.rename(from_patchdir, to_patchdir)
96 from_base = os.path.join(git.base_dir, 'refs', 'bases', from_name)
97 if os.path.isfile(from_base):
98 os.rename(from_base, to_base)
100 print 'Renamed branch "%s" as "%s".' % (from_name, to_name)
102 def func(parser, options, args):
106 if len(args) == 0 or len(args) > 2:
107 parser.error('incorrect number of arguments')
112 git.create_branch(args[0], tree_id)
113 stack.Series(args[0]).init()
115 print 'Branch "%s" created.' % args[0]
121 parser.error('incorrect number of arguments')
122 delete_branch(args[0], options.force)
128 parser.error('incorrect number of arguments')
130 branches = os.listdir(os.path.join(git.base_dir, 'refs', 'heads'))
133 print 'Available branches:'
141 parser.error('incorrect number of arguments')
142 rename_branch(args[0], args[1])
147 print 'Switching to branch "%s"...' % args[0],
150 git.switch_branch(args[0])
155 # default action: print the current branch
157 parser.error('incorrect number of arguments')
159 print git.get_head_file()