##// END OF EJS Templates
keyword: wrap functions only once at loading keyword extension...
FUJIWARA Katsunori -
r33071:279c072a default
parent child Browse files
Show More
@@ -577,9 +577,136 b' def shrink(ui, repo, *pats, **opts):'
577 577 # 3rd argument sets expansion to False
578 578 _kwfwrite(ui, repo, False, *pats, **opts)
579 579
580 # monkeypatches
581
582 def kwpatchfile_init(orig, self, ui, gp, backend, store, eolmode=None):
583 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
584 rejects or conflicts due to expanded keywords in working dir.'''
585 orig(self, ui, gp, backend, store, eolmode)
586 kwt = getattr(getattr(backend, 'repo', None), '_keywordkwt', None)
587 if kwt:
588 # shrink keywords read from working dir
589 self.lines = kwt.shrinklines(self.fname, self.lines)
590
591 def kwdiff(orig, repo, *args, **kwargs):
592 '''Monkeypatch patch.diff to avoid expansion.'''
593 kwt = getattr(repo, '_keywordkwt', None)
594 if kwt:
595 restrict = kwt.restrict
596 kwt.restrict = True
597 try:
598 for chunk in orig(repo, *args, **kwargs):
599 yield chunk
600 finally:
601 if kwt:
602 kwt.restrict = restrict
603
604 def kwweb_skip(orig, web, req, tmpl):
605 '''Wraps webcommands.x turning off keyword expansion.'''
606 kwt = getattr(web.repo, '_keywordkwt', None)
607 if kwt:
608 origmatch = kwt.match
609 kwt.match = util.never
610 try:
611 for chunk in orig(web, req, tmpl):
612 yield chunk
613 finally:
614 if kwt:
615 kwt.match = origmatch
616
617 def kw_amend(orig, ui, repo, commitfunc, old, extra, pats, opts):
618 '''Wraps cmdutil.amend expanding keywords after amend.'''
619 kwt = getattr(repo, '_keywordkwt', None)
620 if kwt is None:
621 return orig(ui, repo, commitfunc, old, extra, pats, opts)
622 with repo.wlock():
623 kwt.postcommit = True
624 newid = orig(ui, repo, commitfunc, old, extra, pats, opts)
625 if newid != old.node():
626 ctx = repo[newid]
627 kwt.restrict = True
628 kwt.overwrite(ctx, ctx.files(), False, True)
629 kwt.restrict = False
630 return newid
631
632 def kw_copy(orig, ui, repo, pats, opts, rename=False):
633 '''Wraps cmdutil.copy so that copy/rename destinations do not
634 contain expanded keywords.
635 Note that the source of a regular file destination may also be a
636 symlink:
637 hg cp sym x -> x is symlink
638 cp sym x; hg cp -A sym x -> x is file (maybe expanded keywords)
639 For the latter we have to follow the symlink to find out whether its
640 target is configured for expansion and we therefore must unexpand the
641 keywords in the destination.'''
642 kwt = getattr(repo, '_keywordkwt', None)
643 if kwt is None:
644 return orig(ui, repo, pats, opts, rename)
645 with repo.wlock():
646 orig(ui, repo, pats, opts, rename)
647 if opts.get('dry_run'):
648 return
649 wctx = repo[None]
650 cwd = repo.getcwd()
651
652 def haskwsource(dest):
653 '''Returns true if dest is a regular file and configured for
654 expansion or a symlink which points to a file configured for
655 expansion. '''
656 source = repo.dirstate.copied(dest)
657 if 'l' in wctx.flags(source):
658 source = pathutil.canonpath(repo.root, cwd,
659 os.path.realpath(source))
660 return kwt.match(source)
661
662 candidates = [f for f in repo.dirstate.copies() if
663 'l' not in wctx.flags(f) and haskwsource(f)]
664 kwt.overwrite(wctx, candidates, False, False)
665
666 def kw_dorecord(orig, ui, repo, commitfunc, *pats, **opts):
667 '''Wraps record.dorecord expanding keywords after recording.'''
668 kwt = getattr(repo, '_keywordkwt', None)
669 if kwt is None:
670 return orig(ui, repo, commitfunc, *pats, **opts)
671 with repo.wlock():
672 # record returns 0 even when nothing has changed
673 # therefore compare nodes before and after
674 kwt.postcommit = True
675 ctx = repo['.']
676 wstatus = ctx.status()
677 ret = orig(ui, repo, commitfunc, *pats, **opts)
678 recctx = repo['.']
679 if ctx != recctx:
680 modified, added = _preselect(wstatus, recctx.files())
681 kwt.restrict = False
682 kwt.overwrite(recctx, modified, False, True)
683 kwt.overwrite(recctx, added, False, True, True)
684 kwt.restrict = True
685 return ret
686
687 def kwfilectx_cmp(orig, self, fctx):
688 if fctx._customcmp:
689 return fctx.cmp(self)
690 kwt = getattr(self._repo, '_keywordkwt', None)
691 if kwt is None:
692 return orig(self, fctx)
693 # keyword affects data size, comparing wdir and filelog size does
694 # not make sense
695 if (fctx._filenode is None and
696 (self._repo._encodefilterpats or
697 kwt.match(fctx.path()) and 'l' not in fctx.flags() or
698 self.size() - 4 == fctx.size()) or
699 self.size() == fctx.size()):
700 return self._filelog.cmp(self._filenode, fctx.data())
701 return True
580 702
581 703 def uisetup(ui):
582 ''' Monkeypatches dispatch._parse to retrieve user command.'''
704 ''' Monkeypatches dispatch._parse to retrieve user command.
705 Overrides file method to return kwfilelog instead of filelog
706 if file matches user configuration.
707 Wraps commit to overwrite configured files with updated
708 keyword substitutions.
709 Monkeypatches patch and webcommands.'''
583 710
584 711 def kwdispatch_parse(orig, ui, args):
585 712 '''Monkeypatch dispatch._parse to obtain running hg command.'''
@@ -589,13 +716,17 b' def uisetup(ui):'
589 716
590 717 extensions.wrapfunction(dispatch, '_parse', kwdispatch_parse)
591 718
719 extensions.wrapfunction(context.filectx, 'cmp', kwfilectx_cmp)
720 extensions.wrapfunction(patch.patchfile, '__init__', kwpatchfile_init)
721 extensions.wrapfunction(patch, 'diff', kwdiff)
722 extensions.wrapfunction(cmdutil, 'amend', kw_amend)
723 extensions.wrapfunction(cmdutil, 'copy', kw_copy)
724 extensions.wrapfunction(cmdutil, 'dorecord', kw_dorecord)
725 for c in nokwwebcommands.split():
726 extensions.wrapfunction(webcommands, c, kwweb_skip)
727
592 728 def reposetup(ui, repo):
593 '''Sets up repo as kwrepo for keyword substitution.
594 Overrides file method to return kwfilelog instead of filelog
595 if file matches user configuration.
596 Wraps commit to overwrite configured files with updated
597 keyword substitutions.
598 Monkeypatches patch and webcommands.'''
729 '''Sets up repo as kwrepo for keyword substitution.'''
599 730
600 731 try:
601 732 if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
@@ -665,134 +796,3 b' def reposetup(ui, repo):'
665 796
666 797 repo.__class__ = kwrepo
667 798 repo._keywordkwt = kwt
668
669 # monkeypatches
670 def kwpatchfile_init(orig, self, ui, gp, backend, store, eolmode=None):
671 '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
672 rejects or conflicts due to expanded keywords in working dir.'''
673 orig(self, ui, gp, backend, store, eolmode)
674 kwt = getattr(getattr(backend, 'repo', None), '_keywordkwt', None)
675 if kwt:
676 # shrink keywords read from working dir
677 self.lines = kwt.shrinklines(self.fname, self.lines)
678
679 def kwdiff(orig, repo, *args, **kwargs):
680 '''Monkeypatch patch.diff to avoid expansion.'''
681 kwt = getattr(repo, '_keywordkwt', None)
682 if kwt:
683 restrict = kwt.restrict
684 kwt.restrict = True
685 try:
686 for chunk in orig(repo, *args, **kwargs):
687 yield chunk
688 finally:
689 if kwt:
690 kwt.restrict = restrict
691
692 def kwweb_skip(orig, web, req, tmpl):
693 '''Wraps webcommands.x turning off keyword expansion.'''
694 kwt = getattr(web.repo, '_keywordkwt', None)
695 if kwt:
696 origmatch = kwt.match
697 kwt.match = util.never
698 try:
699 for chunk in orig(web, req, tmpl):
700 yield chunk
701 finally:
702 if kwt:
703 kwt.match = origmatch
704
705 def kw_amend(orig, ui, repo, commitfunc, old, extra, pats, opts):
706 '''Wraps cmdutil.amend expanding keywords after amend.'''
707 kwt = getattr(repo, '_keywordkwt', None)
708 if kwt is None:
709 return orig(ui, repo, commitfunc, old, extra, pats, opts)
710 with repo.wlock():
711 kwt.postcommit = True
712 newid = orig(ui, repo, commitfunc, old, extra, pats, opts)
713 if newid != old.node():
714 ctx = repo[newid]
715 kwt.restrict = True
716 kwt.overwrite(ctx, ctx.files(), False, True)
717 kwt.restrict = False
718 return newid
719
720 def kw_copy(orig, ui, repo, pats, opts, rename=False):
721 '''Wraps cmdutil.copy so that copy/rename destinations do not
722 contain expanded keywords.
723 Note that the source of a regular file destination may also be a
724 symlink:
725 hg cp sym x -> x is symlink
726 cp sym x; hg cp -A sym x -> x is file (maybe expanded keywords)
727 For the latter we have to follow the symlink to find out whether its
728 target is configured for expansion and we therefore must unexpand the
729 keywords in the destination.'''
730 kwt = getattr(repo, '_keywordkwt', None)
731 if kwt is None:
732 return orig(ui, repo, pats, opts, rename)
733 with repo.wlock():
734 orig(ui, repo, pats, opts, rename)
735 if opts.get('dry_run'):
736 return
737 wctx = repo[None]
738 cwd = repo.getcwd()
739
740 def haskwsource(dest):
741 '''Returns true if dest is a regular file and configured for
742 expansion or a symlink which points to a file configured for
743 expansion. '''
744 source = repo.dirstate.copied(dest)
745 if 'l' in wctx.flags(source):
746 source = pathutil.canonpath(repo.root, cwd,
747 os.path.realpath(source))
748 return kwt.match(source)
749
750 candidates = [f for f in repo.dirstate.copies() if
751 'l' not in wctx.flags(f) and haskwsource(f)]
752 kwt.overwrite(wctx, candidates, False, False)
753
754 def kw_dorecord(orig, ui, repo, commitfunc, *pats, **opts):
755 '''Wraps record.dorecord expanding keywords after recording.'''
756 kwt = getattr(repo, '_keywordkwt', None)
757 if kwt is None:
758 return orig(ui, repo, commitfunc, *pats, **opts)
759 with repo.wlock():
760 # record returns 0 even when nothing has changed
761 # therefore compare nodes before and after
762 kwt.postcommit = True
763 ctx = repo['.']
764 wstatus = ctx.status()
765 ret = orig(ui, repo, commitfunc, *pats, **opts)
766 recctx = repo['.']
767 if ctx != recctx:
768 modified, added = _preselect(wstatus, recctx.files())
769 kwt.restrict = False
770 kwt.overwrite(recctx, modified, False, True)
771 kwt.overwrite(recctx, added, False, True, True)
772 kwt.restrict = True
773 return ret
774
775 def kwfilectx_cmp(orig, self, fctx):
776 if fctx._customcmp:
777 return fctx.cmp(self)
778 kwt = getattr(self._repo, '_keywordkwt', None)
779 if kwt is None:
780 return orig(self, fctx)
781 # keyword affects data size, comparing wdir and filelog size does
782 # not make sense
783 if (fctx._filenode is None and
784 (self._repo._encodefilterpats or
785 kwt.match(fctx.path()) and 'l' not in fctx.flags() or
786 self.size() - 4 == fctx.size()) or
787 self.size() == fctx.size()):
788 return self._filelog.cmp(self._filenode, fctx.data())
789 return True
790
791 extensions.wrapfunction(context.filectx, 'cmp', kwfilectx_cmp)
792 extensions.wrapfunction(patch.patchfile, '__init__', kwpatchfile_init)
793 extensions.wrapfunction(patch, 'diff', kwdiff)
794 extensions.wrapfunction(cmdutil, 'amend', kw_amend)
795 extensions.wrapfunction(cmdutil, 'copy', kw_copy)
796 extensions.wrapfunction(cmdutil, 'dorecord', kw_dorecord)
797 for c in nokwwebcommands.split():
798 extensions.wrapfunction(webcommands, c, kwweb_skip)
General Comments 0
You need to be logged in to leave comments. Login now