From cc3db2b1cfb886fddf76ef758b8fb7b06753347c Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sat, 3 Dec 2005 22:50:19 -0500 Subject: [PATCH] Add a "--clone" option to "stg branch" Organization: Straylight/Edgeware From: Chuck Lever Cloning a branch means creating a new branch and copying all of the original branch's patches and its base to it. Like creating a tag, but this also preserves all the StGIT patches as well. Signed-off-by: Chuck Lever --- stgit/commands/branch.py | 30 +++++++++++++++++++++++++++--- stgit/stack.py | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py index ccf1f6b..860d7d5 100644 --- a/stgit/commands/branch.py +++ b/stgit/commands/branch.py @@ -18,7 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -import sys, os +import sys, os, time from optparse import OptionParser, make_option from stgit.commands.common import * @@ -29,10 +29,10 @@ from stgit import stack, git help = 'manage development branches' usage = """%prog [options] branch-name [commit-id] -Create, list, switch between, rename, or delete development branches +Create, clone, switch between, rename, or delete development branches within a git repository. By default, a single branch called 'master' is always created in a new repository. This subcommand allows you to -manage several patch series in the same repository. +manage several patch series in the same repository via GIT branches. When displaying the branches, the names can be prefixed with 's' (StGIT managed) or 'p' (protected).""" @@ -40,6 +40,9 @@ When displaying the branches, the names can be prefixed with options = [make_option('-c', '--create', help = 'create a new development branch', action = 'store_true'), + make_option('--clone', + help = 'clone the contents of the current branch', + action = 'store_true'), make_option('--delete', help = 'delete an existing development branch', action = 'store_true'), @@ -124,6 +127,27 @@ def func(parser, options, args): print 'Branch "%s" created.' % args[0] return + elif options.clone: + + if len(args) == 0: + clone = crt_series.get_branch() + \ + time.strftime('-%C%y%m%d-%H%M%S') + elif len(args) == 1: + clone = args[0] + else: + parser.error('incorrect number of arguments') + + check_local_changes() + check_conflicts() + check_head_top_equal() + + print 'Cloning current branch to "%s"...' % clone, + sys.stdout.flush() + crt_series.clone(clone) + print 'done' + + return + elif options.delete: if len(args) != 1: diff --git a/stgit/stack.py b/stgit/stack.py index bc5915e..8b7c296 100644 --- a/stgit/stack.py +++ b/stgit/stack.py @@ -420,6 +420,33 @@ class Series: self.__init__(to_name) + def clone(self, target_series): + """Clones a series + """ + base = read_string(self.get_base_file()) + git.create_branch(target_series, tree_id = base) + Series(target_series).init() + new_series = Series(target_series) + + # generate an artificial description file + write_string(new_series.__descr_file, 'clone of "%s"' % self.__name) + + # clone self's entire series as unapplied patches + patches = self.get_applied() + self.get_unapplied() + patches.reverse() + for p in patches: + patch = self.get_patch(p) + new_series.new_patch(p, message = patch.get_description(), + can_edit = False, unapplied = True, + bottom = patch.get_bottom(), + top = patch.get_top(), + author_name = patch.get_authname(), + author_email = patch.get_authemail(), + author_date = patch.get_authdate()) + + # fast forward the cloned series to self's top + new_series.forward_patches(self.get_applied()) + def delete(self, force = False): """Deletes an stgit series """ -- [mdw]