diff options
author | Ben Peart <peartben@gmail.com> | 2017-06-10 09:40:25 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-06-12 14:41:08 -0700 |
commit | 06fe0892d855943b0ecf76103cd0104e8a64782b (patch) | |
tree | afbfdd99c37992a7b5b791feebdebcec2128db36 | |
parent | 3df0c75c7679a8b64527d96c716f61015c9514e3 (diff) | |
download | git-06fe0892d855943b0ecf76103cd0104e8a64782b.tar.gz |
fsmonitor: add a sample query-fsmonitor hook script for Watchman
This hook script integrates the new fsmonitor capabilities of git with
the cross platform Watchman file watching service. To use the script:
Download and install Watchman from https://facebook.github.io/watchman/
and instruct Watchman to watch your working directory for changes
('watchman watch-project /usr/src/git').
Rename the sample integration hook from query-fsmonitor.sample to
query-fsmonitor.
Configure git to use the extension ('git config core.fsmonitor true')
and optionally turn on the untracked cache for optimal performance
('git config core.untrackedcache true').
Signed-off-by: Ben Peart <benpeart@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-x | templates/hooks--query-fsmonitor.sample | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/templates/hooks--query-fsmonitor.sample b/templates/hooks--query-fsmonitor.sample new file mode 100755 index 0000000000..8d05b87a90 --- /dev/null +++ b/templates/hooks--query-fsmonitor.sample @@ -0,0 +1,76 @@ +#!/bin/sh +# +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to provide fast +# git status. +# +# 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" + +# check the hook interface version +if [ "$1" -eq 1 ] +then + # convert nanoseconds to seconds + time_t=$(($2/1000000000)) +else + echo -e "Unsupported query-fsmonitor hook version.\nFalling back to scanning...\n" >&2 + exit 1; +fi + +# Convert unix style paths to what Watchman expects +case "$(uname -s)" in +MINGW*|MSYS_NT*) + GIT_WORK_TREE="$(cygpath -aw "$PWD" | sed 's,\\,/,g')" + ;; +*) + GIT_WORK_TREE="$PWD" + ;; +esac + +# In the query expression below we're asking for names of files that +# changed since $time_t but were not transient (ie created after +# $time_t but no longer exist). +# +# To accomplish this, we're using the "since" generator to use the +# recency index to select candidate nodes and "fields" to limit the +# output to file names only. Then we're using the "expression" term to +# further constrain the results. +# +# The category of transient files that we want to ignore will have a +# creation clock (cclock) newer than $time_t value and will also not +# currently exist. + +echo "[\"query\", \"$GIT_WORK_TREE\", { \ + \"since\": $time_t, \ + \"fields\": [\"name\"], \ + \"expression\": [\"not\", [\"allof\", [\"since\", $time_t, \"cclock\"], [\"not\", \"exists\"]]] \ + }]" | \ + 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}}; + ' |