##// END OF EJS Templates
protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman -
r11627:04f76a95 default
parent child Browse files
Show More
@@ -9,7 +9,7 b' import urllib, tempfile, os'
9 from i18n import _
9 from i18n import _
10 from node import bin, hex
10 from node import bin, hex
11 import changegroup as changegroupmod
11 import changegroup as changegroupmod
12 import streamclone, repo, error, encoding, util
12 import repo, error, encoding, util, store
13 import pushkey as pushkey_
13 import pushkey as pushkey_
14
14
15 # list of nodes encoding / decoding
15 # list of nodes encoding / decoding
@@ -171,7 +171,7 b' def branches(repo, proto, nodes):'
171
171
172 def capabilities(repo, proto):
172 def capabilities(repo, proto):
173 caps = 'lookup changegroupsubset branchmap pushkey'.split()
173 caps = 'lookup changegroupsubset branchmap pushkey'.split()
174 if streamclone.allowed(repo.ui):
174 if _allowstream(repo.ui):
175 caps.append('stream=%d' % repo.changelog.version)
175 caps.append('stream=%d' % repo.changelog.version)
176 caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
176 caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
177 return ' '.join(caps)
177 return ' '.join(caps)
@@ -220,8 +220,52 b' def pushkey(repo, proto, namespace, key,'
220 r = pushkey_.push(repo, namespace, key, old, new)
220 r = pushkey_.push(repo, namespace, key, old, new)
221 return '%s\n' % int(r)
221 return '%s\n' % int(r)
222
222
223 def _allowstream(ui):
224 return ui.configbool('server', 'uncompressed', True, untrusted=True)
225
223 def stream(repo, proto):
226 def stream(repo, proto):
224 return streamres(streamclone.stream_out(repo))
227 '''If the server supports streaming clone, it advertises the "stream"
228 capability with a value representing the version and flags of the repo
229 it is serving. Client checks to see if it understands the format.
230
231 The format is simple: the server writes out a line with the amount
232 of files, then the total amount of bytes to be transfered (separated
233 by a space). Then, for each file, the server first writes the filename
234 and filesize (separated by the null character), then the file contents.
235 '''
236
237 if not _allowstream(repo.ui):
238 return '1\n'
239
240 entries = []
241 total_bytes = 0
242 try:
243 # get consistent snapshot of repo, lock during scan
244 lock = repo.lock()
245 try:
246 repo.ui.debug('scanning\n')
247 for name, ename, size in repo.store.walk():
248 entries.append((name, size))
249 total_bytes += size
250 finally:
251 lock.release()
252 except error.LockError:
253 return '2\n' # error: 2
254
255 def streamer(repo, entries, total):
256 '''stream out all metadata files in repository.'''
257 yield '0\n' # success
258 repo.ui.debug('%d files, %d bytes to transfer\n' %
259 (len(entries), total_bytes))
260 yield '%d %d\n' % (len(entries), total_bytes)
261 for name, size in entries:
262 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
263 # partially encode name over the wire for backwards compat
264 yield '%s\0%d\n' % (store.encodedir(name), size)
265 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
266 yield chunk
267
268 return streamres(streamer(repo, entries, total_bytes))
225
269
226 def unbundle(repo, proto, heads):
270 def unbundle(repo, proto, heads):
227 their_heads = decodelist(heads)
271 their_heads = decodelist(heads)
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now