Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/localrepo.py @ 12296:d7fff529d85d
clone: only use stream when we understand the revlog format
This patch fixes issues with stream cloning in the presense of parentdelta,
lwcopy and similar additions that change the interpretation of the revlog
format, or the format itself.
Currently, the stream capability is sent like this:
stream=<version of changelog>
But the client doesn't actually check the version number; also, it only checks
the changelog and it doesn't capture the interpretation-changes and
flag-changes in parentdelta and lwcopy.
This patch removes the 'stream' capability whenever we use a non-basic revlog
format, to prevent old clients from receiving incorrect data. In those cases,
a new capability called 'streamreqs' is added instead. Instead of a revlog
version, it comes with a list of revlog-format relevant requirements, which
are a subset of the repository requirements, excluding things that are not
relevant for stream.
New clients use this to determine whether or not they can stream. Old clients
only look for the 'stream' capability, as always. New servers will still send
this when serving old repositories.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Wed, 15 Sep 2010 11:06:22 +0200 |
parents | 3388ab21d768 |
children | 44c7dfc2f6a3 |
comparison
equal
deleted
inserted
replaced
12295:3388ab21d768 | 12296:d7fff529d85d |
---|---|
1782 return newheads - oldheads - 1 | 1782 return newheads - oldheads - 1 |
1783 else: | 1783 else: |
1784 return newheads - oldheads + 1 | 1784 return newheads - oldheads + 1 |
1785 | 1785 |
1786 | 1786 |
1787 def stream_in(self, remote): | 1787 def stream_in(self, remote, requirements): |
1788 fp = remote.stream_out() | 1788 fp = remote.stream_out() |
1789 l = fp.readline() | 1789 l = fp.readline() |
1790 try: | 1790 try: |
1791 resp = int(l) | 1791 resp = int(l) |
1792 except ValueError: | 1792 except ValueError: |
1827 if elapsed <= 0: | 1827 if elapsed <= 0: |
1828 elapsed = 0.001 | 1828 elapsed = 0.001 |
1829 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') % | 1829 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') % |
1830 (util.bytecount(total_bytes), elapsed, | 1830 (util.bytecount(total_bytes), elapsed, |
1831 util.bytecount(total_bytes / elapsed))) | 1831 util.bytecount(total_bytes / elapsed))) |
1832 | |
1833 # new requirements = old non-format requirements + new format-related | |
1834 # requirements from the streamed-in repository | |
1835 requirements.update(set(self.requirements) - self.supportedformats) | |
1836 self._applyrequirements(requirements) | |
1837 self._writerequirements() | |
1838 | |
1832 self.invalidate() | 1839 self.invalidate() |
1833 return len(self.heads()) + 1 | 1840 return len(self.heads()) + 1 |
1834 | 1841 |
1835 def clone(self, remote, heads=[], stream=False): | 1842 def clone(self, remote, heads=[], stream=False): |
1836 '''clone remote repository. | 1843 '''clone remote repository. |
1845 | 1852 |
1846 # if revlog format changes, client will have to check version | 1853 # if revlog format changes, client will have to check version |
1847 # and format flags on "stream" capability, and use | 1854 # and format flags on "stream" capability, and use |
1848 # uncompressed only if compatible. | 1855 # uncompressed only if compatible. |
1849 | 1856 |
1850 if stream and not heads and remote.capable('stream'): | 1857 if stream and not heads: |
1851 return self.stream_in(remote) | 1858 # 'stream' means remote revlog format is revlogv1 only |
1859 if remote.capable('stream'): | |
1860 return self.stream_in(remote, set(('revlogv1',))) | |
1861 # otherwise, 'streamreqs' contains the remote revlog format | |
1862 streamreqs = remote.capable('streamreqs') | |
1863 if streamreqs: | |
1864 streamreqs = set(streamreqs.split(',')) | |
1865 # if we support it, stream in and adjust our requirements | |
1866 if not streamreqs - self.supportedformats: | |
1867 return self.stream_in(remote, streamreqs) | |
1852 return self.pull(remote, heads) | 1868 return self.pull(remote, heads) |
1853 | 1869 |
1854 def pushkey(self, namespace, key, old, new): | 1870 def pushkey(self, namespace, key, old, new): |
1855 return pushkey.push(self, namespace, key, old, new) | 1871 return pushkey.push(self, namespace, key, old, new) |
1856 | 1872 |