diff --git a/mercurial/streamclone.py b/mercurial/streamclone.py --- a/mercurial/streamclone.py +++ b/mercurial/streamclone.py @@ -299,6 +299,20 @@ def consumev1(repo, fp, filecount, bytec repo.ui.progress(_('clone'), 0, total=bytecount, unit=_('bytes')) start = time.time() + # TODO: get rid of (potential) inconsistency + # + # If transaction is started and any @filecache property is + # changed at this point, it causes inconsistency between + # in-memory cached property and streamclone-ed file on the + # disk. Nested transaction prevents transaction scope "clone" + # below from writing in-memory changes out at the end of it, + # even though in-memory changes are discarded at the end of it + # regardless of transaction nesting. + # + # But transaction nesting can't be simply prohibited, because + # nesting occurs also in ordinary case (e.g. enabling + # clonebundles). + with repo.transaction('clone'): with repo.svfs.backgroundclosing(repo.ui, expectedcount=filecount): for i in xrange(filecount): @@ -322,8 +336,9 @@ def consumev1(repo, fp, filecount, bytec total=bytecount, unit=_('bytes')) ofp.write(chunk) - # Writing straight to files circumvented the inmemory caches - repo.invalidate(clearfilecache=True) + # force @filecache properties to be reloaded from + # streamclone-ed file at next access + repo.invalidate(clearfilecache=True) elapsed = time.time() - start if elapsed <= 0: diff --git a/tests/test-bundle.t b/tests/test-bundle.t --- a/tests/test-bundle.t +++ b/tests/test-bundle.t @@ -310,9 +310,51 @@ Unpacking packed1 bundles with "hg unbun packed1 can be consumed from debug command +(this also confirms that streamclone-ed changes are visible via +@filecache properties to in-process procedures before closing +transaction) + + $ cat > $TESTTMP/showtip.py < from __future__ import absolute_import + > + > def showtip(ui, repo, hooktype, **kwargs): + > ui.warn('%s: %s\n' % (hooktype, repo['tip'].hex()[:12])) + > + > def reposetup(ui, repo): + > # this confirms (and ensures) that (empty) 00changelog.i + > # before streamclone is already cached as repo.changelog + > ui.setconfig('hooks', 'pretxnopen.showtip', showtip) + > + > # this confirms that streamclone-ed changes are visible to + > # in-process procedures before closing transaction + > ui.setconfig('hooks', 'pretxnclose.showtip', showtip) + > + > # this confirms that streamclone-ed changes are still visible + > # after closing transaction + > ui.setconfig('hooks', 'txnclose.showtip', showtip) + > EOF + $ cat >> $HGRCPATH < [extensions] + > showtip = $TESTTMP/showtip.py + > EOF + $ hg -R packed debugapplystreamclonebundle packed.hg 6 files to transfer, 2.60 KB of data + pretxnopen: 000000000000 + pretxnclose: aa35859c02ea transferred 2.60 KB in *.* seconds (* */sec) (glob) + txnclose: aa35859c02ea + +(for safety, confirm visibility of streamclone-ed changes by another +process, too) + + $ hg -R packed tip -T "{node|short}\n" + aa35859c02ea + + $ cat >> $HGRCPATH < [extensions] + > showtip = ! + > EOF Does not work on non-empty repo