Patchwork [1,of,3] lfs: add a fileset for detecting lfs files

login
register
mail settings
Submitter Matt Harbison
Date Feb. 9, 2018, 5:30 a.m.
Message ID <5b3ca0f7f4b676863d5b.1518154221@Envy>
Download mbox | patch
Permalink /patch/27496/
State Accepted
Headers show

Comments

Matt Harbison - Feb. 9, 2018, 5:30 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1517093899 18000
#      Sat Jan 27 17:58:19 2018 -0500
# Node ID 5b3ca0f7f4b676863d5b3a481ce7ed88bf6acd55
# Parent  c64b9adfb371b6e9dfd2257d3e2f62d5121341df
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.
Yuya Nishihara - Feb. 9, 2018, 12:59 p.m.
On Fri, 09 Feb 2018 00:30:21 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1517093899 18000
> #      Sat Jan 27 17:58:19 2018 -0500
> # Node ID 5b3ca0f7f4b676863d5b3a481ce7ed88bf6acd55
> # Parent  c64b9adfb371b6e9dfd2257d3e2f62d5121341df
> lfs: add a fileset for detecting lfs files

Queued this, thanks.

Patch

diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -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."""
diff --git a/tests/test-lfs.t b/tests/test-lfs.t
--- a/tests/test-lfs.t
+++ b/tests/test-lfs.t
@@ -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.