Skip to content

Commit 42dc9a2

Browse files
jeffhostetlerGit for Windows Build Agent
authored andcommitted
Merge pull request #3082 from dscho/fsmonitor-gfw
Add an experimental built-in FSMonitor
2 parents 608f63f + afcc1f1 commit 42dc9a2

File tree

5 files changed

+157
-14
lines changed

5 files changed

+157
-14
lines changed

Documentation/config/core.txt

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,45 @@ core.fsmonitor::
6666
will identify all files that may have changed since the
6767
requested date/time. This information is used to speed up git by
6868
avoiding unnecessary processing of files that have not changed.
69-
See the "fsmonitor-watchman" section of linkgit:githooks[5].
69+
+
70+
See the "fsmonitor-watchman" section of linkgit:githooks[5].
71+
+
72+
Note: FSMonitor hooks (and this config setting) are ignored if the
73+
(experimental) built-in FSMonitor is enabled (see
74+
`core.useBuiltinFSMonitor`).
7075

7176
core.fsmonitorHookVersion::
72-
Sets the version of hook that is to be used when calling fsmonitor.
73-
There are currently versions 1 and 2. When this is not set,
74-
version 2 will be tried first and if it fails then version 1
75-
will be tried. Version 1 uses a timestamp as input to determine
76-
which files have changes since that time but some monitors
77-
like watchman have race conditions when used with a timestamp.
78-
Version 2 uses an opaque string so that the monitor can return
79-
something that can be used to determine what files have changed
80-
without race conditions.
77+
Sets the version of hook that is to be used when calling the
78+
FSMonitor hook (as configured via `core.fsmonitor`).
79+
+
80+
There are currently versions 1 and 2. When this is not set,
81+
version 2 will be tried first and if it fails then version 1
82+
will be tried. Version 1 uses a timestamp as input to determine
83+
which files have changes since that time but some monitors
84+
like watchman have race conditions when used with a timestamp.
85+
Version 2 uses an opaque string so that the monitor can return
86+
something that can be used to determine what files have changed
87+
without race conditions.
88+
+
89+
Note: FSMonitor hooks (and this config setting) are ignored if the
90+
built-in FSMonitor is enabled (see `core.useBuiltinFSMonitor`).
91+
92+
core.useBuiltinFSMonitor::
93+
(EXPERIMENTAL) If set to true, enable the built-in filesystem
94+
event watcher (for technical details, see
95+
linkgit:git-fsmonitor--daemon[1]).
96+
+
97+
Like external (hook-based) FSMonitors, the built-in FSMonitor can speed up
98+
Git commands that need to refresh the Git index (e.g. `git status`) in a
99+
worktree with many files. The built-in FSMonitor facility eliminates the
100+
need to install and maintain an external third-party monitoring tool.
101+
+
102+
The built-in FSMonitor is currently available only on a limited set of
103+
supported platforms.
104+
+
105+
Note: if this config setting is set to `true`, any FSMonitor hook
106+
configured via `core.fsmonitor` (and possibly `core.fsmonitorHookVersion`)
107+
is ignored.
81108

82109
core.trustctime::
83110
If false, the ctime differences between the index and the
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
git-fsmonitor--daemon(1)
2+
========================
3+
4+
NAME
5+
----
6+
git-fsmonitor--daemon - (EXPERIMENTAL) Builtin file system monitor daemon
7+
8+
SYNOPSIS
9+
--------
10+
[verse]
11+
'git fsmonitor--daemon' --start
12+
'git fsmonitor--daemon' --run
13+
'git fsmonitor--daemon' --stop
14+
'git fsmonitor--daemon' --is-running
15+
'git fsmonitor--daemon' --is-supported
16+
'git fsmonitor--daemon' --query <token>
17+
'git fsmonitor--daemon' --query-index
18+
'git fsmonitor--daemon' --flush
19+
20+
DESCRIPTION
21+
-----------
22+
23+
NOTE! This command is still only an experiment, subject to change dramatically
24+
(or even to be abandoned).
25+
26+
Monitors files and directories in the working directory for changes using
27+
platform-specific file system notification facilities.
28+
29+
It communicates directly with commands like `git status` using the
30+
link:technical/api-simple-ipc.html[simple IPC] interface instead of
31+
the slower linkgit:githooks[5] interface.
32+
33+
OPTIONS
34+
-------
35+
36+
--start::
37+
Starts the fsmonitor daemon in the background.
38+
39+
--run::
40+
Runs the fsmonitor daemon in the foreground.
41+
42+
--stop::
43+
Stops the fsmonitor daemon running for the current working
44+
directory, if present.
45+
46+
--is-running::
47+
Exits with zero status if the fsmonitor daemon is watching the
48+
current working directory.
49+
50+
--is-supported::
51+
Exits with zero status if the fsmonitor daemon feature is supported
52+
on this platform.
53+
54+
--query <token>::
55+
Connects to the fsmonitor daemon (starting it if necessary) and
56+
requests the list of changed files and directories since the
57+
given token.
58+
This is intended for testing purposes.
59+
60+
--query-index::
61+
Read the current `<token>` from the File System Monitor index
62+
extension (if present) and use it to query the fsmonitor daemon.
63+
This is intended for testing purposes.
64+
65+
--flush::
66+
Force the fsmonitor daemon to flush its in-memory cache and
67+
re-sync with the file system.
68+
This is intended for testing purposes.
69+
70+
REMARKS
71+
-------
72+
The fsmonitor daemon is a long running process that will watch a single
73+
working directory. Commands, such as `git status`, should automatically
74+
start it (if necessary) when `core.useBuiltinFSMonitor` is set to `true`
75+
(see linkgit:git-config[1]).
76+
77+
Configure the built-in FSMonitor via `core.useBuiltinFSMonitor` in each
78+
working directory separately, or globally via `git config --global
79+
core.useBuiltinFSMonitor true`.
80+
81+
Tokens are opaque strings. They are used by the fsmonitor daemon to
82+
mark a point in time and the associated internal state. Callers should
83+
make no assumptions about the content of the token. In particular,
84+
the should not assume that it is a timestamp.
85+
86+
Query commands send a request-token to the daemon and it responds with
87+
a summary of the changes that have occurred since that token was
88+
created. The daemon also returns a response-token that the client can
89+
use in a future query.
90+
91+
For more information see the "File System Monitor" section in
92+
linkgit:git-update-index[1].
93+
94+
CAVEATS
95+
-------
96+
97+
The fsmonitor daemon does not currently know about submodules and does
98+
not know to filter out file system events that happen within a
99+
submodule. If fsmonitor daemon is watching a super repo and a file is
100+
modified within the working directory of a submodule, it will report
101+
the change (as happening against the super repo). However, the client
102+
should properly ignore these extra events, so performance may be affected
103+
but it should not cause an incorrect result.
104+
105+
GIT
106+
---
107+
Part of the linkgit:git[1] suite

Documentation/git-update-index.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,9 @@ FILE SYSTEM MONITOR
498498
This feature is intended to speed up git operations for repos that have
499499
large working directories.
500500

501-
It enables git to work together with a file system monitor (see the
501+
It enables git to work together with a file system monitor (see
502+
linkgit:git-fsmonitor--daemon[1]
503+
and the
502504
"fsmonitor-watchman" section of linkgit:githooks[5]) that can
503505
inform it as to what files have been modified. This enables git to avoid
504506
having to lstat() every file to find modified files.

Documentation/githooks.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,8 @@ fsmonitor-watchman
593593

594594
This hook is invoked when the configuration option `core.fsmonitor` is
595595
set to `.git/hooks/fsmonitor-watchman` or `.git/hooks/fsmonitor-watchmanv2`
596-
depending on the version of the hook to use.
596+
depending on the version of the hook to use, unless overridden via
597+
`core.useBuiltinFSMonitor` (see linkgit:git-config[1]).
597598

598599
Version 1 takes two arguments, a version (1) and the time in elapsed
599600
nanoseconds since midnight, January 1, 1970.

repo-settings.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
#include "config.h"
33
#include "repository.h"
44
#include "midx.h"
5+
#include "fsmonitor-ipc.h"
56

67
#define UPDATE_DEFAULT_BOOL(s,v) do { if (s == -1) { s = v; } } while(0)
78

89
void prepare_repo_settings(struct repository *r)
910
{
10-
int value;
11+
int value, feature_many_files = 0;
1112
char *strval;
1213

1314
if (r->settings.initialized)
@@ -62,6 +63,7 @@ void prepare_repo_settings(struct repository *r)
6263
r->settings.use_builtin_fsmonitor = 1;
6364

6465
if (!repo_config_get_bool(r, "feature.manyfiles", &value) && value) {
66+
feature_many_files = 1;
6567
UPDATE_DEFAULT_BOOL(r->settings.index_version, 4);
6668
UPDATE_DEFAULT_BOOL(r->settings.core_untracked_cache, UNTRACKED_CACHE_WRITE);
6769
}
@@ -70,8 +72,12 @@ void prepare_repo_settings(struct repository *r)
7072
r->settings.fetch_write_commit_graph = value;
7173
UPDATE_DEFAULT_BOOL(r->settings.fetch_write_commit_graph, 0);
7274

73-
if (!repo_config_get_bool(r, "feature.experimental", &value) && value)
75+
if (!repo_config_get_bool(r, "feature.experimental", &value) && value) {
7476
UPDATE_DEFAULT_BOOL(r->settings.fetch_negotiation_algorithm, FETCH_NEGOTIATION_SKIPPING);
77+
if (feature_many_files && fsmonitor_ipc__is_supported())
78+
UPDATE_DEFAULT_BOOL(r->settings.use_builtin_fsmonitor,
79+
1);
80+
}
7581

7682
/* Hack for test programs like test-dump-untracked-cache */
7783
if (ignore_untracked_cache_config)

0 commit comments

Comments
 (0)