[PATCH 2 of 2 STABLE V2] largefiles: don't copy largefiles from working dir to the store while converting

Matt Harbison matt_harbison at yahoo.com
Tue Oct 23 21:33:57 CDT 2012


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1351042339 14400
# Branch stable
# Node ID 936113ca0f11832da68bcca03c9363e967b573ed
# Parent  65787aa94114382cb175f4f17e90a251f637856a
largefiles: don't copy largefiles from working dir to the store while converting

Previously, if one or more largefiles for a repo being converted were not in the
usercache, the convert would abort with a reference to the largefile being
missing (as opposed to the previous patch, where the standin was referenced as
missing).  This is because commitctx() tries to copy all largefiles to the
local store, first from the user cache, and if the file isn't found there, from
the working directory.  No files will exist in the working directory during a
convert, however.  It is not sufficient to force the source repo to be local
before proceeding, because clone and pull do not download largefiles by default.

This is slightly less than ideal because while the conversion will now complete,
it won't be possible to update to revs with missing largefiles unless the user
intervenes manually, because there is no default path pointing back to the
source repo.  Ideally these files would be cached during the conversion.

This check could have been done in reposetup.commitctx() instead, but this
ensures the local store directory is created, which is necessary to enable the
standin matcher.

The rm -> 'rm -f' change in the test is to temporarily suppress an error
clearing the cache- as noted, the cache is is not repopulated during convert.
When that is fixed, this can be changed back and the verification errors will
disappear too.

diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -234,7 +234,7 @@
     util.makedirs(os.path.dirname(storepath(repo, hash)))
     if inusercache(repo.ui, hash):
         link(usercachepath(repo.ui, hash), storepath(repo, hash))
-    else:
+    elif not getattr(repo, "_isconverting", False):
         dst = util.atomictempfile(storepath(repo, hash),
                                   createmode=repo.store.createmode)
         for chunk in util.filechunkiter(open(file, 'rb')):
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -1113,3 +1113,11 @@
         result = orig(ui, repo, file1, *pats, **opts)
         return result
     return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
+
+def mercurialsinkbefore(orig, sink):
+    sink.repo._isconverting = True
+    orig(sink)
+
+def mercurialsinkafter(orig, sink):
+    sink.repo._isconverting = False
+    orig(sink)
diff --git a/hgext/largefiles/uisetup.py b/hgext/largefiles/uisetup.py
--- a/hgext/largefiles/uisetup.py
+++ b/hgext/largefiles/uisetup.py
@@ -168,3 +168,10 @@
         if name == 'transplant':
             extensions.wrapcommand(getattr(module, 'cmdtable'), 'transplant',
                 overrides.overridetransplant)
+        if name == 'convert':
+            convcmd = getattr(module, 'convcmd')
+            hgsink = getattr(convcmd, 'mercurial_sink')
+            extensions.wrapfunction(hgsink, 'before',
+                                    overrides.mercurialsinkbefore)
+            extensions.wrapfunction(hgsink, 'after',
+                                    overrides.mercurialsinkafter)
diff --git a/tests/test-lfconvert.t b/tests/test-lfconvert.t
--- a/tests/test-lfconvert.t
+++ b/tests/test-lfconvert.t
@@ -275,6 +275,9 @@
 
   $ cd ..
 
+Clearing the usercache ensures that commitctx doesn't try to cache largefiles
+from the working dir on a convert.
+  $ rm "${USERCACHE}"/*
   $ hg convert largefiles-repo
   assuming destination largefiles-repo-hg
   initializing destination largefiles-repo-hg repository
@@ -304,6 +307,9 @@
   |
   o  0:d4892ec57ce2  add large, normal1
   
+Verify will fail (for now) if the usercache is purged before converting, since
+largefiles are not cached in the converted repo's local store by the conversion
+process.
   $ hg -R largefiles-repo-hg verify --large --lfa
   checking changesets
   checking manifests
@@ -311,7 +317,20 @@
   checking files
   8 files, 7 changesets, 12 total revisions
   searching 7 changesets for largefiles
+  changeset 0:d4892ec57ce2: large missing
+    (looked for hash 2e000fa7e85759c7f4c254d4d9c33ef481e459a7)
+  changeset 1:334e5237836d: sub/maybelarge.dat missing
+    (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
+  changeset 2:261ad3f3f037: stuff/maybelarge.dat missing
+    (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
+  changeset 3:55759520c76f: sub/maybelarge.dat missing
+    (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
+  changeset 5:9cc5aa7204f0: stuff/maybelarge.dat missing
+    (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
+  changeset 6:17126745edfd: anotherlarge missing
+    (looked for hash 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3)
   verified existence of 6 revisions of 4 largefiles
+  [1]
   $ hg -R largefiles-repo-hg showconfig paths
 
 
@@ -319,7 +338,7 @@
 
 Ensure the largefile can be cached in the source if necessary
   $ hg clone -U largefiles-repo issue3519
-  $ rm "${USERCACHE}"/*
+  $ rm -f "${USERCACHE}"/*
   $ hg lfconvert --to-normal issue3519 normalized3519
   initializing destination normalized3519
 


More information about the Mercurial-devel mailing list