From: Catalin Marinas Date: Mon, 8 Aug 2005 16:36:23 +0000 (+0100) Subject: Implement the fold command X-Git-Tag: v0.6~15 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/stgit/commitdiff_plain/c14444b97c474c156299a5d5f3fe161af2290884 Implement the fold command At the moment, it only applies a patch read from a file or the standard input on top of the current patch or on its bottom and three-way merged with it (useful for upgrading external patches). Signed-off-by: Catalin Marinas --- diff --git a/TODO b/TODO index 26c9aae..696a6de 100644 --- a/TODO +++ b/TODO @@ -2,10 +2,7 @@ The TODO list until 1.0: - tag (snapshot) command - log command (it should also show the log per single patch) -- improved import command to import patches from a different branch in - the same tree - tutorial, man page -- fold command (to merge 2 patches into one) - regression tests - release 1.0 diff --git a/stgit/commands/fold.py b/stgit/commands/fold.py new file mode 100644 index 0000000..95c962f --- /dev/null +++ b/stgit/commands/fold.py @@ -0,0 +1,90 @@ +__copyright__ = """ +Copyright (C) 2005, Catalin Marinas + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +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 +from optparse import OptionParser, make_option + +from stgit.commands.common import * +from stgit.utils import * +from stgit import stack, git + + +help = 'integrate a GNU diff patch into the current patch' +usage = """%prog [options] [] + +Apply the given GNU diff file (or the standard input) onto the top of +the current patch. With the '--threeway' option, the patch is applied +onto the bottom of the current patch and a three-way merged is +performed with the current top.""" + +options = [make_option('-t', '--threeway', + help = 'perform a three-way merge with the current patch', + action = 'store_true'), + make_option('-n', '--norefresh', + help = 'do not refresh the current patch', + action = 'store_true')] + + +def func(parser, options, args): + """Integrate a GNU diff patch into the current patch + """ + if len(args) > 1: + parser.error('incorrect number of arguments') + + check_local_changes() + check_conflicts() + check_head_top_equal() + + if len(args) == 1: + filename = args[0] + else: + filename = None + + current = crt_series.get_current() + if not current: + raise CmdException, 'No patches applied' + + if filename: + print 'Folding patch "%s"...' % filename, + else: + print 'Folding patch from stdin...', + sys.stdout.flush() + + if options.threeway: + crt_patch = crt_series.get_patch(current) + bottom = crt_patch.get_bottom() + top = crt_patch.get_top() + + git.switch(bottom) + git.apply_patch(filename) + fold_head = crt_series.refresh_patch(commit_only = True) + git.switch(top) + + git.merge(bottom, top, fold_head) + else: + git.apply_patch(filename) + + # no merge conflicts at this point, exception would have been raised + modified = git.local_changes() + + if not options.norefresh and modified: + crt_series.refresh_patch() + + if modified: + print 'done' + else: + print 'done (unchanged)' diff --git a/stgit/git.py b/stgit/git.py index 3a999e4..fdba68a 100644 --- a/stgit/git.py +++ b/stgit/git.py @@ -94,7 +94,6 @@ def get_conflicts(): def _input(cmd, file_desc): p = popen2.Popen3(cmd) for line in file_desc: - print line p.tochild.write(line) p.tochild.close() if p.wait(): diff --git a/stgit/main.py b/stgit/main.py index fee0cc1..f16efe5 100644 --- a/stgit/main.py +++ b/stgit/main.py @@ -36,6 +36,7 @@ import stgit.commands.clean import stgit.commands.clone import stgit.commands.export import stgit.commands.files +import stgit.commands.fold import stgit.commands.imprt import stgit.commands.init import stgit.commands.mail @@ -65,6 +66,7 @@ commands = { 'clone': stgit.commands.clone, 'export': stgit.commands.export, 'files': stgit.commands.files, + 'fold': stgit.commands.fold, 'import': stgit.commands.imprt, 'init': stgit.commands.init, 'mail': stgit.commands.mail, diff --git a/stgit/stack.py b/stgit/stack.py index d5b15e4..065c084 100644 --- a/stgit/stack.py +++ b/stgit/stack.py @@ -329,7 +329,8 @@ class Series: def refresh_patch(self, message = None, edit = False, author_name = None, author_email = None, author_date = None, - committer_name = None, committer_email = None): + committer_name = None, committer_email = None, + commit_only = False): """Generates a new commit for the given patch """ name = self.get_current() @@ -369,13 +370,16 @@ class Series: committer_name = committer_name, committer_email = committer_email) - patch.set_top(commit_id) - patch.set_description(descr) - patch.set_authname(author_name) - patch.set_authemail(author_email) - patch.set_authdate(author_date) - patch.set_commname(committer_name) - patch.set_commemail(committer_email) + if not commit_only: + patch.set_top(commit_id) + patch.set_description(descr) + patch.set_authname(author_name) + patch.set_authemail(author_email) + patch.set_authdate(author_date) + patch.set_commname(committer_name) + patch.set_commemail(committer_email) + + return commit_id def new_patch(self, name, message = None, edit = False, author_name = None, author_email = None, author_date = None,