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')) |