website/docs/cmd/watch-project.md
Since 3.1.
Requests that the project containing the requested dir is watched for changes. Watchman will track all files and dirs rooted at the project path, and respond with the relative path difference between the project path and the requested dir.
With a proliferation of tools that wish to take advantage of filesystem watching at different locations in a filesystem tree, it is possible and likely for those tools to establish multiple overlapping watches.
Most systems have a finite limit on the number of directories that can be watched effectively; when that limit is exceeded the performance and reliability of filesystem watching is degraded, sometimes to the point that it ceases to function.
It is therefore desirable to avoid this situation and consolidate the filesystem
watches. Watchman offers the watch-project command to allow clients to opt-in
to the watch consolidation behavior described below.
A project is the logical root of a set of related files in a filesystem tree and is a good point at which to consolidate watches. Tools such as hgwatchman will most likely have already established a watch at the root of a project, so any other tools that wish to watch a sub-directory can do so for no additional cost if they re-use that existing watch at a higher level in the filesystem tree.
The watch-project command uses a simple procedure to locate the project path
that corresponds to a given path. While simple it is rather verbose to describe
it precisely:
root_files. Any file in this list, if present in a directory, identifies
that directory as being a valid project directory.watch-project. The candidate directory is passed to the realpath(3)
function and the result is set as the new value of the candidate directory.root_files, one by
one, and the resultant path is tested for existence. If the path exists then
the candidate directory is the path that will be used for watch and the
search is halted successfully.root_files can be found in the candidate directory then the
parent of the candidate directory is used as a new candidate and the process
is repeated at step 3 above.Watchman may perform the above search procedure twice. The logic is:
root_files will be set to list only .watchmanconfigroot_files is set to the global
configuration option root_files and the search
procedure is re-run.watch-project commandWhat this means in laymans terms is that the definitive location of the project
root is where the .watchmanconfig file is found. If it is not found then the
set of files defined by the root_files configuration is used to locate a
candidate.
If no viable candidate is found then watchman will watch the requested
directory, unless the enforce_root_files setting is set to true.
The default value for root_files will match most common version control root
directories. The default value for enforce_root_files is false.
Assuming that ~/www/.hg and ~/www/some/child/dir both exist, then the
command:
$ watchman watch-project ~/www/some/child/dir
{
"version": "3.0.1",
"watch": "/Users/wez/www",
"relative_path": "some/child/dir"
}
establishes a watch on the ~/www directory because that is the directory that
contains .hg, which is one of the items listed in the default value for
root_files.
As a client using watch-project it is important to observe the relative_path
and/or watch elements of the response; they identify which directory is
actually being watched. Any triggers, subscriptions or queries that the client
issues must be relative to the watched root to operate as expected. A client
can use relative_path to more easily construct queries or adjust the results
of queries by either concatenating the string when composing paths in a query
expression or removing the string from the prefix when processing the results.
If relative_path is missing from the response it means that the requested dir
is the same as the watched dir and that the watch-project invocation turned
out to be exactly equivalent to a watch invocation for the requested
directory.
Note that, when you're using the CLI, you can specify the root as
~/www/some/child/dir because the shell will resolve ~/www/some/child/dir to
/Users/wez/www/some/child/dir, but when you use the JSON protocol, you are
responsible for supplying an absolute path.
JSON:
["watch", "/Users/wez/www/some/child/dir"]
Once a viable candidate is found, if watchman is not already watching the directory, then watchman will:
Unless the --no-save-state server option was used to start the watchman
service, watches and their associated triggers are saved and re-established
across a process restart.
Since 3.7.
The watchman service may decide to reap watches that have been idle for an extended period of time. A watch is considered to be idle if no watchman queries have been issued against the watch. If a watch is idle, and has no triggers registered or active subscriptions then it is a candidate for reaping.
The idle_reap_age_seconds configuration parameter controls the idle timeout for a watch. The default is 5 days. A reaped watch is cancelled and removed from the state file.