Skip to content

Commit 20401cb

Browse files
committed
Merge branch 'jh/builtin-fsmonitor' into seen
An attempt to write and ship with a watchman equivalent tailored for our use. * jh/builtin-fsmonitor: (35 commits) BANDAID: sparse fixes t7527: test FS event reporing on MacOS WRT case and Unicode fsmonitor: handle shortname for .git t7527: test status with untracked-cache and fsmonitor--daemon fsmonitor: force update index after large responses fsmonitor: enhance existing comments fsmonitor--daemon: use a cookie file to sync with file system fsmonitor--daemon: periodically truncate list of modified files t7527: create test for fsmonitor--daemon t/perf/p7519: add fsmonitor--daemon test cases t/perf: avoid copying builtin fsmonitor files into test repo t/perf/p7519: speed up test using "test-tool touch" t/helper/test-touch: add helper to touch a series of files fsmonitor--daemon: implement handle_client callback fsmonitor-fs-listen-macos: implement FSEvent listener on MacOS fsmonitor-fs-listen-macos: add macos header files for FSEvent fsmonitor-fs-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 ...
2 parents 6de3d88 + a5a42b9 commit 20401cb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4618
-121
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: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,50 @@ 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, this variable contains the pathname of the "fsmonitor"
66+
hook command.
67+
+
68+
This hook command is used to identify all files that may have changed
69+
since the requested date/time. This information is used to speed up
70+
git by avoiding unnecessary scanning of files that have not changed.
71+
+
72+
See the "fsmonitor-watchman" section of linkgit:githooks[5].
73+
+
74+
Note: The value of this config setting is ignored if the
75+
built-in file system monitor is enabled (see `core.useBuiltinFSMonitor`).
7076

7177
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.
78+
Sets the protocol version to be used when invoking the
79+
"fsmonitor" hook.
80+
+
81+
There are currently versions 1 and 2. When this is not set,
82+
version 2 will be tried first and if it fails then version 1
83+
will be tried. Version 1 uses a timestamp as input to determine
84+
which files have changes since that time but some monitors
85+
like Watchman have race conditions when used with a timestamp.
86+
Version 2 uses an opaque string so that the monitor can return
87+
something that can be used to determine what files have changed
88+
without race conditions.
89+
+
90+
Note: The value of this config setting is ignored if the
91+
built-in file system monitor is enabled (see `core.useBuiltinFSMonitor`).
92+
93+
core.useBuiltinFSMonitor::
94+
If set to true, enable the built-in file system monitor
95+
daemon for this working directory (linkgit:git-fsmonitor--daemon[1]).
96+
+
97+
Like hook-based file system monitors, the built-in file system monitor
98+
can speed up Git commands that need to refresh the Git index
99+
(e.g. `git status`) in a working directory with many files. The
100+
built-in monitor eliminates the need to install and maintain an
101+
external third-party tool.
102+
+
103+
The built-in file system monitor is currently available only on a
104+
limited set of supported platforms. Currently, this includes Windows
105+
and MacOS.
106+
+
107+
Note: if this config setting is set to `true`, the values of
108+
`core.fsmonitor` and `core.fsmonitorHookVersion` are ignored.
81109

82110
core.trustctime::
83111
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.useBuiltinFSMonitor` is set to `true` (see
56+
linkgit:git-config[1]) commands, such as `git status`, will ask the
57+
daemon for changes and 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: 15 additions & 12 deletions
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.
@@ -508,17 +510,18 @@ performance by avoiding the cost of scanning the entire working directory
508510
looking for new files.
509511

510512
If you want to enable (or disable) this feature, it is easier to use
511-
the `core.fsmonitor` configuration variable (see
512-
linkgit:git-config[1]) than using the `--fsmonitor` option to
513-
`git update-index` in each repository, especially if you want to do so
514-
across all repositories you use, because you can set the configuration
515-
variable in your `$HOME/.gitconfig` just once and have it affect all
516-
repositories you touch.
517-
518-
When the `core.fsmonitor` configuration variable is changed, the
519-
file system monitor is added to or removed from the index the next time
520-
a command reads the index. When `--[no-]fsmonitor` are used, the file
521-
system monitor is immediately added to or removed from the index.
513+
the `core.fsmonitor` or `core.useBuiltinFSMonitor` configuration
514+
variable (see linkgit:git-config[1]) than using the `--fsmonitor`
515+
option to `git update-index` in each repository, especially if you
516+
want to do so across all repositories you use, because you can set the
517+
configuration variable in your `$HOME/.gitconfig` just once and have
518+
it affect all repositories you touch.
519+
520+
When the `core.fsmonitor` or `core.useBuiltinFSMonitor` configuration
521+
variable is changed, the file system monitor is added to or removed
522+
from the index the next time a command reads the index. When
523+
`--[no-]fsmonitor` are used, the file system monitor is immediately
524+
added to or removed from the index.
522525

523526
CONFIGURATION
524527
-------------

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.

Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ all::
473473
# directory, and the JSON compilation database 'compile_commands.json' will be
474474
# created at the root of the repository.
475475
#
476+
# If your platform supports a built-in fsmonitor backend, set
477+
# FSMONITOR_DAEMON_BACKEND to the "<name>" of the corresponding
478+
# `compat/fsmonitor/fsmonitor-fs-listen-<name>.c` that implements the
479+
# `fsmonitor_fs_listen__*()` routines.
480+
#
476481
# Define DEVELOPER to enable more compiler warnings. Compiler version
477482
# and family are auto detected, but could be overridden by defining
478483
# COMPILER_FEATURES (see config.mak.dev). You can still set
@@ -715,6 +720,7 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o
715720
TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
716721
TEST_BUILTINS_OBJS += test-example-decorate.o
717722
TEST_BUILTINS_OBJS += test-fast-rebase.o
723+
TEST_BUILTINS_OBJS += test-fsmonitor-client.o
718724
TEST_BUILTINS_OBJS += test-genrandom.o
719725
TEST_BUILTINS_OBJS += test-genzeros.o
720726
TEST_BUILTINS_OBJS += test-getcwd.o
@@ -763,6 +769,7 @@ TEST_BUILTINS_OBJS += test-string-list.o
763769
TEST_BUILTINS_OBJS += test-submodule-config.o
764770
TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
765771
TEST_BUILTINS_OBJS += test-subprocess.o
772+
TEST_BUILTINS_OBJS += test-touch.o
766773
TEST_BUILTINS_OBJS += test-trace2.o
767774
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
768775
TEST_BUILTINS_OBJS += test-userdiff.o
@@ -912,6 +919,7 @@ LIB_OBJS += fetch-pack.o
912919
LIB_OBJS += fmt-merge-msg.o
913920
LIB_OBJS += fsck.o
914921
LIB_OBJS += fsmonitor.o
922+
LIB_OBJS += fsmonitor-ipc.o
915923
LIB_OBJS += gettext.o
916924
LIB_OBJS += gpg-interface.o
917925
LIB_OBJS += graph.o
@@ -1118,6 +1126,7 @@ BUILTIN_OBJS += builtin/fmt-merge-msg.o
11181126
BUILTIN_OBJS += builtin/for-each-ref.o
11191127
BUILTIN_OBJS += builtin/for-each-repo.o
11201128
BUILTIN_OBJS += builtin/fsck.o
1129+
BUILTIN_OBJS += builtin/fsmonitor--daemon.o
11211130
BUILTIN_OBJS += builtin/gc.o
11221131
BUILTIN_OBJS += builtin/get-tar-commit-id.o
11231132
BUILTIN_OBJS += builtin/grep.o
@@ -1958,6 +1967,11 @@ ifdef NEED_ACCESS_ROOT_HANDLER
19581967
COMPAT_OBJS += compat/access.o
19591968
endif
19601969

1970+
ifdef FSMONITOR_DAEMON_BACKEND
1971+
COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND
1972+
COMPAT_OBJS += compat/fsmonitor/fsmonitor-fs-listen-$(FSMONITOR_DAEMON_BACKEND).o
1973+
endif
1974+
19611975
ifeq ($(TCLTK_PATH),)
19621976
NO_TCLTK = NoThanks
19631977
endif
@@ -2874,6 +2888,9 @@ GIT-BUILD-OPTIONS: FORCE
28742888
@echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
28752889
@echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
28762890
@echo X=\'$(X)\' >>$@+
2891+
ifdef FSMONITOR_DAEMON_BACKEND
2892+
@echo FSMONITOR_DAEMON_BACKEND=\''$(subst ','\'',$(subst ','\'',$(FSMONITOR_DAEMON_BACKEND)))'\' >>$@+
2893+
endif
28772894
ifdef TEST_OUTPUT_DIRECTORY
28782895
@echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
28792896
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)