X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/89e3bc51b5d645f6814a152d853994467eafea81..003753379ff42f2c7d1a69cd1b77b95384f19ea2:/stgit/commands/pick.py diff --git a/stgit/commands/pick.py b/stgit/commands/pick.py index f8f3577..5b45434 100644 --- a/stgit/commands/pick.py +++ b/stgit/commands/pick.py @@ -20,7 +20,9 @@ from optparse import OptionParser, make_option from stgit.commands.common import * from stgit.utils import * +from stgit.out import * from stgit import stack, git +from stgit.stack import Series help = 'import a patch from a different branch or a commit object' @@ -32,6 +34,7 @@ the name of the current patch. It can be overridden with the '--name' option. A commit object can be reverted with the '--reverse' option. The log and author information are those of the commit object.""" +directory = DirectoryGotoToplevel() options = [make_option('-n', '--name', help = 'use NAME as the patch name'), make_option('-r', '--reverse', @@ -39,11 +42,17 @@ options = [make_option('-n', '--name', action = 'store_true'), make_option('-p', '--parent', metavar = 'COMMITID', help = 'use COMMITID as parent'), + make_option('-x', '--expose', + help = 'append the imported commit id to the patch log', + action = 'store_true'), make_option('--fold', help = 'fold the commit object into the current patch', action = 'store_true'), make_option('--update', help = 'like fold but only update the current patch files', + action = 'store_true'), + make_option('--unapplied', + help = 'keep the patch unapplied', action = 'store_true')] @@ -53,12 +62,13 @@ def func(parser, options, args): if len(args) != 1: parser.error('incorrect number of arguments') - check_local_changes() - check_conflicts() - check_head_top_equal() + if not options.unapplied: + check_local_changes() + check_conflicts() + check_head_top_equal(crt_series) commit_str = args[0] - commit_id = git_id(commit_str) + commit_id = git_id(crt_series, commit_str) commit = git.Commit(commit_id) if options.fold or options.update: @@ -67,16 +77,14 @@ def func(parser, options, args): else: patch_branch = commit_str.split('@') if options.name: - patch = options.name + patchname = options.name elif len(patch_branch) == 2: - patch = patch_branch[0] + patchname = patch_branch[0] else: - patch = make_patch_name(commit.get_log()) - if not patch: - raise CmdException, 'Unknown patch name' + patchname = None if options.parent: - parent = git_id(options.parent) + parent = git_id(crt_series, options.parent) else: parent = commit.get_parent() @@ -88,46 +96,71 @@ def func(parser, options, args): top = parent if options.fold: - print 'Folding commit %s...' % commit_id, - sys.stdout.flush() + out.start('Folding commit %s' % commit_id) # try a direct git-apply first if not git.apply_diff(bottom, top): - git.merge(bottom, git.get_head(), top) + git.merge(bottom, git.get_head(), top, recursive = True) - print 'done' + out.done() elif options.update: - rev1 = git_id('//bottom') - rev2 = git_id('//top') + rev1 = git_id(crt_series, '//bottom') + rev2 = git_id(crt_series, '//top') files = git.barefiles(rev1, rev2).split('\n') - print 'Updating with commit %s...' % commit_id, - sys.stdout.flush() + out.start('Updating with commit %s' % commit_id) if not git.apply_diff(bottom, top, files = files): raise CmdException, 'Patch updating failed' - print 'done' + out.done() else: message = commit.get_log() + if options.expose: + message += '(imported from commit %s)\n' % commit.get_id_hash() author_name, author_email, author_date = \ name_email_date(commit.get_author()) - print 'Importing commit %s...' % commit_id, - sys.stdout.flush() - - crt_series.new_patch(patch, message = message, can_edit = False, - unapplied = True, bottom = bottom, top = top, - author_name = author_name, - author_email = author_email, - author_date = author_date) - modified = crt_series.push_patch(patch) + out.start('Importing commit %s' % commit_id) + + newpatch = crt_series.new_patch(patchname, message = message, can_edit = False, + unapplied = True, bottom = bottom, top = top, + author_name = author_name, + author_email = author_email, + author_date = author_date) + # in case the patch name was automatically generated + patchname = newpatch.get_name() + + # find a patchlog to fork from + (refpatchname, refbranchname, refpatchid) = parse_rev(commit_str) + if refpatchname and not refpatchid and \ + (not refpatchid or refpatchid == 'top'): + # FIXME: should also support picking //top.old + if refbranchname: + # assume the refseries is OK, since we already resolved + # commit_str to a git_id + refseries = Series(refbranchname) + else: + refseries = crt_series + patch = refseries.get_patch(refpatchname) + if patch.get_log(): + out.info("Log was %s" % newpatch.get_log()) + out.info("Setting log to %s\n" % patch.get_log()) + newpatch.set_log(patch.get_log()) + out.info("Log is now %s" % newpatch.get_log()) + else: + out.info("No log for %s\n" % patchname) + + if not options.unapplied: + modified = crt_series.push_patch(patchname) + else: + modified = False - if crt_series.empty_patch(patch): - print 'done (empty patch)' + if crt_series.empty_patch(patchname): + out.done('empty patch') elif modified: - print 'done (modified)' + out.done('modified') else: - print 'done' - - print_crt_patch() + out.done() + + print_crt_patch(crt_series)