# HG changeset patch # User Matt Harbison # Date 2012-10-24 01:32:19 # Node ID d1d0140287b81c230b20d675c0009d6394e3dd1d # Parent 92bbb21d4b13787bcb1bbaf95aa2c155ca1d3c00 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 @@ def copytostoreabsolute(repo, file, hash 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 @@ def overridecat(orig, ui, repo, file1, * 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 @@ def uisetup(ui): 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 @@ round-trip: converting back to a normal $ 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 @@ round-trip: converting back to a normal | 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 @@ round-trip: converting back to a normal 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 @@ Avoid a traceback if a largefile isn't a 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