Show More
@@ -21,9 +21,13 from . import ( | |||
|
21 | 21 | mdiff, |
|
22 | 22 | policy, |
|
23 | 23 | pycompat, |
|
24 | repository, | |
|
24 | 25 | revlog, |
|
25 | 26 | util, |
|
26 | 27 | ) |
|
28 | from .utils import ( | |
|
29 | interfaceutil, | |
|
30 | ) | |
|
27 | 31 | |
|
28 | 32 | parsers = policy.importmod(r'parsers') |
|
29 | 33 | propertycache = util.propertycache |
@@ -363,6 +367,7 try: | |||
|
363 | 367 | except AttributeError: |
|
364 | 368 | pass |
|
365 | 369 | |
|
370 | @interfaceutil.implementer(repository.imanifestdict) | |
|
366 | 371 | class manifestdict(object): |
|
367 | 372 | def __init__(self, data=''): |
|
368 | 373 | self._lm = _lazymanifest(data) |
@@ -1262,6 +1267,7 class manifestrevlog(revlog.revlog): | |||
|
1262 | 1267 | m.setnode(n) |
|
1263 | 1268 | return n |
|
1264 | 1269 | |
|
1270 | @interfaceutil.implementer(repository.imanifestlog) | |
|
1265 | 1271 | class manifestlog(object): |
|
1266 | 1272 | """A collection class representing the collection of manifest snapshots |
|
1267 | 1273 | referenced by commits in the repository. |
@@ -1342,6 +1348,7 class manifestlog(object): | |||
|
1342 | 1348 | self._dirmancache.clear() |
|
1343 | 1349 | self._revlog.clearcaches() |
|
1344 | 1350 | |
|
1351 | @interfaceutil.implementer(repository.imanifestrevisionwritable) | |
|
1345 | 1352 | class memmanifestctx(object): |
|
1346 | 1353 | def __init__(self, manifestlog): |
|
1347 | 1354 | self._manifestlog = manifestlog |
@@ -1365,6 +1372,7 class memmanifestctx(object): | |||
|
1365 | 1372 | return self._revlog().add(self._manifestdict, transaction, link, p1, p2, |
|
1366 | 1373 | added, removed) |
|
1367 | 1374 | |
|
1375 | @interfaceutil.implementer(repository.imanifestrevisionstored) | |
|
1368 | 1376 | class manifestctx(object): |
|
1369 | 1377 | """A class representing a single revision of a manifest, including its |
|
1370 | 1378 | contents, its parent revs, and its linkrev. |
@@ -1441,6 +1449,7 class manifestctx(object): | |||
|
1441 | 1449 | def find(self, key): |
|
1442 | 1450 | return self.read().find(key) |
|
1443 | 1451 | |
|
1452 | @interfaceutil.implementer(repository.imanifestrevisionwritable) | |
|
1444 | 1453 | class memtreemanifestctx(object): |
|
1445 | 1454 | def __init__(self, manifestlog, dir=''): |
|
1446 | 1455 | self._manifestlog = manifestlog |
@@ -1467,6 +1476,7 class memtreemanifestctx(object): | |||
|
1467 | 1476 | return self._revlog().add(self._treemanifest, transaction, link, p1, p2, |
|
1468 | 1477 | added, removed, readtree=readtree) |
|
1469 | 1478 | |
|
1479 | @interfaceutil.implementer(repository.imanifestrevisionstored) | |
|
1470 | 1480 | class treemanifestctx(object): |
|
1471 | 1481 | def __init__(self, manifestlog, dir, node): |
|
1472 | 1482 | self._manifestlog = manifestlog |
@@ -642,6 +642,286 class ifilestorage(ifileindex, ifiledata | |||
|
642 | 642 | TODO this is used by verify and it should not be part of the interface. |
|
643 | 643 | """ |
|
644 | 644 | |
|
645 | class idirs(interfaceutil.Interface): | |
|
646 | """Interface representing a collection of directories from paths. | |
|
647 | ||
|
648 | This interface is essentially a derived data structure representing | |
|
649 | directories from a collection of paths. | |
|
650 | """ | |
|
651 | ||
|
652 | def addpath(path): | |
|
653 | """Add a path to the collection. | |
|
654 | ||
|
655 | All directories in the path will be added to the collection. | |
|
656 | """ | |
|
657 | ||
|
658 | def delpath(path): | |
|
659 | """Remove a path from the collection. | |
|
660 | ||
|
661 | If the removal was the last path in a particular directory, the | |
|
662 | directory is removed from the collection. | |
|
663 | """ | |
|
664 | ||
|
665 | def __iter__(): | |
|
666 | """Iterate over the directories in this collection of paths.""" | |
|
667 | ||
|
668 | def __contains__(path): | |
|
669 | """Whether a specific directory is in this collection.""" | |
|
670 | ||
|
671 | class imanifestdict(interfaceutil.Interface): | |
|
672 | """Interface representing a manifest data structure. | |
|
673 | ||
|
674 | A manifest is effectively a dict mapping paths to entries. Each entry | |
|
675 | consists of a binary node and extra flags affecting that entry. | |
|
676 | """ | |
|
677 | ||
|
678 | def __getitem__(path): | |
|
679 | """Returns the binary node value for a path in the manifest. | |
|
680 | ||
|
681 | Raises ``KeyError`` if the path does not exist in the manifest. | |
|
682 | ||
|
683 | Equivalent to ``self.find(path)[0]``. | |
|
684 | """ | |
|
685 | ||
|
686 | def find(path): | |
|
687 | """Returns the entry for a path in the manifest. | |
|
688 | ||
|
689 | Returns a 2-tuple of (node, flags). | |
|
690 | ||
|
691 | Raises ``KeyError`` if the path does not exist in the manifest. | |
|
692 | """ | |
|
693 | ||
|
694 | def __len__(): | |
|
695 | """Return the number of entries in the manifest.""" | |
|
696 | ||
|
697 | def __nonzero__(): | |
|
698 | """Returns True if the manifest has entries, False otherwise.""" | |
|
699 | ||
|
700 | __bool__ = __nonzero__ | |
|
701 | ||
|
702 | def __setitem__(path, node): | |
|
703 | """Define the node value for a path in the manifest. | |
|
704 | ||
|
705 | If the path is already in the manifest, its flags will be copied to | |
|
706 | the new entry. | |
|
707 | """ | |
|
708 | ||
|
709 | def __contains__(path): | |
|
710 | """Whether a path exists in the manifest.""" | |
|
711 | ||
|
712 | def __delitem__(path): | |
|
713 | """Remove a path from the manifest. | |
|
714 | ||
|
715 | Raises ``KeyError`` if the path is not in the manifest. | |
|
716 | """ | |
|
717 | ||
|
718 | def __iter__(): | |
|
719 | """Iterate over paths in the manifest.""" | |
|
720 | ||
|
721 | def iterkeys(): | |
|
722 | """Iterate over paths in the manifest.""" | |
|
723 | ||
|
724 | def keys(): | |
|
725 | """Obtain a list of paths in the manifest.""" | |
|
726 | ||
|
727 | def filesnotin(other, match=None): | |
|
728 | """Obtain the set of paths in this manifest but not in another. | |
|
729 | ||
|
730 | ``match`` is an optional matcher function to be applied to both | |
|
731 | manifests. | |
|
732 | ||
|
733 | Returns a set of paths. | |
|
734 | """ | |
|
735 | ||
|
736 | def dirs(): | |
|
737 | """Returns an object implementing the ``idirs`` interface.""" | |
|
738 | ||
|
739 | def hasdir(dir): | |
|
740 | """Returns a bool indicating if a directory is in this manifest.""" | |
|
741 | ||
|
742 | def matches(match): | |
|
743 | """Generate a new manifest filtered through a matcher. | |
|
744 | ||
|
745 | Returns an object conforming to the ``imanifestdict`` interface. | |
|
746 | """ | |
|
747 | ||
|
748 | def walk(match): | |
|
749 | """Generator of paths in manifest satisfying a matcher. | |
|
750 | ||
|
751 | This is equivalent to ``self.matches(match).iterkeys()`` except a new | |
|
752 | manifest object is not created. | |
|
753 | ||
|
754 | If the matcher has explicit files listed and they don't exist in | |
|
755 | the manifest, ``match.bad()`` is called for each missing file. | |
|
756 | """ | |
|
757 | ||
|
758 | def diff(other, match=None, clean=False): | |
|
759 | """Find differences between this manifest and another. | |
|
760 | ||
|
761 | This manifest is compared to ``other``. | |
|
762 | ||
|
763 | If ``match`` is provided, the two manifests are filtered against this | |
|
764 | matcher and only entries satisfying the matcher are compared. | |
|
765 | ||
|
766 | If ``clean`` is True, unchanged files are included in the returned | |
|
767 | object. | |
|
768 | ||
|
769 | Returns a dict with paths as keys and values of 2-tuples of 2-tuples of | |
|
770 | the form ``((node1, flag1), (node2, flag2))`` where ``(node1, flag1)`` | |
|
771 | represents the node and flags for this manifest and ``(node2, flag2)`` | |
|
772 | are the same for the other manifest. | |
|
773 | """ | |
|
774 | ||
|
775 | def setflag(path, flag): | |
|
776 | """Set the flag value for a given path. | |
|
777 | ||
|
778 | Raises ``KeyError`` if the path is not already in the manifest. | |
|
779 | """ | |
|
780 | ||
|
781 | def get(path, default=None): | |
|
782 | """Obtain the node value for a path or a default value if missing.""" | |
|
783 | ||
|
784 | def flags(path, default=''): | |
|
785 | """Return the flags value for a path or a default value if missing.""" | |
|
786 | ||
|
787 | def copy(): | |
|
788 | """Return a copy of this manifest.""" | |
|
789 | ||
|
790 | def items(): | |
|
791 | """Returns an iterable of (path, node) for items in this manifest.""" | |
|
792 | ||
|
793 | def iteritems(): | |
|
794 | """Identical to items().""" | |
|
795 | ||
|
796 | def iterentries(): | |
|
797 | """Returns an iterable of (path, node, flags) for this manifest. | |
|
798 | ||
|
799 | Similar to ``iteritems()`` except items are a 3-tuple and include | |
|
800 | flags. | |
|
801 | """ | |
|
802 | ||
|
803 | def text(): | |
|
804 | """Obtain the raw data representation for this manifest. | |
|
805 | ||
|
806 | Result is used to create a manifest revision. | |
|
807 | """ | |
|
808 | ||
|
809 | def fastdelta(base, changes): | |
|
810 | """Obtain a delta between this manifest and another given changes. | |
|
811 | ||
|
812 | ``base`` in the raw data representation for another manifest. | |
|
813 | ||
|
814 | ``changes`` is an iterable of ``(path, to_delete)``. | |
|
815 | ||
|
816 | Returns a 2-tuple containing ``bytearray(self.text())`` and the | |
|
817 | delta between ``base`` and this manifest. | |
|
818 | """ | |
|
819 | ||
|
820 | class imanifestrevisionbase(interfaceutil.Interface): | |
|
821 | """Base interface representing a single revision of a manifest. | |
|
822 | ||
|
823 | Should not be used as a primary interface: should always be inherited | |
|
824 | as part of a larger interface. | |
|
825 | """ | |
|
826 | ||
|
827 | def new(): | |
|
828 | """Obtain a new manifest instance. | |
|
829 | ||
|
830 | Returns an object conforming to the ``imanifestrevisionwritable`` | |
|
831 | interface. The instance will be associated with the same | |
|
832 | ``imanifestlog`` collection as this instance. | |
|
833 | """ | |
|
834 | ||
|
835 | def copy(): | |
|
836 | """Obtain a copy of this manifest instance. | |
|
837 | ||
|
838 | Returns an object conforming to the ``imanifestrevisionwritable`` | |
|
839 | interface. The instance will be associated with the same | |
|
840 | ``imanifestlog`` collection as this instance. | |
|
841 | """ | |
|
842 | ||
|
843 | def read(): | |
|
844 | """Obtain the parsed manifest data structure. | |
|
845 | ||
|
846 | The returned object conforms to the ``imanifestdict`` interface. | |
|
847 | """ | |
|
848 | ||
|
849 | class imanifestrevisionstored(imanifestrevisionbase): | |
|
850 | """Interface representing a manifest revision committed to storage.""" | |
|
851 | ||
|
852 | def node(): | |
|
853 | """The binary node for this manifest.""" | |
|
854 | ||
|
855 | parents = interfaceutil.Attribute( | |
|
856 | """List of binary nodes that are parents for this manifest revision.""" | |
|
857 | ) | |
|
858 | ||
|
859 | def readdelta(shallow=False): | |
|
860 | """Obtain the manifest data structure representing changes from parent. | |
|
861 | ||
|
862 | This manifest is compared to its 1st parent. A new manifest representing | |
|
863 | those differences is constructed. | |
|
864 | ||
|
865 | The returned object conforms to the ``imanifestdict`` interface. | |
|
866 | """ | |
|
867 | ||
|
868 | def readfast(shallow=False): | |
|
869 | """Calls either ``read()`` or ``readdelta()``. | |
|
870 | ||
|
871 | The faster of the two options is called. | |
|
872 | """ | |
|
873 | ||
|
874 | def find(key): | |
|
875 | """Calls self.read().find(key)``. | |
|
876 | ||
|
877 | Returns a 2-tuple of ``(node, flags)`` or raises ``KeyError``. | |
|
878 | """ | |
|
879 | ||
|
880 | class imanifestrevisionwritable(imanifestrevisionbase): | |
|
881 | """Interface representing a manifest revision that can be committed.""" | |
|
882 | ||
|
883 | def write(transaction, linkrev, p1node, p2node, added, removed): | |
|
884 | """Add this revision to storage. | |
|
885 | ||
|
886 | Takes a transaction object, the changeset revision number it will | |
|
887 | be associated with, its parent nodes, and lists of added and | |
|
888 | removed paths. | |
|
889 | ||
|
890 | Returns the binary node of the created revision. | |
|
891 | """ | |
|
892 | ||
|
893 | class imanifestlog(interfaceutil.Interface): | |
|
894 | """Interface representing a collection of manifest snapshots.""" | |
|
895 | ||
|
896 | def __getitem__(node): | |
|
897 | """Obtain a manifest instance for a given binary node. | |
|
898 | ||
|
899 | Equivalent to calling ``self.get('', node)``. | |
|
900 | ||
|
901 | The returned object conforms to the ``imanifestrevisionstored`` | |
|
902 | interface. | |
|
903 | """ | |
|
904 | ||
|
905 | def get(dir, node, verify=True): | |
|
906 | """Retrieve the manifest instance for a given directory and binary node. | |
|
907 | ||
|
908 | ``node`` always refers to the node of the root manifest (which will be | |
|
909 | the only manifest if flat manifests are being used). | |
|
910 | ||
|
911 | If ``dir`` is the empty string, the root manifest is returned. Otherwise | |
|
912 | the manifest for the specified directory will be returned (requires | |
|
913 | tree manifests). | |
|
914 | ||
|
915 | If ``verify`` is True, ``LookupError`` is raised if the node is not | |
|
916 | known. | |
|
917 | ||
|
918 | The returned object conforms to the ``imanifestrevisionstored`` | |
|
919 | interface. | |
|
920 | """ | |
|
921 | ||
|
922 | def clearcaches(): | |
|
923 | """Clear caches associated with this collection.""" | |
|
924 | ||
|
645 | 925 | class completelocalrepository(interfaceutil.Interface): |
|
646 | 926 | """Monolithic interface for local repositories. |
|
647 | 927 | |
@@ -757,7 +1037,10 class completelocalrepository(interfaceu | |||
|
757 | 1037 | """A handle on the changelog revlog.""") |
|
758 | 1038 | |
|
759 | 1039 | manifestlog = interfaceutil.Attribute( |
|
760 |
"""A |
|
|
1040 | """An instance conforming to the ``imanifestlog`` interface. | |
|
1041 | ||
|
1042 | Provides access to manifests for the repository. | |
|
1043 | """) | |
|
761 | 1044 | |
|
762 | 1045 | dirstate = interfaceutil.Attribute( |
|
763 | 1046 | """Working directory state.""") |
@@ -25,6 +25,7 from mercurial import ( | |||
|
25 | 25 | filelog, |
|
26 | 26 | httppeer, |
|
27 | 27 | localrepo, |
|
28 | manifest, | |
|
28 | 29 | pycompat, |
|
29 | 30 | repository, |
|
30 | 31 | sshpeer, |
@@ -164,9 +165,35 def main(): | |||
|
164 | 165 | checkzobject(httpv2) |
|
165 | 166 | |
|
166 | 167 | ziverify.verifyClass(repository.ifilestorage, filelog.filelog) |
|
168 | ziverify.verifyClass(repository.imanifestdict, manifest.manifestdict) | |
|
169 | ziverify.verifyClass(repository.imanifestrevisionstored, | |
|
170 | manifest.manifestctx) | |
|
171 | ziverify.verifyClass(repository.imanifestrevisionwritable, | |
|
172 | manifest.memmanifestctx) | |
|
173 | ziverify.verifyClass(repository.imanifestrevisionstored, | |
|
174 | manifest.treemanifestctx) | |
|
175 | ziverify.verifyClass(repository.imanifestrevisionwritable, | |
|
176 | manifest.memtreemanifestctx) | |
|
177 | ziverify.verifyClass(repository.imanifestlog, manifest.manifestlog) | |
|
167 | 178 | |
|
168 | 179 | vfs = vfsmod.vfs(b'.') |
|
169 | 180 | fl = filelog.filelog(vfs, b'dummy.i') |
|
170 | 181 | checkzobject(fl, allowextra=True) |
|
171 | 182 | |
|
183 | # Conforms to imanifestlog. | |
|
184 | ml = manifest.manifestlog(vfs, repo) | |
|
185 | checkzobject(ml) | |
|
186 | checkzobject(repo.manifestlog) | |
|
187 | ||
|
188 | # Conforms to imanifestrevision. | |
|
189 | mctx = ml[repo[0].manifestnode()] | |
|
190 | checkzobject(mctx) | |
|
191 | ||
|
192 | # Conforms to imanifestrevisionwritable. | |
|
193 | checkzobject(mctx.new()) | |
|
194 | checkzobject(mctx.copy()) | |
|
195 | ||
|
196 | # Conforms to imanifestdict. | |
|
197 | checkzobject(mctx.read()) | |
|
198 | ||
|
172 | 199 | main() |
General Comments 0
You need to be logged in to leave comments.
Login now