lfs: add a repo requirement for this extension once an lfs file is committed
authorMatt Harbison <matt_harbison@yahoo.com>
Wed, 15 Nov 2017 23:43:15 -0500
changeset 35175 e0a1b9ee93cd
parent 35164 6864c405f023
child 35176 671aba341d90
lfs: add a repo requirement for this extension once an lfs file is committed Largefiles does the same thing (also delayed until the first largefile commit), to prevent access to the repo without the extension. In the case of this extension, not having the extension loaded while accessing an lfs file results in cryptic errors about "missing processor for flag '0x2000'". If enabled locally but not remotely, the cryptic error message is about no common changegroup version. (It wants '03', which is currently experimental.) The largefiles extension looks for any tracked file that starts with '.hglf/'. Unfortunately, that doesn't work here. I didn't see any way to get the files that were just committed, without doing a full status. But since there's no secondary check on adding an lfs file once the extension is loaded and a threshold set, the best practice is to only enable this locally on a repo that needs it. That should minimize the unnecessary overhead for repos without an lfs file.
hgext/lfs/__init__.py
tests/test-lfs.t
--- a/hgext/lfs/__init__.py	Thu Nov 30 22:32:13 2017 +0900
+++ b/hgext/lfs/__init__.py	Wed Nov 15 23:43:15 2017 -0500
@@ -37,6 +37,7 @@
     exchange,
     extensions,
     filelog,
+    localrepo,
     registrar,
     revlog,
     scmutil,
@@ -84,6 +85,13 @@
 
 templatekeyword = registrar.templatekeyword()
 
+def featuresetup(ui, supported):
+    # don't die on seeing a repo with the lfs requirement
+    supported |= {'lfs'}
+
+def uisetup(ui):
+    localrepo.localrepository.featuresetupfuncs.add(featuresetup)
+
 def reposetup(ui, repo):
     # Nothing to do with a remote repo
     if not repo.local():
@@ -98,6 +106,17 @@
     # Push hook
     repo.prepushoutgoinghooks.add('lfs', wrapper.prepush)
 
+    if 'lfs' not in repo.requirements:
+        def checkrequireslfs(ui, repo, **kwargs):
+            if 'lfs' not in repo.requirements:
+                ctx = repo[kwargs['node']]
+                # TODO: is there a way to just walk the files in the commit?
+                if any(ctx[f].islfs() for f in ctx.files()):
+                    repo.requirements.add('lfs')
+                    repo._writerequirements()
+
+        ui.setconfig('hooks', 'commit.lfs', checkrequireslfs, 'lfs')
+
 def wrapfilelog(filelog):
     wrapfunction = extensions.wrapfunction
 
--- a/tests/test-lfs.t	Thu Nov 30 22:32:13 2017 +0900
+++ b/tests/test-lfs.t	Wed Nov 15 23:43:15 2017 -0500
@@ -20,7 +20,11 @@
 
 # Commit large file
   $ echo $LONG > largefile
+  $ grep lfs .hg/requires
+  [1]
   $ hg commit --traceback -Aqm "add large file"
+  $ grep lfs .hg/requires
+  lfs
 
 # Ensure metadata is stored
   $ hg debugdata largefile 0