Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/localrepo.py @ 2778:fdc232d8a193
Move repo.verify
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 07 Aug 2006 16:27:09 -0500 |
parents | b550cd82f92a |
children | 987c31e2a08c |
comparison
equal
deleted
inserted
replaced
2777:81d7db1aa0fb | 2778:fdc232d8a193 |
---|---|
1691 self.hook("incoming", node=hex(self.changelog.node(i)), | 1691 self.hook("incoming", node=hex(self.changelog.node(i)), |
1692 source=srctype, url=url) | 1692 source=srctype, url=url) |
1693 | 1693 |
1694 return newheads - oldheads + 1 | 1694 return newheads - oldheads + 1 |
1695 | 1695 |
1696 def verify(self): | |
1697 filelinkrevs = {} | |
1698 filenodes = {} | |
1699 changesets = revisions = files = 0 | |
1700 errors = [0] | |
1701 warnings = [0] | |
1702 neededmanifests = {} | |
1703 | |
1704 def err(msg): | |
1705 self.ui.warn(msg + "\n") | |
1706 errors[0] += 1 | |
1707 | |
1708 def warn(msg): | |
1709 self.ui.warn(msg + "\n") | |
1710 warnings[0] += 1 | |
1711 | |
1712 def checksize(obj, name): | |
1713 d = obj.checksize() | |
1714 if d[0]: | |
1715 err(_("%s data length off by %d bytes") % (name, d[0])) | |
1716 if d[1]: | |
1717 err(_("%s index contains %d extra bytes") % (name, d[1])) | |
1718 | |
1719 def checkversion(obj, name): | |
1720 if obj.version != revlog.REVLOGV0: | |
1721 if not revlogv1: | |
1722 warn(_("warning: `%s' uses revlog format 1") % name) | |
1723 elif revlogv1: | |
1724 warn(_("warning: `%s' uses revlog format 0") % name) | |
1725 | |
1726 revlogv1 = self.revlogversion != revlog.REVLOGV0 | |
1727 if self.ui.verbose or revlogv1 != self.revlogv1: | |
1728 self.ui.status(_("repository uses revlog format %d\n") % | |
1729 (revlogv1 and 1 or 0)) | |
1730 | |
1731 seen = {} | |
1732 self.ui.status(_("checking changesets\n")) | |
1733 checksize(self.changelog, "changelog") | |
1734 | |
1735 for i in range(self.changelog.count()): | |
1736 changesets += 1 | |
1737 n = self.changelog.node(i) | |
1738 l = self.changelog.linkrev(n) | |
1739 if l != i: | |
1740 err(_("incorrect link (%d) for changeset revision %d") %(l, i)) | |
1741 if n in seen: | |
1742 err(_("duplicate changeset at revision %d") % i) | |
1743 seen[n] = 1 | |
1744 | |
1745 for p in self.changelog.parents(n): | |
1746 if p not in self.changelog.nodemap: | |
1747 err(_("changeset %s has unknown parent %s") % | |
1748 (short(n), short(p))) | |
1749 try: | |
1750 changes = self.changelog.read(n) | |
1751 except KeyboardInterrupt: | |
1752 self.ui.warn(_("interrupted")) | |
1753 raise | |
1754 except Exception, inst: | |
1755 err(_("unpacking changeset %s: %s") % (short(n), inst)) | |
1756 continue | |
1757 | |
1758 neededmanifests[changes[0]] = n | |
1759 | |
1760 for f in changes[3]: | |
1761 filelinkrevs.setdefault(f, []).append(i) | |
1762 | |
1763 seen = {} | |
1764 self.ui.status(_("checking manifests\n")) | |
1765 checkversion(self.manifest, "manifest") | |
1766 checksize(self.manifest, "manifest") | |
1767 | |
1768 for i in range(self.manifest.count()): | |
1769 n = self.manifest.node(i) | |
1770 l = self.manifest.linkrev(n) | |
1771 | |
1772 if l < 0 or l >= self.changelog.count(): | |
1773 err(_("bad manifest link (%d) at revision %d") % (l, i)) | |
1774 | |
1775 if n in neededmanifests: | |
1776 del neededmanifests[n] | |
1777 | |
1778 if n in seen: | |
1779 err(_("duplicate manifest at revision %d") % i) | |
1780 | |
1781 seen[n] = 1 | |
1782 | |
1783 for p in self.manifest.parents(n): | |
1784 if p not in self.manifest.nodemap: | |
1785 err(_("manifest %s has unknown parent %s") % | |
1786 (short(n), short(p))) | |
1787 | |
1788 try: | |
1789 delta = mdiff.patchtext(self.manifest.delta(n)) | |
1790 except KeyboardInterrupt: | |
1791 self.ui.warn(_("interrupted")) | |
1792 raise | |
1793 except Exception, inst: | |
1794 err(_("unpacking manifest %s: %s") % (short(n), inst)) | |
1795 continue | |
1796 | |
1797 try: | |
1798 ff = [ l.split('\0') for l in delta.splitlines() ] | |
1799 for f, fn in ff: | |
1800 filenodes.setdefault(f, {})[bin(fn[:40])] = 1 | |
1801 except (ValueError, TypeError), inst: | |
1802 err(_("broken delta in manifest %s: %s") % (short(n), inst)) | |
1803 | |
1804 self.ui.status(_("crosschecking files in changesets and manifests\n")) | |
1805 | |
1806 for m, c in neededmanifests.items(): | |
1807 err(_("Changeset %s refers to unknown manifest %s") % | |
1808 (short(m), short(c))) | |
1809 del neededmanifests | |
1810 | |
1811 for f in filenodes: | |
1812 if f not in filelinkrevs: | |
1813 err(_("file %s in manifest but not in changesets") % f) | |
1814 | |
1815 for f in filelinkrevs: | |
1816 if f not in filenodes: | |
1817 err(_("file %s in changeset but not in manifest") % f) | |
1818 | |
1819 self.ui.status(_("checking files\n")) | |
1820 ff = filenodes.keys() | |
1821 ff.sort() | |
1822 for f in ff: | |
1823 if f == "/dev/null": | |
1824 continue | |
1825 files += 1 | |
1826 if not f: | |
1827 err(_("file without name in manifest %s") % short(n)) | |
1828 continue | |
1829 fl = self.file(f) | |
1830 checkversion(fl, f) | |
1831 checksize(fl, f) | |
1832 | |
1833 nodes = {nullid: 1} | |
1834 seen = {} | |
1835 for i in range(fl.count()): | |
1836 revisions += 1 | |
1837 n = fl.node(i) | |
1838 | |
1839 if n in seen: | |
1840 err(_("%s: duplicate revision %d") % (f, i)) | |
1841 if n not in filenodes[f]: | |
1842 err(_("%s: %d:%s not in manifests") % (f, i, short(n))) | |
1843 else: | |
1844 del filenodes[f][n] | |
1845 | |
1846 flr = fl.linkrev(n) | |
1847 if flr not in filelinkrevs.get(f, []): | |
1848 err(_("%s:%s points to unexpected changeset %d") | |
1849 % (f, short(n), flr)) | |
1850 else: | |
1851 filelinkrevs[f].remove(flr) | |
1852 | |
1853 # verify contents | |
1854 try: | |
1855 t = fl.read(n) | |
1856 except KeyboardInterrupt: | |
1857 self.ui.warn(_("interrupted")) | |
1858 raise | |
1859 except Exception, inst: | |
1860 err(_("unpacking file %s %s: %s") % (f, short(n), inst)) | |
1861 | |
1862 # verify parents | |
1863 (p1, p2) = fl.parents(n) | |
1864 if p1 not in nodes: | |
1865 err(_("file %s:%s unknown parent 1 %s") % | |
1866 (f, short(n), short(p1))) | |
1867 if p2 not in nodes: | |
1868 err(_("file %s:%s unknown parent 2 %s") % | |
1869 (f, short(n), short(p1))) | |
1870 nodes[n] = 1 | |
1871 | |
1872 # cross-check | |
1873 for node in filenodes[f]: | |
1874 err(_("node %s in manifests not in %s") % (hex(node), f)) | |
1875 | |
1876 self.ui.status(_("%d files, %d changesets, %d total revisions\n") % | |
1877 (files, changesets, revisions)) | |
1878 | |
1879 if warnings[0]: | |
1880 self.ui.warn(_("%d warnings encountered!\n") % warnings[0]) | |
1881 if errors[0]: | |
1882 self.ui.warn(_("%d integrity errors encountered!\n") % errors[0]) | |
1883 return 1 | |
1884 | |
1885 def stream_in(self, remote): | 1696 def stream_in(self, remote): |
1886 fp = remote.stream_out() | 1697 fp = remote.stream_out() |
1887 resp = int(fp.readline()) | 1698 resp = int(fp.readline()) |
1888 if resp != 0: | 1699 if resp != 0: |
1889 raise util.Abort(_('operation forbidden by server')) | 1700 raise util.Abort(_('operation forbidden by server')) |
1904 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') % | 1715 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') % |
1905 (util.bytecount(total_bytes), elapsed, | 1716 (util.bytecount(total_bytes), elapsed, |
1906 util.bytecount(total_bytes / elapsed))) | 1717 util.bytecount(total_bytes / elapsed))) |
1907 self.reload() | 1718 self.reload() |
1908 return len(self.heads()) + 1 | 1719 return len(self.heads()) + 1 |
1909 | 1720 |
1910 def clone(self, remote, heads=[], stream=False): | 1721 def clone(self, remote, heads=[], stream=False): |
1911 '''clone remote repository. | 1722 '''clone remote repository. |
1912 | 1723 |
1913 keyword arguments: | 1724 keyword arguments: |
1914 heads: list of revs to clone (forces use of pull) | 1725 heads: list of revs to clone (forces use of pull) |