跳到主要内容

query

从 1.6 版本开始。

$ watchman -j <<-EOT
["query", "/path/to/root", {
"suffix": "php",
"expression": ["allof",
["type", "f"],
["not", "empty"],
["ipcre", "test", "basename"]
],
"fields": ["name"]
}]
EOT

针对指定的根目录执行查询。 此示例使用 watchman 二进制文件的 -j 标志,该标志告诉它读取 stdin 并将其解释为要发送到 watchman 服务的 JSON 请求对象。 此标志允许您传入一个漂亮的 JSON 对象(如上所示),但如果您使用的是套接字接口,您仍然必须将对象格式化为单行 JSON 请求,如协议规范中所述。

query 的第一个参数是受监视根目录的路径。 第二个参数包含一个 JSON 对象,描述要运行的查询。 查询对象通过将其传递给查询引擎(请参阅文件查询)进行处理,该引擎将生成一组匹配的文件。

然后,query 命令将查阅查询对象的 fields 成员; 如果它不存在,它将默认为

"fields": ["name", "exists", "new", "size", "mode"]

对于结果集中的每个文件,query 命令将生成一个 JSON 对象值,其中填充了请求的字段。 例如,默认字段集将返回类似于这样的响应

{
"version": "2.9",
"clock": "c:80616:59",
"is_fresh_instance": false,
"files": [
{
"exists": true,
"mode": 33188,
"new": false,
"name": "argv.c",
"size": 1340,
}
]
}

如果无法计算字段的值,则字段的值可能为 null,或者可能是一个包含带有描述性消息字符串的 error 键的对象

{
"version": "2019-07-22T13:50:36Z",
"is_fresh_instance": false,
"clock": "c:1563834049:1830370:791543813:2257494",
"files": [
{
"content.sha1hex": null,
"name": "docs"
"symlink_target": null,
"type": "d",
},
{
"content.sha1hex": {
"error": "eloop: file is a symlink: Invalid argument: Invalid argument"
},
"type": "l",
"symlink_target": "eloop",
"name": "eloop"
}
]
}

对于使用 since 生成器的查询,如果特定的时钟值表明它是由 watchman 的不同实例返回的,或者之前没有见过命名的游标,则 is_fresh_instance 成员为 true。 在这种情况下,只会返回当前存在的文件,并且所有文件都将 new 设置为 true。 对于所有其他查询,is_fresh_instance 将始终为 true。 高级用户可以将输入参数 empty_on_fresh_instance 设置为 true,在这种情况下,不会为新实例返回任何文件。

如果 fields 成员仅包含一个条目,则文件结果将是一个简单的值数组; ~"fields": ["name"]~ 生成

{
"version": "1.5",
"clock": "c:80616:59",
"files": ["argv.c", "foo.c"]
}

可用字段

  • name - 字符串:文件名,相对于受监视的根目录
  • exists - 布尔值:如果文件存在,则为 true;如果文件已被删除,则为 false
  • cclock - 字符串:"创建时钟";我们首次观察到文件时的时钟值,或最后一次从 !exists 切换到 exists 时的时钟值。
  • oclock - 字符串:"观察时钟";我们上次观察到此文件或其元数据发生某些更改时的时钟值。
  • ctimectime_msctime_usctime_nsctime_f - 上次 inode 更改时间,分别以整数秒、毫秒、微秒、纳秒或浮点秒为单位测量。
  • mtimemtime_msmtime_usmtime_nsmtime_f - 修改时间,分别以整数秒、毫秒、微秒、纳秒或浮点秒为单位测量。
  • size - 整数:文件大小(以字节为单位)
  • mode - 整数:文件(或目录)模式,表示为十进制整数
  • uid - 整数:所有者 uid
  • gid - 整数:所有者 gid
  • ino - 整数:inode 编号
  • dev - 整数:设备编号
  • nlink - 整数:硬链接数
  • new - 布尔值:此条目是否比 since 生成器条件更新

从 3.1 版本开始。

从 4.6 版本开始。

  • symlink_target - 字符串:如果文件是符号链接,则为符号链接的目标

从 4.9 版本开始。

  • content.sha1hex - 字符串:文件字节内容的 SHA-1 摘要,编码为 40 个十六进制数字(例如,空文件的 "da39a3ee5e6b4b0d3255bfef95601890afd80709"

同步超时(从 2.1 版本开始)

默认情况下,query 将等待长达 60 秒,以使文件系统的视图变为当前视图。 Watchman 通过创建一个 cookie 文件并等待观察其存在的通知来确定视图是当前的。 如果在 sync_timeout 期间未观察到 cookie,则查询调用将出错并显示同步错误消息。

如果您的同步要求与默认值不同,您可以在构造查询时传入所需的超时; 它必须是以毫秒表示的整数值

["query", "/path/to/root", {
"expression": ["exists"],
"fields": ["name"],
"sync_timeout": 60000
}]

如果您不希望查询创建 cookie 并进行同步,则可以指定 0 作为值; 将在树的当前视图上评估查询,这可能会滞后于文件系统的当前状态。

锁定超时

从 4.6 版本开始。

默认情况下,查询将等待长达 60 秒,以获取锁定来检查文件系统树的视图。 实际上,不应达到此超时(表示环境或负载相关问题)。 但是,在某些情况下,重要的是确保查询尝试早于此超时。 您可以使用 lock_timeout 字段来控制此行为。 lock_timeout 必须是以毫秒表示的整数值

["query", "/path/to/root", {
"expression": ["exists"],
"fields": ["name"],
"lock_timeout": 60000,
"sync_timeout": 60000
}]

在 4.6 之前的版本中,lock_timeout 无法配置,并且具有无限大的有效值。

区分大小写

从 2.9.9 版本开始。

在受监视根目录是不区分大小写的文件系统的系统上(这是 macOS 和 Windows 的常见情况),各种名称匹配操作默认为不区分大小写。

从 4.7 版本开始。

您可以通过在查询规范中设置 case_sensitive 字段来覆盖各种名称匹配操作的区分大小写。 它默认为受监视根目录的区分大小写。 这在您知道树的内容由您的各种工具以区分大小写的方式处理,但运行在不区分大小写的文件系统上的情况下很有用。 通过强制名称匹配进入区分大小写模式,匹配速度更快,并且在某些情况下可以使用替代算法来加速。

$ watchman -j <<-EOT
["query", "/path/to/root", {
"suffix": "php",
"expression": ["match", "foo*.c", "basename"],
"case_sensitive": true,
"fields": ["name"]
}]
EOT

目录事件

通常,Watchman 应报告所有查询的目录更改。

在 EdenFS 存储库上,有一个例外。 当用户在时间查询期间更改提交时,可能不会报告跨这些提交更改的目录更改。

选项 always_include_directories 存在,用于包含跨提交转换的目录事件。 这仅支持 mercurial。 这可能很昂贵,因此建议不需要此功能的客户端不要使用此功能。 此值默认为 false。