[PATCH 3 of 4 RFC] largefiles: add lfcache command to ensure caching for specified revisions

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sun Nov 13 09:47:02 CST 2011


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1321197991 -32400
# Branch stable
# Node ID 15127ffc0db4682da9f7dd222bf3acebbc787cc7
# Parent  0044c64b84315ba79eea458c8f198309b13438b5
largefiles: add lfcache command to ensure caching for specified revisions

accessing to the revisions which are related to largefiles causes
on-demand downloading of them from source repository, and it is not
good in offline environment.

but there is no way for caching such largefiles to prepare for being
offlined.

lfcache command ensures caching for specified revisions.

diff -r 0044c64b8431 -r 15127ffc0db4 hgext/largefiles/lfcommands.py
--- a/hgext/largefiles/lfcommands.py	Mon Nov 14 00:26:08 2011 +0900
+++ b/hgext/largefiles/lfcommands.py	Mon Nov 14 00:26:31 2011 +0900
@@ -12,6 +12,7 @@
 import shutil
 
 from mercurial import util, match as match_, hg, node, context, error
+from mercurial import scmutil, cmdutil
 from mercurial.i18n import _
 
 import lfutil
@@ -116,6 +117,79 @@
             shutil.rmtree(rdst.root)
         dst_lock.release()
 
+def lfcache(ui, repo, *patterns, **opts):
+    '''cache all largefiles locally needed by the specified revisions
+
+    This command ensures that you can get contents of largefiles related
+    to specified revision safely even in offline environment.
+
+    Largefiles not matched with specified file patterns may be cached,
+    because file patterns are used not to limit cache target files,
+    but to specify revisions to be cached.
+
+    This command will abort, if none of file pattern or revision
+    limitation options is specified: -d, -k, -r, -m, -u, -b, -p,
+    -l or -M. use -a/--all, if you want cache all largefiles required for
+    all revisions in local repository.
+
+    Returns 0 if all largefiles are successfully cached.
+    '''
+
+    if not (patterns or
+            opts['date'] or opts['keyword'] or opts['rev'] or
+            opts['only_merges'] or opts['user'] or opts['branch'] or
+            opts['prune'] or opts['no_merges'] or opts['limit'] or
+            opts['all']):
+        raise util.Abort(_("specify --all to allow caching all largefiles"))
+
+    matchfn = scmutil.match(repo[None], patterns, opts)
+    limit = cmdutil.loglimit(opts)
+
+    df = False
+    if opts["date"]:
+        df = util.matchdate(opts["date"])
+
+    opts['branch'] = [repo.lookupbranch(b) for b in opts.get('branch', [])]
+
+    def interests(ctx):
+        parents = [p for p in repo.changelog.parentrevs(ctx.rev())
+                   if p != node.nullrev]
+        if opts.get('no_merges') and len(parents) == 2:
+            return False
+        if opts.get('only_merges') and len(parents) != 2:
+            return False
+        if opts.get('branch') and ctx.branch() not in opts['branch']:
+            return False
+        if df and not df(ctx.date()[0]):
+            return False
+        if opts['user'] and not [k for k in opts['user']
+                                 if k.lower() in ctx.user().lower()]:
+            return False
+        if opts.get('keyword'):
+            for k in [kw.lower() for kw in opts['keyword']]:
+                if (k in ctx.user().lower() or
+                    k in ctx.description().lower() or
+                    k in " ".join(ctx.files()).lower()):
+                    break
+            else:
+                return False
+        return True
+
+    count = 0
+    failed = 0
+    prepare = lambda x, y: None # dummy
+    for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prepare):
+        if count == limit:
+            break
+        if not interests(ctx):
+            continue
+        count += 1
+        ui.status(_('caching for rev %d\n') % ctx.rev())
+        cached, missing = cachelfiles(ui, repo, ctx.node())
+        if missing: failed += 1
+
+    return failed and 1 or 0
+
 def _addchangeset(ui, rsrc, rdst, ctx, revmap):
  # Convert src parents to dst parents
     parents = []
@@ -476,4 +550,29 @@
                    _('convert from a largefiles repo to a normal repo')),
                   ],
                   _('hg lfconvert SOURCE DEST [FILE ...]')),
+    'lfcache': (lfcache,
+                [('d', 'date', '',
+                  _('cache for revisions matching date spec'), _('DATE')),
+                 ('k', 'keyword', [],
+                  _('do case-insensitive search for a given text'), _('TEXT')),
+                 ('r', 'rev', [],
+                  _('cache for the specified revision or range'), _('REV')),
+                 ('m', 'only-merges', None,
+                  _('cache only for merging revisions')),
+                 ('u', 'user', [],
+                  _('cache for revisions committed by user'), _('USER')),
+                 ('b', 'branch', [],
+                  _('cache for revisions within the given named branch'),
+                  _('BRANCH')),
+                 ('P', 'prune', [],
+                  _('do not cache for revision or any of its ancestors'),
+                  _('REV')),
+                 ('l', 'limit', '',
+                  _('limit number of revisions cached'), _('NUM')),
+                 ('M', 'no-merges', None,
+                  _('do not cache for merging revisions')),
+                 ('a', 'all', False,
+                  _('allow caching for all revisions'))
+                 ],
+                _('hg lfcache [FILE ...]')),
     }
diff -r 0044c64b8431 -r 15127ffc0db4 hgext/largefiles/uisetup.py
--- a/hgext/largefiles/uisetup.py	Mon Nov 14 00:26:08 2011 +0900
+++ b/hgext/largefiles/uisetup.py	Mon Nov 14 00:26:31 2011 +0900
@@ -15,6 +15,7 @@
 
 import overrides
 import proto
+import lfcommands
 
 def uisetup(ui):
     # Disable auto-status for some commands which assume that all
@@ -135,6 +136,7 @@
         ('unbundle', commands.table),
         ('update', commands.table),
         ('verify', commands.table),
+        ('lfcache', lfcommands.cmdtable),
         ]
 
     # override some extensions' stuff as well


More information about the Mercurial-devel mailing list