Skip to content

Commit 439c1e6

Browse files
committed
Merge branch 'jh/builtin-fsmonitor-part2'
Built-in fsmonitor (part 2). * jh/builtin-fsmonitor-part2: (30 commits) t7527: test status with untracked-cache and fsmonitor--daemon fsmonitor: force update index after large responses fsmonitor--daemon: use a cookie file to sync with file system fsmonitor--daemon: periodically truncate list of modified files t/perf/p7519: add fsmonitor--daemon test cases t/perf/p7519: speed up test on Windows t/perf/p7519: fix coding style t/helper/test-chmtime: skip directories on Windows t/perf: avoid copying builtin fsmonitor files into test repo t7527: create test for fsmonitor--daemon t/helper/fsmonitor-client: create IPC client to talk to FSMonitor Daemon help: include fsmonitor--daemon feature flag in version info fsmonitor--daemon: implement handle_client callback compat/fsmonitor/fsm-listen-darwin: implement FSEvent listener on MacOS compat/fsmonitor/fsm-listen-darwin: add MacOS header files for FSEvent compat/fsmonitor/fsm-listen-win32: implement FSMonitor backend on Windows fsmonitor--daemon: create token-based changed path cache fsmonitor--daemon: define token-ids fsmonitor--daemon: add pathname classification fsmonitor--daemon: implement 'start' command ...
2 parents ba2452b + a3dfe97 commit 439c1e6

38 files changed

+4326
-106
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
/git-format-patch
7373
/git-fsck
7474
/git-fsck-objects
75+
/git-fsmonitor--daemon
7576
/git-gc
7677
/git-get-tar-commit-id
7778
/git-grep

Documentation/config/core.txt

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,54 @@ core.protectNTFS::
6262
Defaults to `true` on Windows, and `false` elsewhere.
6363

6464
core.fsmonitor::
65-
If set, the value of this variable is used as a command which
66-
will identify all files that may have changed since the
67-
requested date/time. This information is used to speed up git by
68-
avoiding unnecessary processing of files that have not changed.
69-
See the "fsmonitor-watchman" section of linkgit:githooks[5].
65+
If set to true, enable the built-in file system monitor
66+
daemon for this working directory (linkgit:git-fsmonitor--daemon[1]).
67+
+
68+
Like hook-based file system monitors, the built-in file system monitor
69+
can speed up Git commands that need to refresh the Git index
70+
(e.g. `git status`) in a working directory with many files. The
71+
built-in monitor eliminates the need to install and maintain an
72+
external third-party tool.
73+
+
74+
The built-in file system monitor is currently available only on a
75+
limited set of supported platforms. Currently, this includes Windows
76+
and MacOS.
77+
+
78+
Otherwise, this variable contains the pathname of the "fsmonitor"
79+
hook command.
80+
+
81+
This hook command is used to identify all files that may have changed
82+
since the requested date/time. This information is used to speed up
83+
git by avoiding unnecessary scanning of files that have not changed.
84+
+
85+
See the "fsmonitor-watchman" section of linkgit:githooks[5].
86+
+
87+
Note that if you concurrently use multiple versions of Git, such
88+
as one version on the command line and another version in an IDE
89+
tool, that the definition of `core.fsmonitor` was extended to
90+
allow boolean values in addition to hook pathnames. Git versions
91+
2.35.1 and prior will not understand the boolean values and will
92+
consider the "true" or "false" values as hook pathnames to be
93+
invoked. Git versions 2.26 thru 2.35.1 default to hook protocol
94+
V2 and will fall back to no fsmonitor (full scan). Git versions
95+
prior to 2.26 default to hook protocol V1 and will silently
96+
assume there were no changes to report (no scan), so status
97+
commands may report incomplete results. For this reason, it is
98+
best to upgrade all of your Git versions before using the built-in
99+
file system monitor.
70100

71101
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.
102+
Sets the protocol version to be used when invoking the
103+
"fsmonitor" hook.
104+
+
105+
There are currently versions 1 and 2. When this is not set,
106+
version 2 will be tried first and if it fails then version 1
107+
will be tried. Version 1 uses a timestamp as input to determine
108+
which files have changes since that time but some monitors
109+
like Watchman have race conditions when used with a timestamp.
110+
Version 2 uses an opaque string so that the monitor can return
111+
something that can be used to determine what files have changed
112+
without race conditions.
81113

82114
core.trustctime::
83115
If false, the ctime differences between the index and the
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
git-fsmonitor--daemon(1)
2+
========================
3+
4+
NAME
5+
----
6+
git-fsmonitor--daemon - A Built-in File System Monitor
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' status
15+
16+
DESCRIPTION
17+
-----------
18+
19+
A daemon to watch the working directory for file and directory
20+
changes using platform-specific file system notification facilities.
21+
22+
This daemon communicates directly with commands like `git status`
23+
using the link:technical/api-simple-ipc.html[simple IPC] interface
24+
instead of the slower linkgit:githooks[5] interface.
25+
26+
This daemon is built into Git so that no third-party tools are
27+
required.
28+
29+
OPTIONS
30+
-------
31+
32+
start::
33+
Starts a daemon in the background.
34+
35+
run::
36+
Runs a daemon in the foreground.
37+
38+
stop::
39+
Stops the daemon running in the current working
40+
directory, if present.
41+
42+
status::
43+
Exits with zero status if a daemon is watching the
44+
current working directory.
45+
46+
REMARKS
47+
-------
48+
49+
This daemon is a long running process used to watch a single working
50+
directory and maintain a list of the recently changed files and
51+
directories. Performance of commands such as `git status` can be
52+
increased if they just ask for a summary of changes to the working
53+
directory and can avoid scanning the disk.
54+
55+
When `core.fsmonitor` is set to `true` (see linkgit:git-config[1])
56+
commands, such as `git status`, will ask the daemon for changes and
57+
automatically start it (if necessary).
58+
59+
For more information see the "File System Monitor" section in
60+
linkgit:git-update-index[1].
61+
62+
CAVEATS
63+
-------
64+
65+
The fsmonitor daemon does not currently know about submodules and does
66+
not know to filter out file system events that happen within a
67+
submodule. If fsmonitor daemon is watching a super repo and a file is
68+
modified within the working directory of a submodule, it will report
69+
the change (as happening against the super repo). However, the client
70+
will properly ignore these extra events, so performance may be affected
71+
but it will not cause an incorrect result.
72+
73+
GIT
74+
---
75+
Part of the linkgit:git[1] suite

Documentation/git-update-index.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,9 @@ FILE SYSTEM MONITOR
527527
This feature is intended to speed up git operations for repos that have
528528
large working directories.
529529

530-
It enables git to work together with a file system monitor (see the
530+
It enables git to work together with a file system monitor (see
531+
linkgit:git-fsmonitor--daemon[1]
532+
and the
531533
"fsmonitor-watchman" section of linkgit:githooks[5]) that can
532534
inform it as to what files have been modified. This enables git to avoid
533535
having to lstat() every file to find modified files.
@@ -538,8 +540,8 @@ looking for new files.
538540

539541
If you want to enable (or disable) this feature, it is easier to use
540542
the `core.fsmonitor` configuration variable (see
541-
linkgit:git-config[1]) than using the `--fsmonitor` option to
542-
`git update-index` in each repository, especially if you want to do so
543+
linkgit:git-config[1]) than using the `--fsmonitor` option to `git
544+
update-index` in each repository, especially if you want to do so
543545
across all repositories you use, because you can set the configuration
544546
variable in your `$HOME/.gitconfig` just once and have it affect all
545547
repositories you touch.

Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,11 @@ include shared.mak
475475
# directory, and the JSON compilation database 'compile_commands.json' will be
476476
# created at the root of the repository.
477477
#
478+
# If your platform supports a built-in fsmonitor backend, set
479+
# FSMONITOR_DAEMON_BACKEND to the "<name>" of the corresponding
480+
# `compat/fsmonitor/fsm-listen-<name>.c` that implements the
481+
# `fsm_listen__*()` routines.
482+
#
478483
# Define DEVELOPER to enable more compiler warnings. Compiler version
479484
# and family are auto detected, but could be overridden by defining
480485
# COMPILER_FEATURES (see config.mak.dev). You can still set
@@ -716,6 +721,7 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o
716721
TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
717722
TEST_BUILTINS_OBJS += test-example-decorate.o
718723
TEST_BUILTINS_OBJS += test-fast-rebase.o
724+
TEST_BUILTINS_OBJS += test-fsmonitor-client.o
719725
TEST_BUILTINS_OBJS += test-genrandom.o
720726
TEST_BUILTINS_OBJS += test-genzeros.o
721727
TEST_BUILTINS_OBJS += test-getcwd.o
@@ -933,6 +939,8 @@ LIB_OBJS += fetch-pack.o
933939
LIB_OBJS += fmt-merge-msg.o
934940
LIB_OBJS += fsck.o
935941
LIB_OBJS += fsmonitor.o
942+
LIB_OBJS += fsmonitor-ipc.o
943+
LIB_OBJS += fsmonitor-settings.o
936944
LIB_OBJS += gettext.o
937945
LIB_OBJS += gpg-interface.o
938946
LIB_OBJS += graph.o
@@ -1139,6 +1147,7 @@ BUILTIN_OBJS += builtin/fmt-merge-msg.o
11391147
BUILTIN_OBJS += builtin/for-each-ref.o
11401148
BUILTIN_OBJS += builtin/for-each-repo.o
11411149
BUILTIN_OBJS += builtin/fsck.o
1150+
BUILTIN_OBJS += builtin/fsmonitor--daemon.o
11421151
BUILTIN_OBJS += builtin/gc.o
11431152
BUILTIN_OBJS += builtin/get-tar-commit-id.o
11441153
BUILTIN_OBJS += builtin/grep.o
@@ -1992,6 +2001,11 @@ ifdef NEED_ACCESS_ROOT_HANDLER
19922001
COMPAT_OBJS += compat/access.o
19932002
endif
19942003

2004+
ifdef FSMONITOR_DAEMON_BACKEND
2005+
COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND
2006+
COMPAT_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o
2007+
endif
2008+
19952009
ifeq ($(TCLTK_PATH),)
19962010
NO_TCLTK = NoThanks
19972011
endif
@@ -2848,6 +2862,9 @@ GIT-BUILD-OPTIONS: FORCE
28482862
@echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
28492863
@echo SANITIZE_LEAK=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_LEAK)))'\' >>$@+
28502864
@echo X=\'$(X)\' >>$@+
2865+
ifdef FSMONITOR_DAEMON_BACKEND
2866+
@echo FSMONITOR_DAEMON_BACKEND=\''$(subst ','\'',$(subst ','\'',$(FSMONITOR_DAEMON_BACKEND)))'\' >>$@+
2867+
endif
28512868
ifdef TEST_OUTPUT_DIRECTORY
28522869
@echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
28532870
endif

builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix);
159159
int cmd_for_each_repo(int argc, const char **argv, const char *prefix);
160160
int cmd_format_patch(int argc, const char **argv, const char *prefix);
161161
int cmd_fsck(int argc, const char **argv, const char *prefix);
162+
int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix);
162163
int cmd_gc(int argc, const char **argv, const char *prefix);
163164
int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);
164165
int cmd_grep(int argc, const char **argv, const char *prefix);

0 commit comments

Comments
 (0)