comparison mercurial/cmdutil.py @ 20500:ce3f3082ec45

import: move tryone closure in cmdutil We extract the `tryone` function into the `cmdutil` module. A lot of the command context have to be passed to the utility function, but having and explicit declaration will allow extension to wrap it. This will allows use to make changeset evolution related experiment in dedicated extension. Improving the API of this function is noble goal but outside of the scope of this patches.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Tue, 11 Feb 2014 16:52:36 -0800
parents 78f4c2b7052f
children 86cefb15e7b5
comparison
equal deleted inserted replaced
20499:2efd608473fb 20500:ce3f3082ec45
539 if logfile and logfilefd not in (0, 1, 2): 539 if logfile and logfilefd not in (0, 1, 2):
540 os.close(logfilefd) 540 os.close(logfilefd)
541 541
542 if runfn: 542 if runfn:
543 return runfn() 543 return runfn()
544
545 def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
546 """Utility function used by commands.import to import a single patch
547
548 This function is explicitly defined here to help the evolve extension to
549 wrap this part of the import logic.
550
551 The API is currently a bit ugly because it a simple code translation from
552 the import command. Feel free to make it better.
553
554 :hunk: a patch (as a binary string)
555 :parents: nodes that will be parent of the created commit
556 :opts: the full dict of option passed to the import command
557 :msgs: list to save commit message to.
558 (used in case we need to save it when failing)
559 :updatefunc: a function that update a repo to a given node
560 updatefunc(<repo>, <node>)
561 """
562 tmpname, message, user, date, branch, nodeid, p1, p2 = \
563 patch.extract(ui, hunk)
564
565 editor = commiteditor
566 if opts.get('edit'):
567 editor = commitforceeditor
568 update = not opts.get('bypass')
569 strip = opts["strip"]
570 sim = float(opts.get('similarity') or 0)
571 if not tmpname:
572 return (None, None)
573 msg = _('applied to working directory')
574
575 try:
576 cmdline_message = logmessage(ui, opts)
577 if cmdline_message:
578 # pickup the cmdline msg
579 message = cmdline_message
580 elif message:
581 # pickup the patch msg
582 message = message.strip()
583 else:
584 # launch the editor
585 message = None
586 ui.debug('message:\n%s\n' % message)
587
588 if len(parents) == 1:
589 parents.append(repo[nullid])
590 if opts.get('exact'):
591 if not nodeid or not p1:
592 raise util.Abort(_('not a Mercurial patch'))
593 p1 = repo[p1]
594 p2 = repo[p2 or nullid]
595 elif p2:
596 try:
597 p1 = repo[p1]
598 p2 = repo[p2]
599 # Without any options, consider p2 only if the
600 # patch is being applied on top of the recorded
601 # first parent.
602 if p1 != parents[0]:
603 p1 = parents[0]
604 p2 = repo[nullid]
605 except error.RepoError:
606 p1, p2 = parents
607 else:
608 p1, p2 = parents
609
610 n = None
611 if update:
612 if p1 != parents[0]:
613 updatefunc(repo, p1.node())
614 if p2 != parents[1]:
615 repo.setparents(p1.node(), p2.node())
616
617 if opts.get('exact') or opts.get('import_branch'):
618 repo.dirstate.setbranch(branch or 'default')
619
620 files = set()
621 patch.patch(ui, repo, tmpname, strip=strip, files=files,
622 eolmode=None, similarity=sim / 100.0)
623 files = list(files)
624 if opts.get('no_commit'):
625 if message:
626 msgs.append(message)
627 else:
628 if opts.get('exact') or p2:
629 # If you got here, you either use --force and know what
630 # you are doing or used --exact or a merge patch while
631 # being updated to its first parent.
632 m = None
633 else:
634 m = scmutil.matchfiles(repo, files or [])
635 n = repo.commit(message, opts.get('user') or user,
636 opts.get('date') or date, match=m,
637 editor=editor)
638 else:
639 if opts.get('exact') or opts.get('import_branch'):
640 branch = branch or 'default'
641 else:
642 branch = p1.branch()
643 store = patch.filestore()
644 try:
645 files = set()
646 try:
647 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
648 files, eolmode=None)
649 except patch.PatchError, e:
650 raise util.Abort(str(e))
651 memctx = context.makememctx(repo, (p1.node(), p2.node()),
652 message,
653 opts.get('user') or user,
654 opts.get('date') or date,
655 branch, files, store,
656 editor=commiteditor)
657 repo.savecommitmessage(memctx.description())
658 n = memctx.commit()
659 finally:
660 store.close()
661 if opts.get('exact') and hex(n) != nodeid:
662 raise util.Abort(_('patch is damaged or loses information'))
663 if n:
664 # i18n: refers to a short changeset id
665 msg = _('created %s') % short(n)
666 return (msg, n)
667 finally:
668 os.unlink(tmpname)
544 669
545 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False, 670 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
546 opts=None): 671 opts=None):
547 '''export changesets as hg patches.''' 672 '''export changesets as hg patches.'''
548 673