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