largefiles: don't copy largefiles from working dir to the store while converting stable
authorMatt Harbison <matt_harbison@yahoo.com>
Tue, 23 Oct 2012 21:32:19 -0400
branchstable
changeset 17878 d1d0140287b8
parent 17877 92bbb21d4b13
child 17879 7b0b1da49f15
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.
hgext/largefiles/lfutil.py
hgext/largefiles/overrides.py
hgext/largefiles/uisetup.py
tests/test-lfconvert.t
--- a/hgext/largefiles/lfutil.py	Tue Oct 23 21:07:14 2012 -0400
+++ b/hgext/largefiles/lfutil.py	Tue Oct 23 21:32:19 2012 -0400
@@ -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')):
--- a/hgext/largefiles/overrides.py	Tue Oct 23 21:07:14 2012 -0400
+++ b/hgext/largefiles/overrides.py	Tue Oct 23 21:32:19 2012 -0400
@@ -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)
--- a/hgext/largefiles/uisetup.py	Tue Oct 23 21:07:14 2012 -0400
+++ b/hgext/largefiles/uisetup.py	Tue Oct 23 21:32:19 2012 -0400
@@ -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)
--- a/tests/test-lfconvert.t	Tue Oct 23 21:07:14 2012 -0400
+++ b/tests/test-lfconvert.t	Tue Oct 23 21:32:19 2012 -0400
@@ -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