Mercurial > hg
comparison mercurial/exchange.py @ 34364:ff406f3e57b2
exchange: perform stream clone with clone bundle with --uncompressed
Previously, `hg clone --uncompressed` would always clone from the
origin server, even if a streaming clone bundle were available.
With this change, we invoke the clone bundle mechanism before the
stream clone mechanism, giving clone bundles the opportunity to
handle --uncompressed (which is mapped to pullop.streamclonepreferred).
The clone bundle filtering code now filters out entries that aren't
stream clones when a stream clone is requested. If a stream clone
clone bundle entry is present, it will be used. Otherwise, the client
will fall back to a server-based streaming clone.
.. feature::
`hg clone --uncompressed` uses clone bundles when possible
Differential Revision: https://phab.mercurial-scm.org/D833
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 28 Sep 2017 15:24:54 +0100 |
parents | 6c7aaf59b21e |
children | cd3f39716fd3 |
comparison
equal
deleted
inserted
replaced
34363:880e47351d1a | 34364:ff406f3e57b2 |
---|---|
1237 wlock = lock = None | 1237 wlock = lock = None |
1238 try: | 1238 try: |
1239 wlock = pullop.repo.wlock() | 1239 wlock = pullop.repo.wlock() |
1240 lock = pullop.repo.lock() | 1240 lock = pullop.repo.lock() |
1241 pullop.trmanager = transactionmanager(repo, 'pull', remote.url()) | 1241 pullop.trmanager = transactionmanager(repo, 'pull', remote.url()) |
1242 streamclone.maybeperformlegacystreamclone(pullop) | |
1243 # This should ideally be in _pullbundle2(). However, it needs to run | 1242 # This should ideally be in _pullbundle2(). However, it needs to run |
1244 # before discovery to avoid extra work. | 1243 # before discovery to avoid extra work. |
1245 _maybeapplyclonebundle(pullop) | 1244 _maybeapplyclonebundle(pullop) |
1245 streamclone.maybeperformlegacystreamclone(pullop) | |
1246 _pulldiscovery(pullop) | 1246 _pulldiscovery(pullop) |
1247 if pullop.canusebundle2: | 1247 if pullop.canusebundle2: |
1248 _pullbundle2(pullop) | 1248 _pullbundle2(pullop) |
1249 _pullchangeset(pullop) | 1249 _pullchangeset(pullop) |
1250 _pullphase(pullop) | 1250 _pullphase(pullop) |
1862 if not entries: | 1862 if not entries: |
1863 repo.ui.note(_('no clone bundles available on remote; ' | 1863 repo.ui.note(_('no clone bundles available on remote; ' |
1864 'falling back to regular clone\n')) | 1864 'falling back to regular clone\n')) |
1865 return | 1865 return |
1866 | 1866 |
1867 entries = filterclonebundleentries(repo, entries) | 1867 entries = filterclonebundleentries( |
1868 repo, entries, streamclonerequested=pullop.streamclonerequested) | |
1869 | |
1868 if not entries: | 1870 if not entries: |
1869 # There is a thundering herd concern here. However, if a server | 1871 # There is a thundering herd concern here. However, if a server |
1870 # operator doesn't advertise bundles appropriate for its clients, | 1872 # operator doesn't advertise bundles appropriate for its clients, |
1871 # they deserve what's coming. Furthermore, from a client's | 1873 # they deserve what's coming. Furthermore, from a client's |
1872 # perspective, no automatic fallback would mean not being able to | 1874 # perspective, no automatic fallback would mean not being able to |
1931 | 1933 |
1932 m.append(attrs) | 1934 m.append(attrs) |
1933 | 1935 |
1934 return m | 1936 return m |
1935 | 1937 |
1936 def filterclonebundleentries(repo, entries): | 1938 def filterclonebundleentries(repo, entries, streamclonerequested=False): |
1937 """Remove incompatible clone bundle manifest entries. | 1939 """Remove incompatible clone bundle manifest entries. |
1938 | 1940 |
1939 Accepts a list of entries parsed with ``parseclonebundlesmanifest`` | 1941 Accepts a list of entries parsed with ``parseclonebundlesmanifest`` |
1940 and returns a new list consisting of only the entries that this client | 1942 and returns a new list consisting of only the entries that this client |
1941 should be able to apply. | 1943 should be able to apply. |
1946 newentries = [] | 1948 newentries = [] |
1947 for entry in entries: | 1949 for entry in entries: |
1948 spec = entry.get('BUNDLESPEC') | 1950 spec = entry.get('BUNDLESPEC') |
1949 if spec: | 1951 if spec: |
1950 try: | 1952 try: |
1951 parsebundlespec(repo, spec, strict=True) | 1953 comp, version, params = parsebundlespec(repo, spec, strict=True) |
1954 | |
1955 # If a stream clone was requested, filter out non-streamclone | |
1956 # entries. | |
1957 if streamclonerequested and (comp != 'UN' or version != 's1'): | |
1958 repo.ui.debug('filtering %s because not a stream clone\n' % | |
1959 entry['URL']) | |
1960 continue | |
1961 | |
1952 except error.InvalidBundleSpecification as e: | 1962 except error.InvalidBundleSpecification as e: |
1953 repo.ui.debug(str(e) + '\n') | 1963 repo.ui.debug(str(e) + '\n') |
1954 continue | 1964 continue |
1955 except error.UnsupportedBundleSpecification as e: | 1965 except error.UnsupportedBundleSpecification as e: |
1956 repo.ui.debug('filtering %s because unsupported bundle ' | 1966 repo.ui.debug('filtering %s because unsupported bundle ' |
1957 'spec: %s\n' % (entry['URL'], str(e))) | 1967 'spec: %s\n' % (entry['URL'], str(e))) |
1958 continue | 1968 continue |
1969 # If we don't have a spec and requested a stream clone, we don't know | |
1970 # what the entry is so don't attempt to apply it. | |
1971 elif streamclonerequested: | |
1972 repo.ui.debug('filtering %s because cannot determine if a stream ' | |
1973 'clone bundle\n' % entry['URL']) | |
1974 continue | |
1959 | 1975 |
1960 if 'REQUIRESNI' in entry and not sslutil.hassni: | 1976 if 'REQUIRESNI' in entry and not sslutil.hassni: |
1961 repo.ui.debug('filtering %s because SNI not supported\n' % | 1977 repo.ui.debug('filtering %s because SNI not supported\n' % |
1962 entry['URL']) | 1978 entry['URL']) |
1963 continue | 1979 continue |