跳到主要内容

watch-project

自 3.1 起。

请求监视包含请求目录的 *project* 中的更改。 Watchman 将跟踪以 *project* 路径为根的所有文件和目录,并返回 *project* 路径和请求目录之间的相对路径差异。

原理

随着希望利用文件系统监视的工具在文件系统树中不同位置的激增,这些工具可能会建立多个重叠的监视。

大多数系统对可以有效监视的目录数量都有一个有限的限制;当超过该限制时,文件系统监视的性能和可靠性会降低,有时甚至会停止工作。

因此,期望避免这种情况并整合文件系统监视。 Watchman 提供了 watch-project 命令,允许客户端选择加入下面描述的监视整合行为。

什么是项目路径?

项目是一组相关文件在文件系统树中的逻辑根,是整合监视的好位置。诸如 hgwatchman 之类的工具很可能已经在项目根目录上建立了监视,因此任何其他希望监视子目录的工具都可以这样做,而无需额外成本,如果它们在文件系统树中更高级别的位置重复使用现有监视。

watch-project 命令使用一个简单的过程来定位与给定路径对应的 *project* 路径。 虽然简单,但精确描述它却相当冗长

  1. 搜索从文件名的列表开始; 我们将其称为 root_files。 此列表中的任何文件(如果存在于目录中)都将该目录标识为有效的项目目录。
  2. 搜索从候选目录设置为传递给 watch-project 的参数开始。 候选目录传递给 realpath(3) 函数,结果设置为候选目录的新值。
  3. 候选目录与每个 root_files 逐个连接,并测试结果路径是否存在。 如果路径存在,则候选目录是用于监视的路径,并且搜索成功停止。
  4. 如果在候选目录中找不到任何 root_files,则候选目录的父目录用作新候选目录,并且该过程在上面的步骤 3 中重复。
  5. 如果找不到可行的候选目录并且到达文件系统的根目录,则搜索失败终止。

Watchman 可能会执行上述搜索过程两次。 逻辑是

  1. root_files 将设置为仅列出 .watchmanconfig
  2. 执行上述搜索过程
  3. 如果搜索成功终止,则为候选目录的当前值建立监视。
  4. 如果搜索失败终止,则 root_files 设置为全局配置选项 root_files 并重新运行搜索过程。
  5. 如果搜索成功终止,则为候选目录的当前值建立监视。
  6. 如果全局配置选项 enforce_root_files 设置为 true,则监视尝试失败。
  7. 否则,为 watch-project 命令的原始参数建立监视

用外行的话来说,这意味着项目根目录的明确位置是找到 .watchmanconfig 文件的位置。 如果未找到,则使用由 root_files 配置定义的文件集来定位候选文件。

如果找不到可行的候选文件,那么 watchman 将监视请求的目录,除非 enforce_root_files 设置设置为 true。

root_files 的默认值将匹配最常见的版本控制根目录。 enforce_root_files 的默认值为 false

使用 watch-project

假设 ~/www/.hg~/www/some/child/dir 都存在,那么该命令

$ watchman watch-project ~/www/some/child/dir
{
"version": "3.0.1",
"watch": "/Users/wez/www",
"relative_path": "some/child/dir"
}

~/www 目录上建立监视,因为该目录包含 .hg,它是 root_files 的默认值中列出的项目之一。

作为使用 watch-project 的客户端,重要的是观察响应的 relative_path 和/或 watch 元素; 它们标识实际正在监视的目录。 客户端发出的任何触发器、订阅或查询都必须相对于被监视的根目录才能按预期运行。 客户端可以使用 relative_path 通过在查询表达式中组合路径时连接字符串或从结果中删除前缀来更轻松地构建查询或调整查询结果。

如果响应中缺少 relative_path,则表示请求的目录与被监视的目录相同,并且 watch-project 调用结果与针对请求目录的 watch 调用完全相同。

请注意,当您使用 CLI 时,您可以将根目录指定为 ~/www/some/child/dir,因为 shell 会将 ~/www/some/child/dir 解析为 /Users/wez/www/some/child/dir,但是当您使用 JSON 协议时,您有责任提供绝对路径。

JSON

["watch", "/Users/wez/www/some/child/dir"]

启动监视

一旦找到可行的候选目录,如果 watchman 尚未监视该目录,那么 watchman 将会

  • 使用内核为目录建立更改通知
  • 将请求排队以爬取目录
  • 当目录内容被解析时,以类似的方式监视这些内容
  • 所有新观察到的文件都被视为已更改

持久性

除非使用 --no-save-state 服务器选项启动 watchman 服务,否则监视及其关联的触发器将被保存并在进程重新启动后重新建立。

自 3.7 起。

watchman 服务可能会决定收割长时间处于空闲状态的监视。 如果没有针对监视发出任何 watchman 查询,则认为监视处于空闲状态。 如果监视处于空闲状态,并且没有注册或活动订阅的触发器,则它可以进行收割。

idle_reap_age_seconds 配置参数控制监视的空闲超时。 默认值为 5 天。 收割的监视将被取消并从状态文件中删除。