[PATCH 4 of 4 STABLE] largefiles: delegate to the wrapped clone command

Matt Harbison matt_harbison at yahoo.com
Sun Sep 9 18:41:38 CDT 2012

# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1347209004 14400
# Branch stable
# Node ID e9c8f5e43d1e0064c093923b8cfe454765de2ad2
# Parent  3c40365f112d4c9621c8031de0aac39e0a98baff
largefiles: delegate to the wrapped clone command

This allows the wrapped command's validation code to run (which is currently
only to ensure 'noupdate' and 'updaterev' aren't both specified), the
copy/pasted unpacking of hg.clone() args to be removed, and any future changes
to the base command (however unlikely) to be inherited by largefiles.

Unfortunately, the command override can't be swapped entirely for an hg.clone()
override because the extra --all-largefiles arg needs to be injected.  It also
isn't enough to call the wrapped clone command and leave the caching code after
it, because the file caching code needs access to the destination repo, which is
only available from hg.clone().  An alternative would be to use the dest path in
the clone command override to re-obtain a reference to the repo.

A slight deviation from the regular hg.clone() function is that the repo is NOT
deleted if the caching fails, but that was also the previous behavior.  Maybe it
should for consistency?

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -722,15 +722,13 @@
             raise util.Abort(_(
             '--all-largefiles is incompatible with non-local destination %s' %
-    result = hg.clone(ui, opts, source, dest,
-                      pull=opts.get('pull'),
-                      stream=opts.get('uncompressed'),
-                      rev=opts.get('rev'),
-                      update=opts.get('updaterev') or not opts.get('noupdate'),
-                      branch=opts.get('branch'))
-    if result is None:
-        return True
-    if opts.get('all_largefiles'):
+    return orig(ui, source, dest, **opts)
+def hgclone(orig, ui, opts, *args, **kwargs):
+    result = orig(ui, opts, *args, **kwargs)
+    if result is not None and opts.get('all_largefiles'):
         sourcerepo, destrepo = result
         repo = destrepo.local()
@@ -745,8 +743,11 @@
         # Caching is implicitly limited to 'rev' option, since the dest repo was
         # truncated at that point.
         success, missing = lfcommands.downloadlfiles(ui, repo, None)
-        return missing != 0
-    return result is None
+        if missing != 0:
+            return None
+    return result
 def overriderebase(orig, ui, repo, **opts):
     repo._isrebasing = True
diff --git a/hgext/largefiles/uisetup.py b/hgext/largefiles/uisetup.py
--- a/hgext/largefiles/uisetup.py
+++ b/hgext/largefiles/uisetup.py
@@ -77,8 +77,9 @@
     cloneopt = [('', 'all-largefiles', None,
                  _('download all versions of all largefiles'))]
+    entry[1].extend(cloneopt)
+    entry = extensions.wrapfunction(hg, 'clone', overrides.hgclone)
-    entry[1].extend(cloneopt)
     entry = extensions.wrapcommand(commands.table, 'cat',
     entry = extensions.wrapfunction(merge, '_checkunknownfile',
diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t
--- a/tests/test-largefiles.t
+++ b/tests/test-largefiles.t
@@ -699,6 +699,12 @@
   3 largefiles updated, 0 removed
   $ cd ..
+Ensure base clone command argument validation
+  $ hg clone -U -u 0 a a-clone-failure
+  abort: cannot specify both --noupdate and --updaterev
+  [255]
   $ hg clone --all-largefiles a ssh://localhost/a
   abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a

More information about the Mercurial-devel mailing list