lfs: add a fileset for detecting lfs files
authorMatt Harbison <matt_harbison@yahoo.com>
Sat, 27 Jan 2018 17:58:19 -0500
changeset 36029 eefb5d603482
parent 36028 c64b9adfb371
child 36030 04304b779df1
lfs: add a fileset for detecting lfs files This currently has the same limitation as {lfs_files}, namely it doesn't report removed files. We may want a dedicated 'lfs()' revset for efficiency, but combining this with the 'contains()' revset should be equivalent for now. Combining with 'set:added()' or 'set:modified()' inside 'files()' should be equivalent to a hypothetical lfs_adds() and lfs_modifies(). I wonder if there's a way to tweak the filesets to evaluate lazily, to close the efficiency gap. It would also be interesting to come up with a template filter for '{files}' that looked at the pattern to 'files()', and filtered appropriately. While passing a fileset as the pattern to `hg log` does filter '{files}', the set is evaluated against the working directory, so there's no way to list all non-lfs files above a certain size in all revisions, for example.
hgext/lfs/__init__.py
tests/test-lfs.t
--- a/hgext/lfs/__init__.py	Wed Feb 07 23:42:48 2018 -0500
+++ b/hgext/lfs/__init__.py	Sat Jan 27 17:58:19 2018 -0500
@@ -193,6 +193,7 @@
 command = registrar.command(cmdtable)
 
 templatekeyword = registrar.templatekeyword()
+filesetpredicate = registrar.filesetpredicate()
 
 def featuresetup(ui, supported):
     # don't die on seeing a repo with the lfs requirement
@@ -349,6 +350,14 @@
     # when writing a bundle via "hg bundle" command, upload related LFS blobs
     wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle)
 
+@filesetpredicate('lfs()')
+def lfsfileset(mctx, x):
+    """File that uses LFS storage."""
+    # i18n: "lfs" is a keyword
+    fileset.getargs(x, 0, 0, _("lfs takes no arguments"))
+    return [f for f in mctx.subset
+            if wrapper.pointerfromctx(mctx.ctx, f) is not None]
+
 @templatekeyword('lfs_files')
 def lfsfiles(repo, ctx, **args):
     """List of strings. LFS files added or modified by the changeset."""
--- a/tests/test-lfs.t	Wed Feb 07 23:42:48 2018 -0500
+++ b/tests/test-lfs.t	Sat Jan 27 17:58:19 2018 -0500
@@ -154,10 +154,22 @@
   $ hg add . -q
   $ hg commit -m 'commit with lfs content'
 
+  $ hg files -r . 'set:added()'
+  large
+  small
+  $ hg files -r . 'set:added() & lfs()'
+  large
+
   $ hg mv large l
   $ hg mv small s
   $ hg commit -m 'renames'
 
+  $ hg files -r . 'set:copied()'
+  l
+  s
+  $ hg files -r . 'set:copied() & lfs()'
+  l
+
   $ echo SHORT > l
   $ echo BECOME-LARGER-FROM-SHORTER > s
   $ hg commit -m 'large to small, small to large'
@@ -1006,7 +1018,7 @@
   
 The LFS policy stops when the .hglfs is gone
 
-  $ hg rm .hglfs
+  $ mv .hglfs .hglfs_
   $ echo 'largefile3' > lfs.test
   $ echo '012345678901234567890abc' > nolfs.exclude
   $ echo '01234567890123456abc' > lfs.catchall
@@ -1014,6 +1026,18 @@
   $ hg log -r . -T '{rev}: {lfs_files % "{file}: {lfsoid}\n"}\n'
   4: 
 
+  $ mv .hglfs_ .hglfs
+  $ echo '012345678901234567890abc' > lfs.test
+  $ hg ci -m 'back to lfs'
+  $ hg rm lfs.test
+  $ hg ci -qm 'remove lfs'
+
+TODO: This should notice the deleted lfs files in rev 6
+  $ hg log -r 'file("set:lfs()")' -T '{rev} {join(lfs_files, ", ")}\n'
+  2 lfs.catchall, lfs.test
+  3 lfs.catchall, lfs.test
+  5 lfs.test
+
   $ cd ..
 
 Unbundling adds a requirement to a non-lfs repo, if necessary.