From: Ben Peart <peartben@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, benpeart@microsoft.com, pclouds@gmail.com,
johannes.schindelin@gmx.de, David.Turner@twosigma.com,
peff@peff.net, christian.couder@gmail.com, avarab@gmail.com
Subject: [PATCH v4 0/6] Fast git status via a file system watcher
Date: Thu, 1 Jun 2017 11:50:59 -0400 [thread overview]
Message-ID: <20170601155105.28356-1-benpeart@microsoft.com> (raw)
Changes from V3 include:
- update test script based on feedback
- update template hook proc with better post-processing code and make
it executable
Ben Peart (6):
bswap: add 64 bit endianness helper get_be64
dir: make lookup_untracked() available outside of dir.c
fsmonitor: teach git to optionally utilize a file system monitor to
speed up detecting new or changed files.
fsmonitor: add test cases for fsmonitor extension
fsmonitor: add documentation for the fsmonitor extension.
fsmonitor: add a sample query-fsmonitor hook script for Watchman
Documentation/config.txt | 7 +
Documentation/githooks.txt | 23 +++
Documentation/technical/index-format.txt | 19 +++
Makefile | 1 +
builtin/update-index.c | 1 +
cache.h | 5 +
compat/bswap.h | 4 +
config.c | 5 +
dir.c | 16 ++-
dir.h | 5 +
entry.c | 1 +
environment.c | 1 +
fsmonitor.c | 238 +++++++++++++++++++++++++++++++
fsmonitor.h | 9 ++
read-cache.c | 28 +++-
t/t7519-status-fsmonitor.sh | 173 ++++++++++++++++++++++
templates/hooks--query-fsmonitor.sample | 60 ++++++++
unpack-trees.c | 1 +
18 files changed, 594 insertions(+), 3 deletions(-)
create mode 100644 fsmonitor.c
create mode 100644 fsmonitor.h
create mode 100755 t/t7519-status-fsmonitor.sh
create mode 100755 templates/hooks--query-fsmonitor.sample
Interdiff (v3..v4):
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 395db46d55..458eabe6dc 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -5,48 +5,46 @@ test_description='git status with file system watcher'
. ./test-lib.sh
clean_repo () {
- git reset --hard HEAD
- git clean -fd
+ git reset --hard HEAD &&
+ git clean -fd &&
rm -f marker
}
dirty_repo () {
- : >untracked
- : >dir1/untracked
- : >dir2/untracked
- echo 1 >modified
- echo 2 >dir1/modified
- echo 3 >dir2/modified
- echo 4 >new
- echo 5 >dir1/new
- echo 6 >dir2/new
- git add new
- git add dir1/new
+ : >untracked &&
+ : >dir1/untracked &&
+ : >dir2/untracked &&
+ echo 1 >modified &&
+ echo 2 >dir1/modified &&
+ echo 3 >dir2/modified &&
+ echo 4 >new &&
+ echo 5 >dir1/new &&
+ echo 6 >dir2/new &&
+ git add new &&
+ git add dir1/new &&
git add dir2/new
}
# The test query-fsmonitor hook proc will output a marker file we can use to
# ensure the hook was actually used to generate the correct results.
+# fsmonitor works correctly with or without the untracked cache
+# but if it is available, we'll turn it on to ensure we test that
+# codepath as well.
+
+test_lazy_prereq UNTRACKED_CACHE '
+ { git update-index --test-untracked-cache; ret=$?; } &&
+ test $ret -ne 1
+'
+
+if test_have_prereq UNTRACKED_CACHE; then
+ git config core.untrackedcache true
+else
+ git config core.untrackedcache false
+fi
+
test_expect_success 'setup' '
mkdir -p .git/hooks &&
- write_script .git/hooks/query-fsmonitor<<-\EOF &&
- if [ $1 -ne 1 ]
- then
- echo -e "Unsupported query-fsmonitor hook version.\n" >&2
- exit 1;
- fi
- : >marker
- printf "untracked\0"
- printf "dir1/untracked\0"
- printf "dir2/untracked\0"
- printf "modified\0"
- printf "dir1/modified\0"
- printf "dir2/modified\0"
- printf "new\0""
- printf "dir1/new\0"
- printf "dir2/new\0"
- EOF
: >tracked &&
: >modified &&
mkdir dir1 &&
@@ -58,55 +56,19 @@ test_expect_success 'setup' '
git add . &&
test_tick &&
git commit -m initial &&
- dirty_repo
-'
-
-cat >.gitignore <<\EOF
-.gitignore
-expect*
-output*
-marker*
-EOF
-
-# Status is well tested elsewhere so we'll just ensure that the results are
-# the same when using core.fsmonitor. First call after turning on the option
-# does a complete scan so need to do two calls to ensure we test the new
-# codepath.
-
-test_expect_success 'status with core.untrackedcache true' '
- git config core.fsmonitor true &&
- git config core.untrackedcache true &&
- git -c core.fsmonitor=false -c core.untrackedcache=true status >expect &&
- clean_repo &&
- git status &&
- test_path_is_missing marker &&
- dirty_repo &&
- git status >output &&
- test_path_is_file marker &&
- test_i18ncmp expect output
-'
-
-
-test_expect_success 'status with core.untrackedcache false' '
git config core.fsmonitor true &&
- git config core.untrackedcache false &&
- git -c core.fsmonitor=false -c core.untrackedcache=false status >expect &&
- clean_repo &&
- git status &&
- test_path_is_missing marker &&
- dirty_repo &&
- git status >output &&
- test_path_is_file marker &&
- test_i18ncmp expect output
+ cat >.gitignore <<-\EOF
+ .gitignore
+ expect*
+ output*
+ marker*
+ EOF
'
# Ensure commands that call refresh_index() to move the index back in time
# properly invalidate the fsmonitor cache
test_expect_success 'refresh_index() invalidates fsmonitor cache' '
- git config core.fsmonitor true &&
- git config core.untrackedcache true &&
- clean_repo &&
git status &&
test_path_is_missing marker &&
dirty_repo &&
@@ -118,6 +80,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
git status &&
test_path_is_file marker &&
git reset HEAD~1 &&
+ rm -f marker &&
git status >output &&
test_path_is_file marker &&
git -c core.fsmonitor=false status >expect &&
@@ -129,9 +92,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
# extensions exist other than 'TREE' so do a "git status" to get the extension
# written before testing the results.
-test_expect_success 'status doesnt detect unreported modifications' '
- git config core.fsmonitor true &&
- git config core.untrackedcache true &&
+test_expect_success "status doesn't detect unreported modifications" '
write_script .git/hooks/query-fsmonitor<<-\EOF &&
:>marker
EOF
@@ -146,13 +107,67 @@ test_expect_success 'status doesnt detect unreported modifications' '
test_i18ngrep ! "Untracked files:" output &&
write_script .git/hooks/query-fsmonitor<<-\EOF &&
:>marker
- printf "untracked%s\0"
+ printf "untracked\0"
printf "dir1/modified\0"
EOF
+ rm -f marker &&
git status >output &&
test_path_is_file marker &&
test_i18ngrep "Changes not staged for commit:" output &&
test_i18ngrep "Untracked files:" output
'
+# Status is well tested elsewhere so we'll just ensure that the results are
+# the same when using core.fsmonitor. First call after turning on the option
+# does a complete scan so we need to do two calls to ensure we test the new
+# codepath.
+
+test_expect_success 'status with core.untrackedcache false' '
+ git config core.untrackedcache false &&
+ write_script .git/hooks/query-fsmonitor<<-\EOF &&
+ if [ $1 -ne 1 ]
+ then
+ echo -e "Unsupported query-fsmonitor hook version.\n" >&2
+ exit 1;
+ fi
+ : >marker
+ printf "untracked\0"
+ printf "dir1/untracked\0"
+ printf "dir2/untracked\0"
+ printf "modified\0"
+ printf "dir1/modified\0"
+ printf "dir2/modified\0"
+ printf "new\0""
+ printf "dir1/new\0"
+ printf "dir2/new\0"
+ EOF
+ clean_repo &&
+ dirty_repo &&
+ git -c core.fsmonitor=false status >expect &&
+ clean_repo &&
+ git status &&
+ test_path_is_missing marker &&
+ dirty_repo &&
+ git status >output &&
+ test_path_is_file marker &&
+ test_i18ncmp expect output
+'
+
+if ! test_have_prereq UNTRACKED_CACHE; then
+ skip_all='This system does not support untracked cache'
+ test_done
+fi
+
+test_expect_success 'status with core.untrackedcache true' '
+ git config core.untrackedcache true &&
+ git -c core.fsmonitor=false status >expect &&
+ clean_repo &&
+ git status &&
+ test_path_is_missing marker &&
+ dirty_repo &&
+ git status >output &&
+ test_path_is_file marker &&
+ test_i18ncmp expect output
+'
+
test_done
diff --git a/templates/hooks--query-fsmonitor.sample b/templates/hooks--query-fsmonitor.sample
old mode 100644
new mode 100755
index 615f3332fa..941c4c5b57
--- a/templates/hooks--query-fsmonitor.sample
+++ b/templates/hooks--query-fsmonitor.sample
@@ -4,10 +4,10 @@
# (https://facebook.github.io/watchman/) with git to provide fast
# git status.
#
-# The hook is passed a time in nanoseconds formatted as a string and
-# outputs to stdout all files that have been modified since the given
-# time. Paths must be relative to the root of the working tree and
-# separated by a single NUL.
+# The hook is passed a version (currently 1) and a time in nanoseconds
+# formatted as a string and outputs to stdout all files that have been
+# modified since the given time. Paths must be relative to the root of
+# the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-fsmonitor"
@@ -33,5 +33,28 @@ esac
# Query Watchman for all the changes since the requested time
echo "[\"query\", \"$GIT_WORK_TREE\", {\"since\": $time_t, \"fields\":[\"name\"]}]" | \
-watchman -j | \
-perl -e 'use JSON::PP; my $o = JSON::PP->new->utf8->decode(join("", <>)); die "Watchman: $o->{'error'}.\nFalling back to scanning...\n" if defined($o->{"error"}); print(join("\0", @{$o->{"files"}}));'
+ watchman -j |
+ perl -0666 -e '
+ use strict;
+ use warnings;
+
+ my $stdin = <>;
+ die "Watchman: command returned no output.\nFalling back to scanning...\n" if $stdin eq "";
+ die "Watchman: command returned invalid output: $stdin\nFalling back to scanning...\n" unless $stdin =~ /^\{/;
+
+ my $json_pkg;
+ eval {
+ require JSON::XS;
+ $json_pkg = "JSON::XS";
+ 1;
+ } or do {
+ require JSON::PP;
+ $json_pkg = "JSON::PP";
+ };
+
+ my $o = $json_pkg->new->utf8->decode($stdin);
+ die "Watchman: $o->{error}.\nFalling back to scanning...\n" if $o->{error};
+
+ local $, = "\0";
+ print @{$o->{files}};
+ '
--
2.13.0.windows.1.9.gc201c67b71
next reply other threads:[~2017-06-01 15:51 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-01 15:50 Ben Peart [this message]
2017-06-01 15:51 ` [PATCH v4 1/6] bswap: add 64 bit endianness helper get_be64 Ben Peart
2017-06-01 15:51 ` [PATCH v4 2/6] dir: make lookup_untracked() available outside of dir.c Ben Peart
2017-06-01 15:51 ` [PATCH v4 3/6] fsmonitor: teach git to optionally utilize a file system monitor to speed up detecting new or changed files Ben Peart
2017-06-01 15:51 ` [PATCH v4 4/6] fsmonitor: add test cases for fsmonitor extension Ben Peart
2017-06-01 15:51 ` [PATCH v4 5/6] fsmonitor: add documentation for the " Ben Peart
2017-06-01 15:51 ` [PATCH v4 6/6] fsmonitor: add a sample query-fsmonitor hook script for Watchman Ben Peart
2017-06-07 21:38 ` Ævar Arnfjörð Bjarmason
2017-06-01 19:57 ` [PATCH v4 0/6] Fast git status via a file system watcher Ævar Arnfjörð Bjarmason
2017-06-01 21:06 ` Ben Peart
2017-06-01 21:12 ` Ævar Arnfjörð Bjarmason
2017-06-01 21:13 ` Stefan Beller
2017-06-01 21:26 ` Jeff King
2017-06-01 20:51 ` Ævar Arnfjörð Bjarmason
2017-06-01 21:13 ` Ævar Arnfjörð Bjarmason
2017-06-02 0:40 ` Ben Peart
2017-06-02 10:28 ` [WIP/PATCH 7/6] perf: add a performance test for core.fsmonitor Ævar Arnfjörð Bjarmason
2017-06-02 21:44 ` David Turner
2017-06-03 18:08 ` Ævar Arnfjörð Bjarmason
2017-06-05 14:27 ` Ben Peart
2017-06-02 22:05 ` Ben Peart
2017-06-02 23:06 ` Ævar Arnfjörð Bjarmason
2017-06-07 19:51 ` Ben Peart
2017-06-07 21:46 ` Ævar Arnfjörð Bjarmason
2017-06-08 1:57 ` Ben Peart
2017-06-04 1:59 ` Junio C Hamano
2017-06-04 7:46 ` Ævar Arnfjörð Bjarmason
2017-06-04 8:21 ` Jeff King
2017-06-02 1:56 ` [PATCH v4 0/6] Fast git status via a file system watcher Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170601155105.28356-1-benpeart@microsoft.com \
--to=peartben@gmail.com \
--cc=David.Turner@twosigma.com \
--cc=avarab@gmail.com \
--cc=benpeart@microsoft.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=johannes.schindelin@gmx.de \
--cc=pclouds@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).