##// END OF EJS Templates
add a fix for issue 1175...
add a fix for issue 1175 If we copy a file followed by an update, it's possible for the parent manifest to no longer contain the source file of the copy, which could cause commit to fail. If this happens, we search backwares from the first parent to find the most likely original revision.

File last commit:

r6840:80e51429 default
r6875:0d714a48 default
Show More
streamclone.py
94 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.
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 import os, osutil, 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):
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 for e, kind, st in osutil.listdir(path, stat=True):
Vadim Gelfer
add support for streaming clone....
r2612 pe = os.path.join(path, e)
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 if kind == stat.S_IFDIR:
Vadim Gelfer
add support for streaming clone....
r2612 if recurse:
for x in walk(pe, True):
yield x
else:
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396 if kind != stat.S_IFREG or len(e) < 2:
Vadim Gelfer
add support for streaming clone....
r2612 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.
Edouard Gomez
Fix inconsistency for the stream_out capability in hgweb...
r4834 def stream_out(repo, fileobj, untrusted=False):
Vadim Gelfer
add support for streaming clone....
r2612 '''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
Edouard Gomez
Fix inconsistency for the stream_out capability in hgweb...
r4834 if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted):
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.
Benoit Boissinot
fix typo
r5456 repolock = None
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687 try:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 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
Thomas Arendsen Hein
Handle locking exceptions if streaming clone can't lock the repo. (Issue324)
r3687
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 fileobj.write('0\n')
repo.ui.debug('scanning\n')
entries = []
total_bytes = 0
for name, size in walkrepo(repo.spath):
name = repo.decodefn(util.pconvert(name))
entries.append((name, size))
total_bytes += size
finally:
del repolock
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()