summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Peart <peartben@gmail.com>2017-06-10 09:40:25 -0400
committerJunio C Hamano <gitster@pobox.com>2017-06-12 14:41:08 -0700
commit06fe0892d855943b0ecf76103cd0104e8a64782b (patch)
treeafbfdd99c37992a7b5b791feebdebcec2128db36
parent3df0c75c7679a8b64527d96c716f61015c9514e3 (diff)
downloadgit-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-xtemplates/hooks--query-fsmonitor.sample76
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}};
+ '