From: Catalin Marinas Date: Wed, 5 Oct 2005 15:58:18 +0000 (+0100) Subject: Allow git.apply_patch() to take a base revision X-Git-Tag: v0.8~77 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/stgit/commitdiff_plain/84fcbc3b78f3a0156025d4eb6f6b76df7a5df233 Allow git.apply_patch() to take a base revision This option is useful for import --base and fold commands. Both these commands were modified to take advantage of it. The fold commands also supports a --base option, similar to the import one. Signed-off-by: Catalin Marinas --- diff --git a/stgit/commands/fold.py b/stgit/commands/fold.py index 9542fa6..963c196 100644 --- a/stgit/commands/fold.py +++ b/stgit/commands/fold.py @@ -29,14 +29,15 @@ 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 merge is -performed with the current top.""" +performed with the current top. With the --base option, the patch is +applied onto the specified base 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')] + make_option('-b', '--base', + help = 'use BASE instead of HEAD applying the patch')] def func(parser, options, args): @@ -67,24 +68,10 @@ def func(parser, options, args): 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) + git.apply_patch(filename, bottom) + elif options.base: + git.apply_patch(filename, git.rev_parse(options.base)) 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)' + print 'done' diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py index 0afe00f..96ba0a1 100644 --- a/stgit/commands/imprt.py +++ b/stgit/commands/imprt.py @@ -220,19 +220,7 @@ def func(parser, options, args): sys.stdout.flush() if options.base: - orig_head = git.get_head() - git.switch(options.base) - - try: - git.apply_patch(filename) - except git.GitException, ex: - print >> sys.stderr, '"git apply" failed' - git.switch(orig_head) - raise - - top = crt_series.refresh_patch(commit_only = True) - git.switch(orig_head) - git.merge(options.base, orig_head, top) + git.apply_patch(filename, git.rev_parse(options.base)) else: git.apply_patch(filename) diff --git a/stgit/git.py b/stgit/git.py index 083e97f..c57063b 100644 --- a/stgit/git.py +++ b/stgit/git.py @@ -245,7 +245,10 @@ def __set_head(val): def rev_parse(git_id): """Parse the string and return a verified SHA1 id """ - return _output_one_line(['git-rev-parse', '--verify', git_id]) + try: + return _output_one_line(['git-rev-parse', '--verify', git_id]) + except GitException: + raise GitException, 'Unknown revision: %s' % git_id def add(names): """Add the files or recursively add the directory contents @@ -511,17 +514,35 @@ def pull(repository = 'origin', refspec = None): if __run('git pull', args) != 0: raise GitException, 'Failed "git pull %s"' % repository -def apply_patch(filename = None): - """Apply a patch onto the current index. There must not be any - local changes in the tree, otherwise the command fails +def apply_patch(filename = None, base = None): + """Apply a patch onto the current or given index. There must not + be any local changes in the tree, otherwise the command fails """ + def __apply_patch(): + if filename: + return __run('git-apply --index', [filename]) == 0 + else: + try: + _input('git-apply --index', sys.stdin) + except GitException: + return False + return True + os.system('git-update-index --refresh > /dev/null') - if filename: - if __run('git-apply --index', [filename]) != 0: - raise GitException, 'Patch does not apply cleanly' - else: - _input('git-apply --index', sys.stdin) + if base: + orig_head = get_head() + switch(base) + + if not __apply_patch(): + if base: + switch(orig_head) + raise GitException, 'Patch does not apply cleanly' + elif base: + top = commit(message = 'temporary commit used for applying a patch', + parents = [base]) + switch(orig_head) + merge(base, orig_head, top) def clone(repository, local_dir): """Clone a remote repository. At the moment, just use the diff --git a/stgit/stack.py b/stgit/stack.py index d411725..76da21a 100644 --- a/stgit/stack.py +++ b/stgit/stack.py @@ -372,8 +372,7 @@ class Series: cache_update = True, author_name = None, author_email = None, author_date = None, - committer_name = None, committer_email = None, - commit_only = False): + committer_name = None, committer_email = None): """Generates a new commit for the given patch """ name = self.get_current() @@ -414,14 +413,13 @@ class Series: committer_name = committer_name, committer_email = 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) + 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