Mercurial > hg
view mercurial/streamclone.py @ 7115:c5c2d43b01da
patchbomb: mime-encode headers and parts not containing patches
Do nothing for "hg email --test" to preserve display.
author | Christian Ebert <blacktrash@gmx.net> |
---|---|
date | Sat, 12 Jul 2008 19:12:10 +0100 |
parents | 63b5f4c73c98 |
children | 810ca383da9c |
line wrap: on
line source
# streamclone.py - streaming clone server support for mercurial # # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> # # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. import util, lock from i18n import _ class StreamException(Exception): def __init__(self, code): Exception.__init__(self) self.code = code def __str__(self): return '%i\n' % self.code # if server supports streaming clone, it advertises "stream" # capability with value that is version+flags of repo it is serving. # client only streams if it can read that repo format. # stream file format is simple. # # server writes out line that says how many files, how many total # bytes. separator is ascii space, byte counts are strings. # # then for each file: # # server writes out line that says file name, how many bytes in # file. separator is ascii nul, byte count is string. # # server writes out raw file data. def stream_out(repo, untrusted=False): '''stream out all metadata files in repository. writes to file-like object, must support write() and optional flush().''' if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted): raise StreamException(1) entries = [] total_bytes = 0 try: l = None try: repo.ui.debug(_('scanning\n')) # get consistent snapshot of repo, lock during scan l = repo.lock() for name, ename, size in repo.store.walk(): entries.append((name, size)) total_bytes += size finally: del l except (lock.LockHeld, lock.LockUnavailable), inst: raise StreamException(2) yield '0\n' repo.ui.debug(_('%d files, %d bytes to transfer\n') % (len(entries), total_bytes)) yield '%d %d\n' % (len(entries), total_bytes) for name, size in entries: repo.ui.debug(_('sending %s (%d bytes)\n') % (name, size)) yield '%s\0%d\n' % (name, size) for chunk in util.filechunkiter(repo.sopener(name), limit=size): yield chunk