largefiles: always create the cache and standin directories when cloning
The standin matcher only works if the .hglf directory exists (and it won't exist
if 'clone -U' is used, unless --all-largefiles is also specified). Since not
even 'update -r null' will get rid of the standin directory, this ensures that
the standin directory always exists if the repo has the 'largefiles'
requirement. This requirement is only set after a largefile is committed, so
these directories will not be created for repos that have the extension enabled
but have not committed a largefile.
With the standin directory in place, 'lfconvert --to-normal' will now be able to
download the required largefiles when converting a repo that was created with
'clone -U', and whose files are not in the usercache.
The downloadlfiles command could probably be put inside the 'largefiles'
requirement conditional too, but given that the user specified --all-largefiles,
there is likely an expectation to print out the number of largefiles downloaded,
even if it is 0.
--- a/hgext/largefiles/overrides.py Sun Oct 14 14:44:08 2012 -0400
+++ b/hgext/largefiles/overrides.py Sun Oct 14 15:10:13 2012 -0400
@@ -733,24 +733,29 @@
def hgclone(orig, ui, opts, *args, **kwargs):
result = orig(ui, opts, *args, **kwargs)
- if result is not None and opts.get('all_largefiles'):
+ if result is not None:
sourcerepo, destrepo = result
repo = destrepo.local()
# The .hglf directory must exist for the standin matcher to match
# anything (which listlfiles uses for each rev), and .hg/largefiles is
# assumed to exist by the code that caches the downloaded file. These
- # directories exist if clone updated to any rev.
- if opts.get('noupdate'):
- util.makedirs(repo.pathto(lfutil.shortname))
- util.makedirs(repo.join(lfutil.longname))
+ # directories exist if clone updated to any rev. (If the repo does not
+ # have largefiles, download never gets to the point of needing
+ # .hg/largefiles, and the standin matcher won't match anything anyway.)
+ if 'largefiles' in repo.requirements:
+ if opts.get('noupdate'):
+ util.makedirs(repo.pathto(lfutil.shortname))
+ util.makedirs(repo.join(lfutil.longname))
# Caching is implicitly limited to 'rev' option, since the dest repo was
- # truncated at that point.
- success, missing = lfcommands.downloadlfiles(ui, repo, None)
+ # truncated at that point. The user may expect a download count with
+ # this option, so attempt whether or not this is a largefile repo.
+ if opts.get('all_largefiles'):
+ success, missing = lfcommands.downloadlfiles(ui, repo, None)
- if missing != 0:
- return None
+ if missing != 0:
+ return None
return result
--- a/tests/test-lfconvert.t Sun Oct 14 14:44:08 2012 -0400
+++ b/tests/test-lfconvert.t Sun Oct 14 15:10:13 2012 -0400
@@ -276,10 +276,21 @@
Avoid a traceback if a largefile isn't available (issue3519)
+Ensure the largefile can be cached in the source if necessary
$ hg clone -U largefiles-repo issue3519
$ rm "${USERCACHE}"/*
$ hg lfconvert --to-normal issue3519 normalized3519
initializing destination normalized3519
+
+Ensure the abort message is useful if a largefile is entirely unavailable
+ $ rm -rf normalized3519
+ $ rm "${USERCACHE}"/*
+ $ rm issue3519/.hg/largefiles/*
+ $ rm largefiles-repo/.hg/largefiles/*
+ $ hg lfconvert --to-normal issue3519 normalized3519
+ initializing destination normalized3519
+ large: can't get file locally
+ (no default or default-push path set in hgrc)
abort: missing largefile 'large' from revision d4892ec57ce212905215fad1d9018f56b99202ad
[255]