{"thread":{"id":"64866","subject":"[PATCH] fsmonitor: fix two bugs in watchman hook retry path","startedAt":"2026-01-26T01:33:25Z","lastAt":"2026-02-28T17:38:01Z","messageCount":8,"participants":["Paul Tarjan via GitGitGadget","Paul Tarjan","Koji Nakamaru","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"534632","messageId":"pull.2180.git.git.1769391202338.gitgitgadget@gmail.com","threadId":"64866","inReplyTo":null,"subject":"[PATCH] fsmonitor: fix two bugs in watchman hook retry path","fromName":"Paul Tarjan via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-01-26T01:33:22Z","receivedAt":"2026-01-26T01:33:25Z","isPatch":true,"sender":{"key":"paul@paultarjan.com","avatar":null},"body":"From: Claude <noreply@anthropic.com>\n\nThe is_work_tree_watched() function in fsmonitor-watchman.sample has\ntwo bugs:\n\n1. Wrong variable in error check: After calling watchman_clock(), the\n   result is stored in $o, but the code checks $output->{error} instead\n   of $o->{error}. This means errors from the clock command are silently\n   ignored.\n\n2. Double output violates protocol: When the retry path triggers (the\n   directory wasn't initially watched), output_result() is called with\n   the \"/\" flag, then launch_watchman() is called recursively which\n   calls output_result() again. This outputs two clock tokens to stdout,\n   but git's fsmonitor v2 protocol expects exactly one response.\n\nFix #1 by checking $o->{error} after watchman_clock().\n\nFix #2 by removing the recursive launch_watchman() call. The \"/\"\n\"everything is dirty\" flag already tells git to do a full scan, and\ngit will call the hook again on the next invocation with a valid clock\ntoken.\n\nApply the same fixes to the test helper scripts in t/t7519/.\n\nSigned-off-by: Paul Tarjan <github@paulisageek.com>\n---\n    fsmonitor-watchman: fix variable reference and remove redundant code\n    \n    The is_work_tree_watched() function in fsmonitor-watchman.sample has two\n    bugs:\n    \n     1. Wrong variable in error check: After calling watchman_clock(), the\n        result is stored in $o, but the code checks $output->{error} instead\n        of $o->{error}. This means errors from the clock command are\n        silently ignored.\n    \n     2. Double output violates protocol: When the retry path triggers (the\n        directory wasn't initially watched), output_result() is called with\n        the \"/\" flag, then launch_watchman() is called recursively which\n        calls output_result() again. This outputs two clock tokens to\n        stdout, but git's fsmonitor v2 protocol expects exactly one\n        response.\n    \n    Fix #1 by checking $o->{error} after watchman_clock().\n    \n    Fix #2 by removing the recursive launch_watchman() call. The \"/\"\n    \"everything is dirty\" flag already tells git to do a full scan, and git\n    will call the hook again on the next invocation with a valid clock\n    token.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2180%2Fptarjan%2Fclaude%2Ffix-watchman-query-bug-sfbIw-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2180/ptarjan/claude/fix-watchman-query-bug-sfbIw-v1\nPull-Request: https://github.com/git/git/pull/2180\n\n t/t7519/fsmonitor-watchman                | 1 -\n t/t7519/fsmonitor-watchman-v2             | 5 +----\n templates/hooks/fsmonitor-watchman.sample | 5 +----\n 3 files changed, 2 insertions(+), 9 deletions(-)\n\ndiff --git a/t/t7519/fsmonitor-watchman b/t/t7519/fsmonitor-watchman\nindex 264b9daf83..907bd1533c 100755\n--- a/t/t7519/fsmonitor-watchman\n+++ b/t/t7519/fsmonitor-watchman\n@@ -109,7 +109,6 @@ sub launch_watchman {\n \t\tclose $fh;\n \n \t\tprint \"/\\0\";\n-\t\teval { launch_watchman() };\n \t\texit 0;\n \t}\n \ndiff --git a/t/t7519/fsmonitor-watchman-v2 b/t/t7519/fsmonitor-watchman-v2\nindex 14ed0aa42d..2c59120c3d 100755\n--- a/t/t7519/fsmonitor-watchman-v2\n+++ b/t/t7519/fsmonitor-watchman-v2\n@@ -141,15 +141,12 @@ sub is_work_tree_watched {\n \t\t# Watchman query just to get it over with now so we won't pay\n \t\t# the cost in git to look up each individual file.\n \t\tmy $o = watchman_clock();\n-\t\t$error = $output->{error};\n+\t\t$error = $o->{error};\n \n \t\tdie \"Watchman: $error.\\n\" .\n \t\t\"Falling back to scanning...\\n\" if $error;\n \n \t\toutput_result($o->{clock}, (\"/\"));\n-\t\t$last_update_token = $o->{clock};\n-\n-\t\teval { launch_watchman() };\n \t\treturn 0;\n \t}\n \ndiff --git a/templates/hooks/fsmonitor-watchman.sample b/templates/hooks/fsmonitor-watchman.sample\nindex 23e856f5de..21c81b6804 100755\n--- a/templates/hooks/fsmonitor-watchman.sample\n+++ b/templates/hooks/fsmonitor-watchman.sample\n@@ -142,15 +142,12 @@ sub is_work_tree_watched {\n \t\t# Watchman query just to get it over with now so we won't pay\n \t\t# the cost in git to look up each individual file.\n \t\tmy $o = watchman_clock();\n-\t\t$error = $output->{error};\n+\t\t$error = $o->{error};\n \n \t\tdie \"Watchman: $error.\\n\" .\n \t\t\"Falling back to scanning...\\n\" if $error;\n \n \t\toutput_result($o->{clock}, (\"/\"));\n-\t\t$last_update_token = $o->{clock};\n-\n-\t\teval { launch_watchman() };\n \t\treturn 0;\n \t}\n \n\nbase-commit: 68cb7f9e92a5d8e9824f5b52ac3d0a9d8f653dbe\n-- \ngitgitgadget\n"},{"id":"535466","messageId":"20260208060359.50233-1-github@paulisageek.com","threadId":"64866","inReplyTo":"pull.2180.git.git.1769391202338.gitgitgadget@gmail.com","subject":"Re: [PATCH] fsmonitor: fix two bugs in watchman hook retry path","fromName":"Paul Tarjan","fromEmail":"paul@paultarjan.com","sentAt":"2026-02-08T06:03:59Z","receivedAt":"2026-02-08T06:04:02Z","isPatch":true,"sender":{"key":"paul@paultarjan.com","avatar":null},"body":"Friendly ping on this patch.\n\nThanks,\nPaul\n"},{"id":"537271","messageId":"20260227062502.6995-1-github@paulisageek.com","threadId":"64866","inReplyTo":"20260208060359.50233-1-github@paulisageek.com","subject":"Re: [PATCH] fsmonitor-watchman: fix variable reference and remove redundant code","fromName":"Paul Tarjan","fromEmail":"paul@paultarjan.com","sentAt":"2026-02-27T06:25:02Z","receivedAt":"2026-02-27T06:25:22Z","isPatch":true,"sender":{"key":"paul@paultarjan.com","avatar":null},"body":"Friendly ping on this patch. Happy to address any feedback.\n\nThanks,\nPaul\n"},{"id":"537397","messageId":"CAOTNsDyy2ZQDhkVyML6j5naS_UC=SjE915hjygj+QmKe4bqc=A@mail.gmail.com","threadId":"64866","inReplyTo":"pull.2180.git.git.1769391202338.gitgitgadget@gmail.com","subject":"Re: [PATCH] fsmonitor: fix two bugs in watchman hook retry path","fromName":"Koji Nakamaru","fromEmail":"koji.nakamaru@gree.net","sentAt":"2026-02-28T17:02:11Z","receivedAt":"2026-02-28T17:02:24Z","isPatch":true,"sender":{"key":"koji.nakamaru@gree.net","avatar":"https://avatars.githubusercontent.com/u/2645978?v=4"},"body":"On Mon, Jan 26, 2026 at 10:33 AM Paul Tarjan via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Claude <noreply@anthropic.com>\n>\n> The is_work_tree_watched() function in fsmonitor-watchman.sample has\n> two bugs:\n>\n> 1. Wrong variable in error check: After calling watchman_clock(), the\n>    result is stored in $o, but the code checks $output->{error} instead\n>    of $o->{error}. This means errors from the clock command are silently\n>    ignored.\n>\n> 2. Double output violates protocol: When the retry path triggers (the\n>    directory wasn't initially watched), output_result() is called with\n>    the \"/\" flag, then launch_watchman() is called recursively which\n>    calls output_result() again. This outputs two clock tokens to stdout,\n>    but git's fsmonitor v2 protocol expects exactly one response.\n>\n> Fix #1 by checking $o->{error} after watchman_clock().\n>\n> Fix #2 by removing the recursive launch_watchman() call. The \"/\"\n> \"everything is dirty\" flag already tells git to do a full scan, and\n> git will call the hook again on the next invocation with a valid clock\n> token.\n>\n> Apply the same fixes to the test helper scripts in t/t7519/.\n>\n> Signed-off-by: Paul Tarjan <github@paulisageek.com>\n> ---\n>     fsmonitor-watchman: fix variable reference and remove redundant code\n>\n>     The is_work_tree_watched() function in fsmonitor-watchman.sample has two\n>     bugs:\n>\n>      1. Wrong variable in error check: After calling watchman_clock(), the\n>         result is stored in $o, but the code checks $output->{error} instead\n>         of $o->{error}. This means errors from the clock command are\n>         silently ignored.\n>\n>      2. Double output violates protocol: When the retry path triggers (the\n>         directory wasn't initially watched), output_result() is called with\n>         the \"/\" flag, then launch_watchman() is called recursively which\n>         calls output_result() again. This outputs two clock tokens to\n>         stdout, but git's fsmonitor v2 protocol expects exactly one\n>         response.\n>\n>     Fix #1 by checking $o->{error} after watchman_clock().\n>\n>     Fix #2 by removing the recursive launch_watchman() call. The \"/\"\n>     \"everything is dirty\" flag already tells git to do a full scan, and git\n>     will call the hook again on the next invocation with a valid clock\n>     token.\n>\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2180%2Fptarjan%2Fclaude%2Ffix-watchman-query-bug-sfbIw-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2180/ptarjan/claude/fix-watchman-query-bug-sfbIw-v1\n> Pull-Request: https://github.com/git/git/pull/2180\n>\n>  t/t7519/fsmonitor-watchman                | 1 -\n>  t/t7519/fsmonitor-watchman-v2             | 5 +----\n>  templates/hooks/fsmonitor-watchman.sample | 5 +----\n>  3 files changed, 2 insertions(+), 9 deletions(-)\n>\n> diff --git a/t/t7519/fsmonitor-watchman b/t/t7519/fsmonitor-watchman\n> index 264b9daf83..907bd1533c 100755\n> --- a/t/t7519/fsmonitor-watchman\n> +++ b/t/t7519/fsmonitor-watchman\n> @@ -109,7 +109,6 @@ sub launch_watchman {\n>                 close $fh;\n>\n>                 print \"/\\0\";\n> -               eval { launch_watchman() };\n>                 exit 0;\n>         }\n>\n> diff --git a/t/t7519/fsmonitor-watchman-v2 b/t/t7519/fsmonitor-watchman-v2\n> index 14ed0aa42d..2c59120c3d 100755\n> --- a/t/t7519/fsmonitor-watchman-v2\n> +++ b/t/t7519/fsmonitor-watchman-v2\n> @@ -141,15 +141,12 @@ sub is_work_tree_watched {\n>                 # Watchman query just to get it over with now so we won't pay\n>                 # the cost in git to look up each individual file.\n>                 my $o = watchman_clock();\n> -               $error = $output->{error};\n> +               $error = $o->{error};\n>\n>                 die \"Watchman: $error.\\n\" .\n>                 \"Falling back to scanning...\\n\" if $error;\n>\n>                 output_result($o->{clock}, (\"/\"));\n> -               $last_update_token = $o->{clock};\n> -\n> -               eval { launch_watchman() };\n>                 return 0;\n>         }\n>\n> diff --git a/templates/hooks/fsmonitor-watchman.sample b/templates/hooks/fsmonitor-watchman.sample\n> index 23e856f5de..21c81b6804 100755\n> --- a/templates/hooks/fsmonitor-watchman.sample\n> +++ b/templates/hooks/fsmonitor-watchman.sample\n> @@ -142,15 +142,12 @@ sub is_work_tree_watched {\n>                 # Watchman query just to get it over with now so we won't pay\n>                 # the cost in git to look up each individual file.\n>                 my $o = watchman_clock();\n> -               $error = $output->{error};\n> +               $error = $o->{error};\n>\n>                 die \"Watchman: $error.\\n\" .\n>                 \"Falling back to scanning...\\n\" if $error;\n>\n>                 output_result($o->{clock}, (\"/\"));\n> -               $last_update_token = $o->{clock};\n> -\n> -               eval { launch_watchman() };\n>                 return 0;\n>         }\n>\n>\n> base-commit: 68cb7f9e92a5d8e9824f5b52ac3d0a9d8f653dbe\n> --\n> gitgitgadget\n>\n\nAlthough I don't have much experience with the Watchman backend, the\nfixes look correct to me.\n\nOne suggestion: it seems we can make the code even cleaner by removing\n$retry and its associated logic, as they appear to be no longer\nnecessary after these changes.\n\n--\nKoji Nakamaru\n"},{"id":"537398","messageId":"aaMiu9mDVAb6Qvyr@fruit.crustytoothpaste.net","threadId":"64866","inReplyTo":"pull.2180.git.git.1769391202338.gitgitgadget@gmail.com","subject":"Re: [PATCH] fsmonitor: fix two bugs in watchman hook retry path","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2026-02-28T17:15:39Z","receivedAt":"2026-02-28T17:15:47Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2026-01-26 at 01:33:22, Paul Tarjan via GitGitGadget wrote:\n> From: Claude <noreply@anthropic.com>\n\nThis looks like it was written by an LLM.  Is that the case, and if so,\nhow does it line up with https://git-scm.com/docs/SubmittingPatches#ai?\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"537399","messageId":"20260228173310.97905-1-github@paulisageek.com","threadId":"64866","inReplyTo":"aaMiu9mDVAb6Qvyr@fruit.crustytoothpaste.net","subject":"Re: [PATCH] fsmonitor-watchman: fix variable reference and remove redundant code","fromName":"Paul Tarjan","fromEmail":"paul@paultarjan.com","sentAt":"2026-02-28T17:33:10Z","receivedAt":"2026-02-28T17:33:13Z","isPatch":true,"sender":{"key":"paul@paultarjan.com","avatar":null},"body":"\"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n\n> This looks like it was written by an LLM.  Is that the case, and if so,\n> how does it line up with https://git-scm.com/docs/SubmittingPatches#ai?\n\nI found these bugs during code review at my company where we use\nthe watchman hook. The $output vs $o mixup and the double\noutput_result() from the recursive call were both causing real\nissues. I used Claude to help with the mechanics of formatting\nand submitting the patch, and it ended up as the commit author,\nwhich was a mistake on my part. I'll fix that in v2 with myself\nas the author.\n\nThanks for flagging it,\nPaul\n"},{"id":"537400","messageId":"20260228173314.97952-1-github@paulisageek.com","threadId":"64866","inReplyTo":"CAOTNsDyy2ZQDhkVyML6j5naS_UC=SjE915hjygj+QmKe4bqc=A@mail.gmail.com","subject":"Re: [PATCH] fsmonitor-watchman: fix variable reference and remove redundant code","fromName":"Paul Tarjan","fromEmail":"paul@paultarjan.com","sentAt":"2026-02-28T17:33:14Z","receivedAt":"2026-02-28T17:33:16Z","isPatch":true,"sender":{"key":"paul@paultarjan.com","avatar":null},"body":"Koji Nakamaru <koji.nakamaru@gree.net> writes:\n\n> Although I don't have much experience with the Watchman backend, the\n> fixes look correct to me.\n>\n> One suggestion: it seems we can make the code even cleaner by removing\n> $retry and its associated logic, as they appear to be no longer\n> necessary after these changes.\n\nGood point. $retry only existed to prevent the infinite recursion\nfrom the recursive launch_watchman() call, so now that we've\nremoved that call it's dead code. Cleaned it up in v2.\n\nThanks for the review,\nPaul\n"},{"id":"537401","messageId":"pull.2180.v2.git.git.1772300277959.gitgitgadget@gmail.com","threadId":"64866","inReplyTo":"pull.2180.git.git.1769391202338.gitgitgadget@gmail.com","subject":"[PATCH v2] fsmonitor-watchman: fix variable reference and remove redundant code","fromName":"Paul Tarjan via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-02-28T17:37:57Z","receivedAt":"2026-02-28T17:38:01Z","isPatch":true,"sender":{"key":"paul@paultarjan.com","avatar":null},"body":"From: Paul Tarjan <github@paulisageek.com>\n\nThe is_work_tree_watched() function in fsmonitor-watchman.sample has\ntwo bugs:\n\n1. Wrong variable in error check: After calling watchman_clock(), the\n   result is stored in $o, but the code checks $output->{error} instead\n   of $o->{error}. This means errors from the clock command are silently\n   ignored.\n\n2. Double output violates protocol: When the retry path triggers (the\n   directory wasn't initially watched), output_result() is called with\n   the \"/\" flag, then launch_watchman() is called recursively which\n   calls output_result() again. This outputs two clock tokens to stdout,\n   but git's fsmonitor v2 protocol expects exactly one response.\n\nFix #1 by checking $o->{error} after watchman_clock().\n\nFix #2 by removing the recursive launch_watchman() call. The \"/\"\n\"everything is dirty\" flag already tells git to do a full scan, and\ngit will call the hook again on the next invocation with a valid clock\ntoken.\n\nWith the recursive call removed, the $retry guard is no longer needed\nsince it only existed to prevent infinite recursion. Remove it.\n\nApply the same fixes to the test helper scripts in t/t7519/.\n\nSigned-off-by: Paul Tarjan <github@paulisageek.com>\n---\n    fsmonitor-watchman: fix variable reference and remove redundant code\n    \n    fsmonitor-watchman: fix variable reference and remove redundant code\n    \n    The is_work_tree_watched() function in fsmonitor-watchman.sample has two\n    bugs:\n    \n     1. Wrong variable in error check: After calling watchman_clock(), the\n        result is stored in $o, but the code checks $output->{error} instead\n        of $o->{error}. This means errors from the clock command are\n        silently ignored.\n    \n     2. Double output violates protocol: When the retry path triggers (the\n        directory wasn't initially watched), output_result() is called with\n        the \"/\" flag, then launch_watchman() is called recursively which\n        calls output_result() again. This outputs two clock tokens to\n        stdout, but git's fsmonitor v2 protocol expects exactly one\n        response.\n    \n    Fix #1 by checking $o->{error} after watchman_clock().\n    \n    Fix #2 by removing the recursive launch_watchman() call. The \"/\"\n    \"everything is dirty\" flag already tells git to do a full scan, and git\n    will call the hook again on the next invocation with a valid clock\n    token.\n    \n    Apply the same fixes to the test helper scripts in t/t7519/.\n    \n    Changes since v1:\n    \n     * Removed $retry variable and associated logic, which only existed to\n       prevent infinite recursion from the now-removed recursive\n       launch_watchman() call\n     * Fixed commit authorship\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2180%2Fptarjan%2Fclaude%2Ffix-watchman-query-bug-sfbIw-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2180/ptarjan/claude/fix-watchman-query-bug-sfbIw-v2\nPull-Request: https://github.com/git/git/pull/2180\n\nRange-diff vs v1:\n\n 1:  116d26287f ! 1:  b9e00b8ab5 fsmonitor: fix two bugs in watchman hook retry path\n     @@\n       ## Metadata ##\n     -Author: Claude <noreply@anthropic.com>\n     +Author: Paul Tarjan <github@paulisageek.com>\n      \n       ## Commit message ##\n     -    fsmonitor: fix two bugs in watchman hook retry path\n     +    fsmonitor-watchman: fix variable reference and remove redundant code\n      \n          The is_work_tree_watched() function in fsmonitor-watchman.sample has\n          two bugs:\n     @@ Commit message\n          git will call the hook again on the next invocation with a valid clock\n          token.\n      \n     +    With the recursive call removed, the $retry guard is no longer needed\n     +    since it only existed to prevent infinite recursion. Remove it.\n     +\n          Apply the same fixes to the test helper scripts in t/t7519/.\n      \n          Signed-off-by: Paul Tarjan <github@paulisageek.com>\n      \n       ## t/t7519/fsmonitor-watchman ##\n     +@@ t/t7519/fsmonitor-watchman: if ($^O =~ 'msys' || $^O =~ 'cygwin') {\n     + \t$git_work_tree = Cwd::cwd();\n     + }\n     + \n     +-my $retry = 1;\n     +-\n     + launch_watchman();\n     + \n     + sub launch_watchman {\n     +@@ t/t7519/fsmonitor-watchman: sub launch_watchman {\n     + \n     + \tmy $o = $json_pkg->new->utf8->decode($response);\n     + \n     +-\tif ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {\n     ++\tif ($o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {\n     + \t\tprint STDERR \"Adding '$git_work_tree' to watchman's watch list.\\n\";\n     +-\t\t$retry--;\n     + \t\tqx/watchman watch \"$git_work_tree\"/;\n     + \t\tdie \"Failed to make watchman watch '$git_work_tree'.\\n\" .\n     + \t\t    \"Falling back to scanning...\\n\" if $? != 0;\n      @@ t/t7519/fsmonitor-watchman: sub launch_watchman {\n       \t\tclose $fh;\n       \n     @@ t/t7519/fsmonitor-watchman: sub launch_watchman {\n       \n      \n       ## t/t7519/fsmonitor-watchman-v2 ##\n     +@@ t/t7519/fsmonitor-watchman-v2: if ($version ne 2) {\n     + \n     + my $git_work_tree = get_working_dir();\n     + \n     +-my $retry = 1;\n     +-\n     + my $json_pkg;\n     + eval {\n     + \trequire JSON::XS;\n     +@@ t/t7519/fsmonitor-watchman-v2: sub watchman_query {\n     + sub is_work_tree_watched {\n     + \tmy ($output) = @_;\n     + \tmy $error = $output->{error};\n     +-\tif ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n     +-\t\t$retry--;\n     ++\tif ($error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n     + \t\tmy $response = qx/watchman watch \"$git_work_tree\"/;\n     + \t\tdie \"Failed to make watchman watch '$git_work_tree'.\\n\" .\n     + \t\t    \"Falling back to scanning...\\n\" if $? != 0;\n      @@ t/t7519/fsmonitor-watchman-v2: sub is_work_tree_watched {\n       \t\t# Watchman query just to get it over with now so we won't pay\n       \t\t# the cost in git to look up each individual file.\n     @@ t/t7519/fsmonitor-watchman-v2: sub is_work_tree_watched {\n       \n      \n       ## templates/hooks/fsmonitor-watchman.sample ##\n     +@@ templates/hooks/fsmonitor-watchman.sample: if ($version ne 2) {\n     + \n     + my $git_work_tree = get_working_dir();\n     + \n     +-my $retry = 1;\n     +-\n     + my $json_pkg;\n     + eval {\n     + \trequire JSON::XS;\n     +@@ templates/hooks/fsmonitor-watchman.sample: sub watchman_query {\n     + sub is_work_tree_watched {\n     + \tmy ($output) = @_;\n     + \tmy $error = $output->{error};\n     +-\tif ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n     +-\t\t$retry--;\n     ++\tif ($error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n     + \t\tmy $response = qx/watchman watch \"$git_work_tree\"/;\n     + \t\tdie \"Failed to make watchman watch '$git_work_tree'.\\n\" .\n     + \t\t    \"Falling back to scanning...\\n\" if $? != 0;\n      @@ templates/hooks/fsmonitor-watchman.sample: sub is_work_tree_watched {\n       \t\t# Watchman query just to get it over with now so we won't pay\n       \t\t# the cost in git to look up each individual file.\n\n\n t/t7519/fsmonitor-watchman                |  6 +-----\n t/t7519/fsmonitor-watchman-v2             | 10 ++--------\n templates/hooks/fsmonitor-watchman.sample | 10 ++--------\n 3 files changed, 5 insertions(+), 21 deletions(-)\n\ndiff --git a/t/t7519/fsmonitor-watchman b/t/t7519/fsmonitor-watchman\nindex 264b9daf83..bcc055c1e0 100755\n--- a/t/t7519/fsmonitor-watchman\n+++ b/t/t7519/fsmonitor-watchman\n@@ -38,8 +38,6 @@ if ($^O =~ 'msys' || $^O =~ 'cygwin') {\n \t$git_work_tree = Cwd::cwd();\n }\n \n-my $retry = 1;\n-\n launch_watchman();\n \n sub launch_watchman {\n@@ -92,9 +90,8 @@ sub launch_watchman {\n \n \tmy $o = $json_pkg->new->utf8->decode($response);\n \n-\tif ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {\n+\tif ($o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {\n \t\tprint STDERR \"Adding '$git_work_tree' to watchman's watch list.\\n\";\n-\t\t$retry--;\n \t\tqx/watchman watch \"$git_work_tree\"/;\n \t\tdie \"Failed to make watchman watch '$git_work_tree'.\\n\" .\n \t\t    \"Falling back to scanning...\\n\" if $? != 0;\n@@ -109,7 +106,6 @@ sub launch_watchman {\n \t\tclose $fh;\n \n \t\tprint \"/\\0\";\n-\t\teval { launch_watchman() };\n \t\texit 0;\n \t}\n \ndiff --git a/t/t7519/fsmonitor-watchman-v2 b/t/t7519/fsmonitor-watchman-v2\nindex 14ed0aa42d..368604c278 100755\n--- a/t/t7519/fsmonitor-watchman-v2\n+++ b/t/t7519/fsmonitor-watchman-v2\n@@ -29,8 +29,6 @@ if ($version ne 2) {\n \n my $git_work_tree = get_working_dir();\n \n-my $retry = 1;\n-\n my $json_pkg;\n eval {\n \trequire JSON::XS;\n@@ -122,8 +120,7 @@ sub watchman_query {\n sub is_work_tree_watched {\n \tmy ($output) = @_;\n \tmy $error = $output->{error};\n-\tif ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n-\t\t$retry--;\n+\tif ($error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n \t\tmy $response = qx/watchman watch \"$git_work_tree\"/;\n \t\tdie \"Failed to make watchman watch '$git_work_tree'.\\n\" .\n \t\t    \"Falling back to scanning...\\n\" if $? != 0;\n@@ -141,15 +138,12 @@ sub is_work_tree_watched {\n \t\t# Watchman query just to get it over with now so we won't pay\n \t\t# the cost in git to look up each individual file.\n \t\tmy $o = watchman_clock();\n-\t\t$error = $output->{error};\n+\t\t$error = $o->{error};\n \n \t\tdie \"Watchman: $error.\\n\" .\n \t\t\"Falling back to scanning...\\n\" if $error;\n \n \t\toutput_result($o->{clock}, (\"/\"));\n-\t\t$last_update_token = $o->{clock};\n-\n-\t\teval { launch_watchman() };\n \t\treturn 0;\n \t}\n \ndiff --git a/templates/hooks/fsmonitor-watchman.sample b/templates/hooks/fsmonitor-watchman.sample\nindex 23e856f5de..429e0a51c1 100755\n--- a/templates/hooks/fsmonitor-watchman.sample\n+++ b/templates/hooks/fsmonitor-watchman.sample\n@@ -29,8 +29,6 @@ if ($version ne 2) {\n \n my $git_work_tree = get_working_dir();\n \n-my $retry = 1;\n-\n my $json_pkg;\n eval {\n \trequire JSON::XS;\n@@ -123,8 +121,7 @@ sub watchman_query {\n sub is_work_tree_watched {\n \tmy ($output) = @_;\n \tmy $error = $output->{error};\n-\tif ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n-\t\t$retry--;\n+\tif ($error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {\n \t\tmy $response = qx/watchman watch \"$git_work_tree\"/;\n \t\tdie \"Failed to make watchman watch '$git_work_tree'.\\n\" .\n \t\t    \"Falling back to scanning...\\n\" if $? != 0;\n@@ -142,15 +139,12 @@ sub is_work_tree_watched {\n \t\t# Watchman query just to get it over with now so we won't pay\n \t\t# the cost in git to look up each individual file.\n \t\tmy $o = watchman_clock();\n-\t\t$error = $output->{error};\n+\t\t$error = $o->{error};\n \n \t\tdie \"Watchman: $error.\\n\" .\n \t\t\"Falling back to scanning...\\n\" if $error;\n \n \t\toutput_result($o->{clock}, (\"/\"));\n-\t\t$last_update_token = $o->{clock};\n-\n-\t\teval { launch_watchman() };\n \t\treturn 0;\n \t}\n \n\nbase-commit: 68cb7f9e92a5d8e9824f5b52ac3d0a9d8f653dbe\n-- \ngitgitgadget\n"}]}