Mercurial > hg
changeset 47788:48f07adbda98 stable
streamclone: ensure the server sends the right amount of data
Otherwise, the client would fail with some confusing error. I have
seen an error which I think is this, perhaps due to a concurrent
revlog split, which streamclones do not handle correctly and would
result in a short read of the index of the revlog being split.
Differential Revision: https://phab.mercurial-scm.org/D11236
author | Valentin Gatien-Baron <valentin.gatienbaron@gmail.com> |
---|---|
date | Sun, 01 Aug 2021 10:54:03 -0400 |
parents | 48da5c325750 |
children | 064cd182555f |
files | mercurial/streamclone.py |
diffstat | 1 files changed, 15 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/streamclone.py Thu Jul 29 16:23:45 2021 -0400 +++ b/mercurial/streamclone.py Sun Aug 01 10:54:03 2021 -0400 @@ -583,7 +583,7 @@ # copy is delayed until we are in the try entries = [_filterfull(e, copy, vfsmap) for e in entries] yield None # this release the lock on the repository - seen = 0 + totalbytecount = 0 for src, name, ftype, data in entries: vfs = vfsmap[src] @@ -595,6 +595,7 @@ elif ftype == _filefull: fp = open(data, b'rb') size = util.fstat(fp).st_size + bytecount = 0 try: yield util.uvarintencode(size) yield name @@ -603,9 +604,20 @@ else: chunks = util.filechunkiter(fp, limit=size) for chunk in chunks: - seen += len(chunk) - progress.update(seen) + bytecount += len(chunk) + totalbytecount += len(chunk) + progress.update(totalbytecount) yield chunk + if bytecount != size: + # Would most likely be caused by a race due to `hg strip` or + # a revlog split + raise error.Abort( + _( + b'clone could only read %d bytes from %s, but ' + b'expected %d bytes' + ) + % (bytecount, name, size) + ) finally: fp.close()