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