[PATCH] locate: add support for filtering by file type
Bryan O'Sullivan
bos at serpentine.com
Tue Apr 2 15:33:40 CDT 2013
# HG changeset patch
# User Bryan O'Sullivan <bryano at fb.com>
# Date 1364934784 25200
# Tue Apr 02 13:33:04 2013 -0700
# Node ID d13118dd5f087467e5edf4e6752ac3110ee21475
# Parent 65a67c7aefed9d86aa24758aaa7529445856db9f
locate: add support for filtering by file type
This makes it possible to say "show me matches that are not symlinks"
via "-t x -t f", and so on.
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3814,6 +3814,7 @@ def init(ui, dest=".", **opts):
@command('locate',
[('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
+ ('t', 'type', [], _('only print files of the given type'), _('TYPE')),
('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
('f', 'fullpath', None, _('print complete paths from the filesystem root')),
] + walkopts,
@@ -3831,6 +3832,15 @@ def locate(ui, repo, *pats, **opts):
If no patterns are given to match, this command prints the names
of all files under Mercurial control in the working directory.
+ To look for particular types of file, specify one or more "--type"
+ arguments:
+
+ - "symlink" or "l": symbolic links
+
+ - "executable", "exe", or "x": executable files
+
+ - "plain" or "f": plain files (not executable, not symlinks)
+
If you want to feed the output of this command into the "xargs"
command, use the -0 option to both this command and "xargs". This
will avoid the problem of "xargs" treating single filenames that
@@ -3841,12 +3851,26 @@ def locate(ui, repo, *pats, **opts):
end = opts.get('print0') and '\0' or '\n'
rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
+ typenames = dict(symlink='l', l='l',
+ plain='', f='',
+ executable='x', exe='x', x='x')
+ try:
+ types = set(typenames[t] for t in opts.get('type'))
+ except KeyError, err:
+ raise util.Abort(_('unknown file type: %s') % err)
+ if not types or types == set(typenames.itervalues()):
+ # match all file types
+ types = None
+
ret = 1
- m = scmutil.match(repo[rev], pats, opts, default='relglob')
+ ctx = repo[rev]
+ m = scmutil.match(ctx, pats, opts, default='relglob')
m.bad = lambda x, y: False
for abs in repo[rev].walk(m):
if not rev and abs not in repo.dirstate:
continue
+ if types and ctx[abs].flags() not in types:
+ continue
if opts.get('fullpath'):
ui.write(repo.wjoin(abs), end)
else:
diff --git a/tests/test-locate.t b/tests/test-locate.t
--- a/tests/test-locate.t
+++ b/tests/test-locate.t
@@ -1,10 +1,12 @@
$ hg init repo
$ cd repo
$ echo 0 > a
+ $ chmod +x a
$ echo 0 > b
$ echo 0 > t.h
$ mkdir t
$ echo 0 > t/x
+ $ chmod +x t/x a
$ echo 0 > t/b
$ echo 0 > t/e.h
$ mkdir dir.h
@@ -23,6 +25,20 @@
$ hg locate a
a
+ $ hg locate -t x -t l a
+ a
+
+ $ hg locate -t x
+ a
+ t/x
+
+ $ ln -s wibble symlink
+ $ hg add symlink
+ $ hg locate -t l
+ symlink
+ $ hg locate -t f symlink
+ [1]
+ $ hg forget symlink
$ hg locate NONEXISTENT
[1]
More information about the Mercurial-devel
mailing list