comparison mercurial/streamclone.py @ 26446:3ea10bb761ce

streamclone: refactor code for deciding to stream clone Having this in a standalone function will eventually enable bundle2 to share code with the bundle1 code path. While I was here, I also added some comments to add clarity.
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 02 Oct 2015 22:22:11 -0700
parents f134fb33c906
children 591088f7028a
comparison
equal deleted inserted replaced
26445:f134fb33c906 26446:3ea10bb761ce
15 error, 15 error,
16 store, 16 store,
17 util, 17 util,
18 ) 18 )
19 19
20 def canperformstreamclone(repo, remote, heads, streamrequested=None):
21 """Whether it is possible to perform a streaming clone as part of pull.
22
23 Returns a tuple of (supported, requirements). ``supported`` is True if
24 streaming clone is supported and False otherwise. ``requirements`` is
25 a set of repo requirements from the remote, or ``None`` if stream clone
26 isn't supported.
27 """
28 # Streaming clone only works if all data is being requested.
29 if heads:
30 return False, None
31
32 # If we don't have a preference, let the server decide for us. This
33 # likely only comes into play in LANs.
34 if streamrequested is None:
35 # The server can advertise whether to prefer streaming clone.
36 streamrequested = remote.capable('stream-preferred')
37
38 if not streamrequested:
39 return False, None
40
41 # In order for stream clone to work, the client has to support all the
42 # requirements advertised by the server.
43 #
44 # The server advertises its requirements via the "stream" and "streamreqs"
45 # capability. "stream" (a value-less capability) is advertised if and only
46 # if the only requirement is "revlogv1." Else, the "streamreqs" capability
47 # is advertised and contains a comma-delimited list of requirements.
48 requirements = set()
49 if remote.capable('stream'):
50 requirements.add('revlogv1')
51 else:
52 streamreqs = remote.capable('streamreqs')
53 # This is weird and shouldn't happen with modern servers.
54 if not streamreqs:
55 return False, None
56
57 streamreqs = set(streamreqs.split(','))
58 # Server requires something we don't support. Bail.
59 if streamreqs - repo.supportedformats:
60 return False, None
61 requirements = streamreqs
62
63 return True, requirements
64
20 def maybeperformstreamclone(repo, remote, heads, stream): 65 def maybeperformstreamclone(repo, remote, heads, stream):
21 # now, all clients that can request uncompressed clones can 66 supported, requirements = canperformstreamclone(repo, remote, heads,
22 # read repo formats supported by all servers that can serve 67 streamrequested=stream)
23 # them. 68 if not supported:
24 69 return
25 # if revlog format changes, client will have to check version 70
26 # and format flags on "stream" capability, and use 71 streamin(repo, remote, requirements)
27 # uncompressed only if compatible.
28
29 if stream is None:
30 # if the server explicitly prefers to stream (for fast LANs)
31 stream = remote.capable('stream-preferred')
32
33 if stream and not heads:
34 # 'stream' means remote revlog format is revlogv1 only
35 if remote.capable('stream'):
36 streamin(repo, remote, set(('revlogv1',)))
37 else:
38 # otherwise, 'streamreqs' contains the remote revlog format
39 streamreqs = remote.capable('streamreqs')
40 if streamreqs:
41 streamreqs = set(streamreqs.split(','))
42 # if we support it, stream in and adjust our requirements
43 if not streamreqs - repo.supportedformats:
44 streamin(repo, remote, streamreqs)
45 72
46 def allowservergeneration(ui): 73 def allowservergeneration(ui):
47 """Whether streaming clones are allowed from the server.""" 74 """Whether streaming clones are allowed from the server."""
48 return ui.configbool('server', 'uncompressed', True, untrusted=True) 75 return ui.configbool('server', 'uncompressed', True, untrusted=True)
49 76