[PATCH 1 of 4] streamclone: force @filecache properties to be reloaded from file

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Fri Sep 2 14:34:10 EDT 2016

# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1472840247 -32400
#      Sat Sep 03 03:17:27 2016 +0900
# Node ID b9866cdaf302d52a7ddafa60a8a8e5155a764342
# Parent  ea486ad5201ccc2cfc254277ba19c81c3131781a
streamclone: force @filecache properties to be reloaded from file

Before this patch, consumev1() invokes repo.invalidate() after closing
transaction, to force @filecache properties to be reloaded from files
at next access, because streamclone writes data into files directly.

But this doesn't work as expected in the case below:

  1. at closing transaction, repo._refreshfilecachestats() refreshes
     file stat of each @filecache properties with streamclone-ed files

     This means that in-memory properties are treated as valid.

  2. but streamclone doesn't changes in-memory properties

     This means that in-memory properties are actually invalid.

  3. repo.invalidate() just forces to examine file stat of @filecache
     properties at the first access after it

     Such examination should concludes that reloading from file isn't
     needed, because file stat was already refreshed at (1).

     Therefore, invalid in-memory cached properties (2) are
     unintentionally treated as valid (1).

This patch invokes repo.invalidate() with clearfilecache=True, to
force @filecache properties to be reloaded from file at next access.

BTW, it is accidental that repo.invalidate() without
clearfilecache=True in streamclone case seems to work as expected
before this patch.

If transaction is started via "filtered repo" object,
repo._refreshfilecachestats() tries to refresh file stat of each
@filecache properties on "filtered repo" object, even though all of
them are stored into "unfiltered repo" object.

In this case, repo._refreshfilecachestats() does nothing
unintentionally, but this unexpected behavior causes reloading
@filecache properties after repo.invalidate().

This is reason why this patch should be applied before making
_refreshfilecachestats() correctly refresh file stat of @filecache

diff --git a/mercurial/streamclone.py b/mercurial/streamclone.py
--- a/mercurial/streamclone.py
+++ b/mercurial/streamclone.py
@@ -323,7 +323,7 @@ def consumev1(repo, fp, filecount, bytec
         # Writing straight to files circumvented the inmemory caches
-        repo.invalidate()
+        repo.invalidate(clearfilecache=True)
         elapsed = time.time() - start
         if elapsed <= 0:

More information about the Mercurial-devel mailing list