##// END OF EJS Templates
Fix handling of paths when run outside the repo....
Fix handling of paths when run outside the repo. The main problem was that dirstate.getcwd() returned just "", which was interpreted as "we're at the repo root". It now returns an absolute path. The util.pathto function was also changed to deal with the "cwd is an absolute path" case.

File last commit:

r4134:9dc64c84 merge default
r4230:c93562fb default
Show More
streamclone.py
96 lines | 3.2 KiB | text/x-python | PythonLexer
Vadim Gelfer
add support for streaming clone....
r2612 # 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.
from demandload import demandload
from i18n import gettext as _
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687 demandload(globals(), "os stat util lock")
Vadim Gelfer
add support for streaming clone....
r2612
# 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.
def walkrepo(root):
'''iterate over metadata files in repository.
walk in natural (sorted) order.
yields 2-tuples: name of .d or .i file, size of file.'''
strip_count = len(root) + len(os.sep)
def walk(path, recurse):
ents = os.listdir(path)
ents.sort()
for e in ents:
pe = os.path.join(path, e)
st = os.lstat(pe)
if stat.S_ISDIR(st.st_mode):
if recurse:
for x in walk(pe, True):
yield x
else:
if not stat.S_ISREG(st.st_mode) or len(e) < 2:
continue
sfx = e[-2:]
if sfx in ('.d', '.i'):
yield pe[strip_count:], st.st_size
# write file data first
for x in walk(os.path.join(root, 'data'), True):
yield x
# write manifest before changelog
meta = list(walk(root, False))
Vadim Gelfer
fix problem with uncompressed clone and python 2.3.
r2623 meta.sort()
meta.reverse()
Vadim Gelfer
add support for streaming clone....
r2612 for x in meta:
yield x
# 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, fileobj):
'''stream out all metadata files in repository.
writes to file-like object, must support write() and optional flush().'''
Vadim Gelfer
clone: disable stream support on server side by default....
r2621
Vadim Gelfer
rename stream hgrc option to compressed.
r2622 if not repo.ui.configbool('server', 'uncompressed'):
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 fileobj.write('1\n')
return
Vadim Gelfer
add support for streaming clone....
r2612 # get consistent snapshot of repo. lock during scan so lock not
# needed while we stream, and commits can happen.
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687 try:
repolock = repo.lock()
except (lock.LockHeld, lock.LockUnavailable), inst:
repo.ui.warn('locking the repository failed: %s\n' % (inst,))
fileobj.write('2\n')
return
fileobj.write('0\n')
Vadim Gelfer
add support for streaming clone....
r2612 repo.ui.debug('scanning\n')
entries = []
total_bytes = 0
Benoit Boissinot
introduce localrepo.spath for the store path, sopener fixes
r3791 for name, size in walkrepo(repo.spath):
Patrick Mezard
streamclone: stream_out tried to decodefilename non-normalized paths
r4127 name = repo.decodefn(util.pconvert(name))
Vadim Gelfer
add support for streaming clone....
r2612 entries.append((name, size))
total_bytes += size
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687 repolock.release()
Vadim Gelfer
add support for streaming clone....
r2612
repo.ui.debug('%d files, %d bytes to transfer\n' %
(len(entries), total_bytes))
fileobj.write('%d %d\n' % (len(entries), total_bytes))
for name, size in entries:
repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
fileobj.write('%s\0%d\n' % (name, size))
Benoit Boissinot
introduce localrepo.spath for the store path, sopener fixes
r3791 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
Vadim Gelfer
add support for streaming clone....
r2612 fileobj.write(chunk)
flush = getattr(fileobj, 'flush', None)
if flush: flush()