{"thread":{"id":"57542","subject":"[PATCH 01/16] t/test-lib: avoid using git on LHS of pipe","startedAt":"2022-03-11T22:28:26Z","lastAt":"2022-03-21T19:26:20Z","messageCount":32,"participants":["Jeff Hostetler via GitGitGadget","Junio C Hamano","Ævar Arnfjörð Bjarmason","Derrick Stolee","Jeff Hostetler"],"isPatch":true,"patchVersion":1,"patchTotal":16},"messages":[{"id":"451163","messageId":"6750cc17bc439c14e752606fbb7271086a802eaf.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 01/16] t/test-lib: avoid using git on LHS of pipe","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:48Z","receivedAt":"2022-03-11T22:28:26Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! help: include fsmonitor--daemon feature flag in version info\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/test-lib.sh | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex 46cd596e7f5..5d819c1bc11 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -1803,5 +1803,6 @@ GIT_TEST_MAINT_SCHEDULER=\"none:exit 1\"\n # Does this platform support `git fsmonitor--daemon`\n #\n test_lazy_prereq FSMONITOR_DAEMON '\n-\tgit version --build-options | grep \"feature:\" | grep \"fsmonitor--daemon\"\n+\tgit version --build-options >output &&\n+\tgrep \"feature: fsmonitor--daemon\" output\n '\n-- \ngitgitgadget\n\n"},{"id":"451164","messageId":"84df95be620c76afed73d1679722459e2ff32018.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 05/16] fsmonitor--daemon: refactor cookie handling for readability","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:52Z","receivedAt":"2022-03-11T22:43:04Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! fsmonitor--daemon: use a cookie file to sync with file system\n\nUse implicit definitions for FCIR_ enum values.\n\nRemove const from cookie->name.\n\nReverse if then and else branches around open() to ease readability.\n\nDocument that we don't care about errors from close() and unlink().\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n builtin/fsmonitor--daemon.c | 53 +++++++++++++++++++++----------------\n 1 file changed, 30 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c\nindex 97ca2a356e5..02a99ce98a2 100644\n--- a/builtin/fsmonitor--daemon.c\n+++ b/builtin/fsmonitor--daemon.c\n@@ -109,14 +109,14 @@ static int do_as_client__status(void)\n \n enum fsmonitor_cookie_item_result {\n \tFCIR_ERROR = -1, /* could not create cookie file ? */\n-\tFCIR_INIT = 0,\n+\tFCIR_INIT,\n \tFCIR_SEEN,\n \tFCIR_ABORT,\n };\n \n struct fsmonitor_cookie_item {\n \tstruct hashmap_entry entry;\n-\tconst char *name;\n+\tchar *name;\n \tenum fsmonitor_cookie_item_result result;\n };\n \n@@ -166,37 +166,44 @@ static enum fsmonitor_cookie_item_result with_lock__wait_for_cookie(\n \t * that the listener thread has seen it.\n \t */\n \tfd = open(cookie_pathname.buf, O_WRONLY | O_CREAT | O_EXCL, 0600);\n-\tif (fd >= 0) {\n-\t\tclose(fd);\n-\t\tunlink(cookie_pathname.buf);\n-\n-\t\t/*\n-\t\t * Technically, this is an infinite wait (well, unless another\n-\t\t * thread sends us an abort).  I'd like to change this to\n-\t\t * use `pthread_cond_timedwait()` and return an error/timeout\n-\t\t * and let the caller do the trivial response thing, but we\n-\t\t * don't have that routine in our thread-utils.\n-\t\t *\n-\t\t * After extensive beta testing I'm not really worried about\n-\t\t * this.  Also note that the above open() and unlink() calls\n-\t\t * will cause at least two FS events on that path, so the odds\n-\t\t * of getting stuck are pretty slim.\n-\t\t */\n-\t\twhile (cookie->result == FCIR_INIT)\n-\t\t\tpthread_cond_wait(&state->cookies_cond,\n-\t\t\t\t\t  &state->main_lock);\n-\t} else {\n+\tif (fd < 0) {\n \t\terror_errno(_(\"could not create fsmonitor cookie '%s'\"),\n \t\t\t    cookie->name);\n \n \t\tcookie->result = FCIR_ERROR;\n+\t\tgoto done;\n \t}\n \n+\t/*\n+\t * Technically, close() and unlink() can fail, but we don't\n+\t * care here.  We only created the file to trigger a watch\n+\t * event from the FS to know that when we're up to date.\n+\t */\n+\tclose(fd);\n+\tunlink(cookie_pathname.buf);\n+\n+\t/*\n+\t * Technically, this is an infinite wait (well, unless another\n+\t * thread sends us an abort).  I'd like to change this to\n+\t * use `pthread_cond_timedwait()` and return an error/timeout\n+\t * and let the caller do the trivial response thing, but we\n+\t * don't have that routine in our thread-utils.\n+\t *\n+\t * After extensive beta testing I'm not really worried about\n+\t * this.  Also note that the above open() and unlink() calls\n+\t * will cause at least two FS events on that path, so the odds\n+\t * of getting stuck are pretty slim.\n+\t */\n+\twhile (cookie->result == FCIR_INIT)\n+\t\tpthread_cond_wait(&state->cookies_cond,\n+\t\t\t\t  &state->main_lock);\n+\n+done:\n \thashmap_remove(&state->cookies, &cookie->entry, NULL);\n \n \tresult = cookie->result;\n \n-\tfree((char*)cookie->name);\n+\tfree(cookie->name);\n \tfree(cookie);\n \tstrbuf_release(&cookie_pathname);\n \n-- \ngitgitgadget\n\n"},{"id":"451166","messageId":"b120972a441d3081519af0e31bb0c639df148287.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 02/16] update-index: convert advise() messages back to warning()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:49Z","receivedAt":"2022-03-11T22:44:13Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! update-index: convert fsmonitor warnings to advise\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n builtin/update-index.c | 12 ++++++------\n 1 file changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex d335f1ac72a..75d646377cc 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1238,18 +1238,18 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tif (fsmonitor > 0) {\n \t\tenum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);\n \t\tif (fsm_mode == FSMONITOR_MODE_DISABLED) {\n-\t\t\tadvise(_(\"core.fsmonitor is unset; \"\n-\t\t\t\t \"set it if you really want to \"\n-\t\t\t\t \"enable fsmonitor\"));\n+\t\t\twarning(_(\"core.fsmonitor is unset; \"\n+\t\t\t\t  \"set it if you really want to \"\n+\t\t\t\t  \"enable fsmonitor\"));\n \t\t}\n \t\tadd_fsmonitor(&the_index);\n \t\treport(_(\"fsmonitor enabled\"));\n \t} else if (!fsmonitor) {\n \t\tenum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);\n \t\tif (fsm_mode > FSMONITOR_MODE_DISABLED)\n-\t\t\tadvise(_(\"core.fsmonitor is set; \"\n-\t\t\t\t \"remove it if you really want to \"\n-\t\t\t\t \"disable fsmonitor\"));\n+\t\t\twarning(_(\"core.fsmonitor is set; \"\n+\t\t\t\t  \"remove it if you really want to \"\n+\t\t\t\t  \"disable fsmonitor\"));\n \t\tremove_fsmonitor(&the_index);\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n-- \ngitgitgadget\n\n"},{"id":"451167","messageId":"68bdb635c877be7b1493ba91940b0a78e342e773.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 10/16] t7527: delete unused verify_status() function","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:57Z","receivedAt":"2022-03-11T22:44:43Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! t7527: create test for fsmonitor--daemon\n\nRemove unused function verify_status().\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/t7527-builtin-fsmonitor.sh | 10 ----------\n 1 file changed, 10 deletions(-)\n\ndiff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh\nindex f60e211dbab..ef8777e7f6d 100755\n--- a/t/t7527-builtin-fsmonitor.sh\n+++ b/t/t7527-builtin-fsmonitor.sh\n@@ -303,16 +303,6 @@ directory_to_file () {\n \techo 1 >dir1\n }\n \n-verify_status () {\n-\tgit status >actual &&\n-\tGIT_INDEX_FILE=.git/fresh-index git read-tree master &&\n-\tGIT_INDEX_FILE=.git/fresh-index git -c core.fsmonitor=false status >expect &&\n-\ttest_cmp expect actual &&\n-\techo HELLO AFTER &&\n-\tcat .git/trace &&\n-\techo HELLO AFTER\n-}\n-\n # The next few test cases confirm that our fsmonitor daemon sees each type\n # of OS filesystem notification that we care about.  At this layer we just\n # ensure we are getting the OS notifications and do not try to confirm what\n-- \ngitgitgadget\n\n"},{"id":"451168","messageId":"d9592c7a0b798d0b5ab60580afbe36cd48d12616.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 11/16] fsmonitor-ipc: add _() to calls to die()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:58Z","receivedAt":"2022-03-11T22:46:34Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! fsmonitor-ipc: create client routines for git-fsmonitor--daemon\n\nFix translation markings.\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n fsmonitor-ipc.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c\nindex 91a535f1219..789e7397baa 100644\n--- a/fsmonitor-ipc.c\n+++ b/fsmonitor-ipc.c\n@@ -152,7 +152,7 @@ int fsmonitor_ipc__send_command(const char *command,\n \tstate = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options,\n \t\t\t\t       &connection);\n \tif (state != IPC_STATE__LISTENING) {\n-\t\tdie(\"fsmonitor--daemon is not running\");\n+\t\tdie(_(\"fsmonitor--daemon is not running\"));\n \t\treturn -1;\n \t}\n \n@@ -161,7 +161,7 @@ int fsmonitor_ipc__send_command(const char *command,\n \tipc_client_close_connection(connection);\n \n \tif (ret == -1) {\n-\t\tdie(\"could not send '%s' command to fsmonitor--daemon\", c);\n+\t\tdie(_(\"could not send '%s' command to fsmonitor--daemon\"), c);\n \t\treturn -1;\n \t}\n \n-- \ngitgitgadget\n\n"},{"id":"451169","messageId":"118ba1b5d04283da93b46f24201827c4a226d3fa.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 15/16] fsmonitor--daemon: add _() to calls to error()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:15:02Z","receivedAt":"2022-03-11T22:47:45Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! fsmonitor--daemon: implement 'start' command\n\nFixup translation on die().\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n builtin/fsmonitor--daemon.c | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c\nindex b3687a200ef..a30ecf6cfac 100644\n--- a/builtin/fsmonitor--daemon.c\n+++ b/builtin/fsmonitor--daemon.c\n@@ -1381,7 +1381,7 @@ static int try_to_start_background_daemon(void)\n \t * immediately exited).\n \t */\n \tif (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)\n-\t\tdie(\"fsmonitor--daemon is already running '%s'\",\n+\t\tdie(_(\"fsmonitor--daemon is already running '%s'\"),\n \t\t    the_repository->worktree);\n \n \tif (fsmonitor__announce_startup) {\n@@ -1411,13 +1411,13 @@ static int try_to_start_background_daemon(void)\n \tdefault:\n \tcase SBGR_ERROR:\n \tcase SBGR_CB_ERROR:\n-\t\treturn error(\"daemon failed to start\");\n+\t\treturn error(_(\"daemon failed to start\"));\n \n \tcase SBGR_TIMEOUT:\n-\t\treturn error(\"daemon not online yet\");\n+\t\treturn error(_(\"daemon not online yet\"));\n \n \tcase SBGR_DIED:\n-\t\treturn error(\"daemon terminated\");\n+\t\treturn error(_(\"daemon terminated\"));\n \t}\n }\n \n-- \ngitgitgadget\n\n"},{"id":"451170","messageId":"pull.1174.git.1647033303.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":null,"subject":"[PATCH 00/16] Builtin FSMonitor Part 2.5","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:47Z","receivedAt":"2022-03-11T22:47:46Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"I'm calling this series part 2.5. It should be inserted between parts 2 and\n3. I'll send a new version of part 3 after I send part 2.5.\n\nThis series is a bunch of \"fixup!\" commits for part 2. It addresses feedback\non part 2 that wasn't received until after part 2 had graduated to \"next\".\n\nI was originally planning to include them at the beginning of part 3, but\nsince there are so many, I thought it would be easier to add a fixup series\nin the middle. (And since GGG has a limit of 30 commits, I couldn't add them\nto either existing series without going over the limit.)\n\nMost of the commits deal with translation markings for die/error messages\nand fixing && chains in the tests. And there were a few readability\nimprovements.\n\nJeff Hostetler (16):\n  t/test-lib: avoid using git on LHS of pipe\n  update-index: convert advise() messages back to warning()\n  compat/fsmonitor/fsm-listen-darwin: split out GCC-specific\n    declarations\n  t/helper/fsmonitor-client: cleanup call to parse_options()\n  fsmonitor--daemon: refactor cookie handling for readability\n  t/perf/p7519: use grep rather than egrep in test\n  t/perf/p7519: cleanup coding style\n  t7527: add parameters to start_daemon to handle args and subshell\n  t7527: fix && chaining in matrix_try()\n  t7527: delete unused verify_status() function\n  fsmonitor-ipc: add _() to calls to die()\n  compat/fsmonitor/fsm-listen-darwin: add _() to calls to error()\n  compat/fsmonitor/fsm-listen-win32: add _() to calls to error()\n  fsmonitor--daemon: add _() to calls to die()\n  fsmonitor--daemon: add _() to calls to error()\n  fsmonitor-settings: simplify initialization of settings data\n\n builtin/fsmonitor--daemon.c          |  63 ++++----\n builtin/update-index.c               |  12 +-\n compat/fsmonitor/fsm-darwin-gcc.h    |  92 +++++++++++\n compat/fsmonitor/fsm-listen-darwin.c |  95 +----------\n compat/fsmonitor/fsm-listen-win32.c  |   6 +-\n fsmonitor-ipc.c                      |   4 +-\n fsmonitor-settings.c                 |   3 +-\n t/helper/test-fsmonitor-client.c     |  17 +-\n t/perf/p7519-fsmonitor.sh            |  23 +--\n t/t7527-builtin-fsmonitor.sh         | 233 +++++++++++++--------------\n t/test-lib.sh                        |   3 +-\n 11 files changed, 276 insertions(+), 275 deletions(-)\n create mode 100644 compat/fsmonitor/fsm-darwin-gcc.h\n\n\nbase-commit: 1a9241e1fee9d418e436849853f031329e792192\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1174%2Fjeffhostetler%2Fbuiltin-fsmonitor-part2.5-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1174/jeffhostetler/builtin-fsmonitor-part2.5-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1174\n-- \ngitgitgadget\n"},{"id":"451171","messageId":"25fc4c993422cfcc1fcf7d4432828a8df1bb25bd.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 12/16] compat/fsmonitor/fsm-listen-darwin: add _() to calls to error()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:59Z","receivedAt":"2022-03-11T22:49:58Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! compat/fsmonitor/fsm-listen-darwin: implement FSEvent listener \\\non MacOS\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n compat/fsmonitor/fsm-listen-darwin.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c\nindex 9a73fb607d5..d9d0d0fa0e9 100644\n--- a/compat/fsmonitor/fsm-listen-darwin.c\n+++ b/compat/fsmonitor/fsm-listen-darwin.c\n@@ -335,7 +335,7 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state)\n \treturn 0;\n \n failed:\n-\terror(\"Unable to create FSEventStream.\");\n+\terror(_(\"Unable to create FSEventStream.\"));\n \n \tFREE_AND_NULL(state->backend_data);\n \treturn -1;\n@@ -383,7 +383,7 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state)\n \tdata->stream_scheduled = 1;\n \n \tif (!FSEventStreamStart(data->stream)) {\n-\t\terror(\"Failed to start the FSEventStream\");\n+\t\terror(_(\"Failed to start the FSEventStream\"));\n \t\tgoto force_error_stop_without_loop;\n \t}\n \tdata->stream_started = 1;\n-- \ngitgitgadget\n\n"},{"id":"451173","messageId":"2ddb702b330b1bdf7d81e006c5bbe3aee819c8be.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 03/16] compat/fsmonitor/fsm-listen-darwin: split out GCC-specific declarations","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:50Z","receivedAt":"2022-03-11T22:50:24Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! compat/fsmonitor/fsm-listen-darwin: add MacOS header files \\\nfor FSEvent\n\nSplit out GCC-specific MacOS declarations into separate file from\nthe clang-specific header file includes to reduce visual noise.\n\nEliminate unnecessary includes when using clang.\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n compat/fsmonitor/fsm-darwin-gcc.h    | 92 ++++++++++++++++++++++++++++\n compat/fsmonitor/fsm-listen-darwin.c | 91 +--------------------------\n 2 files changed, 93 insertions(+), 90 deletions(-)\n create mode 100644 compat/fsmonitor/fsm-darwin-gcc.h\n\ndiff --git a/compat/fsmonitor/fsm-darwin-gcc.h b/compat/fsmonitor/fsm-darwin-gcc.h\nnew file mode 100644\nindex 00000000000..1c75c3d48e7\n--- /dev/null\n+++ b/compat/fsmonitor/fsm-darwin-gcc.h\n@@ -0,0 +1,92 @@\n+#ifndef FSM_DARWIN_GCC_H\n+#define FSM_DARWIN_GCC_H\n+\n+#ifndef __clang__\n+/*\n+ * It is possible to #include CoreFoundation/CoreFoundation.h when compiling\n+ * with clang, but not with GCC as of time of writing.\n+ *\n+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93082 for details.\n+ */\n+typedef unsigned int FSEventStreamCreateFlags;\n+#define kFSEventStreamEventFlagNone               0x00000000\n+#define kFSEventStreamEventFlagMustScanSubDirs    0x00000001\n+#define kFSEventStreamEventFlagUserDropped        0x00000002\n+#define kFSEventStreamEventFlagKernelDropped      0x00000004\n+#define kFSEventStreamEventFlagEventIdsWrapped    0x00000008\n+#define kFSEventStreamEventFlagHistoryDone        0x00000010\n+#define kFSEventStreamEventFlagRootChanged        0x00000020\n+#define kFSEventStreamEventFlagMount              0x00000040\n+#define kFSEventStreamEventFlagUnmount            0x00000080\n+#define kFSEventStreamEventFlagItemCreated        0x00000100\n+#define kFSEventStreamEventFlagItemRemoved        0x00000200\n+#define kFSEventStreamEventFlagItemInodeMetaMod   0x00000400\n+#define kFSEventStreamEventFlagItemRenamed        0x00000800\n+#define kFSEventStreamEventFlagItemModified       0x00001000\n+#define kFSEventStreamEventFlagItemFinderInfoMod  0x00002000\n+#define kFSEventStreamEventFlagItemChangeOwner    0x00004000\n+#define kFSEventStreamEventFlagItemXattrMod       0x00008000\n+#define kFSEventStreamEventFlagItemIsFile         0x00010000\n+#define kFSEventStreamEventFlagItemIsDir          0x00020000\n+#define kFSEventStreamEventFlagItemIsSymlink      0x00040000\n+#define kFSEventStreamEventFlagOwnEvent           0x00080000\n+#define kFSEventStreamEventFlagItemIsHardlink     0x00100000\n+#define kFSEventStreamEventFlagItemIsLastHardlink 0x00200000\n+#define kFSEventStreamEventFlagItemCloned         0x00400000\n+\n+typedef struct __FSEventStream *FSEventStreamRef;\n+typedef const FSEventStreamRef ConstFSEventStreamRef;\n+\n+typedef unsigned int CFStringEncoding;\n+#define kCFStringEncodingUTF8 0x08000100\n+\n+typedef const struct __CFString *CFStringRef;\n+typedef const struct __CFArray *CFArrayRef;\n+typedef const struct __CFRunLoop *CFRunLoopRef;\n+\n+struct FSEventStreamContext {\n+    long long version;\n+    void *cb_data, *retain, *release, *copy_description;\n+};\n+\n+typedef struct FSEventStreamContext FSEventStreamContext;\n+typedef unsigned int FSEventStreamEventFlags;\n+#define kFSEventStreamCreateFlagNoDefer 0x02\n+#define kFSEventStreamCreateFlagWatchRoot 0x04\n+#define kFSEventStreamCreateFlagFileEvents 0x10\n+\n+typedef unsigned long long FSEventStreamEventId;\n+#define kFSEventStreamEventIdSinceNow 0xFFFFFFFFFFFFFFFFULL\n+\n+typedef void (*FSEventStreamCallback)(ConstFSEventStreamRef streamRef,\n+\t\t\t\t      void *context,\n+\t\t\t\t      __SIZE_TYPE__ num_of_events,\n+\t\t\t\t      void *event_paths,\n+\t\t\t\t      const FSEventStreamEventFlags event_flags[],\n+\t\t\t\t      const FSEventStreamEventId event_ids[]);\n+typedef double CFTimeInterval;\n+FSEventStreamRef FSEventStreamCreate(void *allocator,\n+\t\t\t\t     FSEventStreamCallback callback,\n+\t\t\t\t     FSEventStreamContext *context,\n+\t\t\t\t     CFArrayRef paths_to_watch,\n+\t\t\t\t     FSEventStreamEventId since_when,\n+\t\t\t\t     CFTimeInterval latency,\n+\t\t\t\t     FSEventStreamCreateFlags flags);\n+CFStringRef CFStringCreateWithCString(void *allocator, const char *string,\n+\t\t\t\t      CFStringEncoding encoding);\n+CFArrayRef CFArrayCreate(void *allocator, const void **items, long long count,\n+\t\t\t void *callbacks);\n+void CFRunLoopRun(void);\n+void CFRunLoopStop(CFRunLoopRef run_loop);\n+CFRunLoopRef CFRunLoopGetCurrent(void);\n+extern CFStringRef kCFRunLoopDefaultMode;\n+void FSEventStreamScheduleWithRunLoop(FSEventStreamRef stream,\n+\t\t\t\t      CFRunLoopRef run_loop,\n+\t\t\t\t      CFStringRef run_loop_mode);\n+unsigned char FSEventStreamStart(FSEventStreamRef stream);\n+void FSEventStreamStop(FSEventStreamRef stream);\n+void FSEventStreamInvalidate(FSEventStreamRef stream);\n+void FSEventStreamRelease(FSEventStreamRef stream);\n+\n+#endif /* !clang */\n+#endif /* FSM_DARWIN_GCC_H */\ndiff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c\nindex 5c5de1ae702..9a73fb607d5 100644\n--- a/compat/fsmonitor/fsm-listen-darwin.c\n+++ b/compat/fsmonitor/fsm-listen-darwin.c\n@@ -1,95 +1,6 @@\n #ifndef __clang__\n-/*\n- * It is possible to #include CoreFoundation/CoreFoundation.h when compiling\n- * with clang, but not with GCC as of time of writing.\n- *\n- * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93082 for details.\n- */\n-typedef unsigned int FSEventStreamCreateFlags;\n-#define kFSEventStreamEventFlagNone               0x00000000\n-#define kFSEventStreamEventFlagMustScanSubDirs    0x00000001\n-#define kFSEventStreamEventFlagUserDropped        0x00000002\n-#define kFSEventStreamEventFlagKernelDropped      0x00000004\n-#define kFSEventStreamEventFlagEventIdsWrapped    0x00000008\n-#define kFSEventStreamEventFlagHistoryDone        0x00000010\n-#define kFSEventStreamEventFlagRootChanged        0x00000020\n-#define kFSEventStreamEventFlagMount              0x00000040\n-#define kFSEventStreamEventFlagUnmount            0x00000080\n-#define kFSEventStreamEventFlagItemCreated        0x00000100\n-#define kFSEventStreamEventFlagItemRemoved        0x00000200\n-#define kFSEventStreamEventFlagItemInodeMetaMod   0x00000400\n-#define kFSEventStreamEventFlagItemRenamed        0x00000800\n-#define kFSEventStreamEventFlagItemModified       0x00001000\n-#define kFSEventStreamEventFlagItemFinderInfoMod  0x00002000\n-#define kFSEventStreamEventFlagItemChangeOwner    0x00004000\n-#define kFSEventStreamEventFlagItemXattrMod       0x00008000\n-#define kFSEventStreamEventFlagItemIsFile         0x00010000\n-#define kFSEventStreamEventFlagItemIsDir          0x00020000\n-#define kFSEventStreamEventFlagItemIsSymlink      0x00040000\n-#define kFSEventStreamEventFlagOwnEvent           0x00080000\n-#define kFSEventStreamEventFlagItemIsHardlink     0x00100000\n-#define kFSEventStreamEventFlagItemIsLastHardlink 0x00200000\n-#define kFSEventStreamEventFlagItemCloned         0x00400000\n-\n-typedef struct __FSEventStream *FSEventStreamRef;\n-typedef const FSEventStreamRef ConstFSEventStreamRef;\n-\n-typedef unsigned int CFStringEncoding;\n-#define kCFStringEncodingUTF8 0x08000100\n-\n-typedef const struct __CFString *CFStringRef;\n-typedef const struct __CFArray *CFArrayRef;\n-typedef const struct __CFRunLoop *CFRunLoopRef;\n-\n-struct FSEventStreamContext {\n-    long long version;\n-    void *cb_data, *retain, *release, *copy_description;\n-};\n-\n-typedef struct FSEventStreamContext FSEventStreamContext;\n-typedef unsigned int FSEventStreamEventFlags;\n-#define kFSEventStreamCreateFlagNoDefer 0x02\n-#define kFSEventStreamCreateFlagWatchRoot 0x04\n-#define kFSEventStreamCreateFlagFileEvents 0x10\n-\n-typedef unsigned long long FSEventStreamEventId;\n-#define kFSEventStreamEventIdSinceNow 0xFFFFFFFFFFFFFFFFULL\n-\n-typedef void (*FSEventStreamCallback)(ConstFSEventStreamRef streamRef,\n-\t\t\t\t      void *context,\n-\t\t\t\t      __SIZE_TYPE__ num_of_events,\n-\t\t\t\t      void *event_paths,\n-\t\t\t\t      const FSEventStreamEventFlags event_flags[],\n-\t\t\t\t      const FSEventStreamEventId event_ids[]);\n-typedef double CFTimeInterval;\n-FSEventStreamRef FSEventStreamCreate(void *allocator,\n-\t\t\t\t     FSEventStreamCallback callback,\n-\t\t\t\t     FSEventStreamContext *context,\n-\t\t\t\t     CFArrayRef paths_to_watch,\n-\t\t\t\t     FSEventStreamEventId since_when,\n-\t\t\t\t     CFTimeInterval latency,\n-\t\t\t\t     FSEventStreamCreateFlags flags);\n-CFStringRef CFStringCreateWithCString(void *allocator, const char *string,\n-\t\t\t\t      CFStringEncoding encoding);\n-CFArrayRef CFArrayCreate(void *allocator, const void **items, long long count,\n-\t\t\t void *callbacks);\n-void CFRunLoopRun(void);\n-void CFRunLoopStop(CFRunLoopRef run_loop);\n-CFRunLoopRef CFRunLoopGetCurrent(void);\n-extern CFStringRef kCFRunLoopDefaultMode;\n-void FSEventStreamScheduleWithRunLoop(FSEventStreamRef stream,\n-\t\t\t\t      CFRunLoopRef run_loop,\n-\t\t\t\t      CFStringRef run_loop_mode);\n-unsigned char FSEventStreamStart(FSEventStreamRef stream);\n-void FSEventStreamStop(FSEventStreamRef stream);\n-void FSEventStreamInvalidate(FSEventStreamRef stream);\n-void FSEventStreamRelease(FSEventStreamRef stream);\n+#include \"fsm-darwin-gcc.h\"\n #else\n-/*\n- * Let Apple's headers declare `isalnum()` first, before\n- * Git's headers override it via a constant\n- */\n-#include <string.h>\n #include <CoreFoundation/CoreFoundation.h>\n #include <CoreServices/CoreServices.h>\n #endif\n-- \ngitgitgadget\n\n"},{"id":"451175","messageId":"edd4af7333a479e5c92b1cfc13311ad974297857.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 06/16] t/perf/p7519: use grep rather than egrep in test","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:53Z","receivedAt":"2022-03-11T22:51:45Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! t/perf/p7519: speed up test on Windows\n\nUse grep rather than egrep\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/perf/p7519-fsmonitor.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh\nindex a1c552129cc..5f97edf6a11 100755\n--- a/t/perf/p7519-fsmonitor.sh\n+++ b/t/perf/p7519-fsmonitor.sh\n@@ -218,7 +218,7 @@ test_fsmonitor_suite () {\n \t\tgit ls-files | \\\n \t\t\thead -100000 | \\\n \t\t\tgrep -v \\\" | \\\n-\t\t\tegrep -v \" .\" | \\\n+\t\t\tgrep -v \" .\" | \\\n \t\t\txargs test-tool chmtime -300 &&\n \t\tgit status\n \t'\n-- \ngitgitgadget\n\n"},{"id":"451176","messageId":"3482fb79a517d4703b5aa888a8c3d4890d034cf7.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 07/16] t/perf/p7519: cleanup coding style","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:54Z","receivedAt":"2022-03-11T22:52:39Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! t/perf/p7519: add fsmonitor--daemon test cases\n\nAdd \"_hook\" to name of shell function to set up for Watchman/hook test runs.\n\nFix code style of added \"if then\".\n\nAdd body of builtin test to a test_expect_success.\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/perf/p7519-fsmonitor.sh | 21 +++++++++++----------\n 1 file changed, 11 insertions(+), 10 deletions(-)\n\ndiff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh\nindex 5f97edf6a11..7a7981b0e61 100755\n--- a/t/perf/p7519-fsmonitor.sh\n+++ b/t/perf/p7519-fsmonitor.sh\n@@ -141,7 +141,7 @@ test_expect_success \"one time repo setup\" '\n \tfi\n '\n \n-setup_for_fsmonitor () {\n+setup_for_fsmonitor_hook () {\n \t# set INTEGRATION_SCRIPT depending on the environment\n \tif test -n \"$INTEGRATION_PATH\"\n \tthen\n@@ -182,8 +182,7 @@ test_perf_w_drop_caches () {\n }\n \n test_fsmonitor_suite () {\n-\tif test -n \"$USE_FSMONITOR_DAEMON\"\n-\tthen\n+\tif test -n \"$USE_FSMONITOR_DAEMON\"; then\n \t\tDESC=\"builtin fsmonitor--daemon\"\n \telif test -n \"$INTEGRATION_SCRIPT\"; then\n \t\tDESC=\"fsmonitor=$(basename $INTEGRATION_SCRIPT)\"\n@@ -264,11 +263,11 @@ test_fsmonitor_suite () {\n trace_start fsmonitor-watchman\n if test -n \"$GIT_PERF_7519_FSMONITOR\"; then\n \tfor INTEGRATION_PATH in $GIT_PERF_7519_FSMONITOR; do\n-\t\ttest_expect_success \"setup for fsmonitor $INTEGRATION_PATH\" 'setup_for_fsmonitor'\n+\t\ttest_expect_success \"setup for fsmonitor $INTEGRATION_PATH\" 'setup_for_fsmonitor_hook'\n \t\ttest_fsmonitor_suite\n \tdone\n else\n-\ttest_expect_success \"setup for fsmonitor\" 'setup_for_fsmonitor'\n+\ttest_expect_success \"setup for fsmonitor hook\" 'setup_for_fsmonitor_hook'\n \ttest_fsmonitor_suite\n fi\n \n@@ -306,13 +305,15 @@ if test_have_prereq FSMONITOR_DAEMON\n then\n \tUSE_FSMONITOR_DAEMON=t\n \n-\ttrace_start fsmonitor--daemon--server\n-\tgit fsmonitor--daemon start\n+\ttest_expect_success \"setup for builtin fsmonitor\" '\n+\t\ttrace_start fsmonitor--daemon--server &&\n+\t\tgit fsmonitor--daemon start &&\n \n-\ttrace_start fsmonitor--daemon--client\n+\t\ttrace_start fsmonitor--daemon--client &&\n \n-\tgit config core.fsmonitor true\n-\tgit update-index --fsmonitor\n+\t\tgit config core.fsmonitor true &&\n+\t\tgit update-index --fsmonitor\n+\t'\n \n \ttest_fsmonitor_suite\n \n-- \ngitgitgadget\n\n"},{"id":"451177","messageId":"378c5ca510ce4029df6caf83740c582a93008612.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 14/16] fsmonitor--daemon: add _() to calls to die()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:15:01Z","receivedAt":"2022-03-11T22:53:41Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! fsmonitor--daemon: implement 'run' command\n\nFix translation marking on die().\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n builtin/fsmonitor--daemon.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c\nindex 02a99ce98a2..b3687a200ef 100644\n--- a/builtin/fsmonitor--daemon.c\n+++ b/builtin/fsmonitor--daemon.c\n@@ -1326,7 +1326,7 @@ static int try_to_run_foreground_daemon(int detach_console)\n \t * common error case.\n \t */\n \tif (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)\n-\t\tdie(\"fsmonitor--daemon is already running '%s'\",\n+\t\tdie(_(\"fsmonitor--daemon is already running '%s'\"),\n \t\t    the_repository->worktree);\n \n \tif (fsmonitor__announce_startup) {\n-- \ngitgitgadget\n\n"},{"id":"451178","messageId":"903643c449821f24d80c999b50031945c79a0a7e.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 09/16] t7527: fix && chaining in matrix_try()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:56Z","receivedAt":"2022-03-11T22:53:43Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! t7527: test status with untracked-cache and fsmonitor--daemon\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/t7527-builtin-fsmonitor.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh\nindex 026382a0d86..f60e211dbab 100755\n--- a/t/t7527-builtin-fsmonitor.sh\n+++ b/t/t7527-builtin-fsmonitor.sh\n@@ -536,9 +536,9 @@ matrix_clean_up_repo () {\n }\n \n matrix_try () {\n-\tuc=$1\n-\tfsm=$2\n-\tfn=$3\n+\tuc=$1 &&\n+\tfsm=$2 &&\n+\tfn=$3 &&\n \n \ttest_expect_success \"Matrix[uc:$uc][fsm:$fsm] $fn\" '\n \t\tmatrix_clean_up_repo &&\n-- \ngitgitgadget\n\n"},{"id":"451180","messageId":"6693900600f5b27525dfe7de78e73900306e0ab5.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 08/16] t7527: add parameters to start_daemon to handle args and subshell","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:55Z","receivedAt":"2022-03-11T22:59:25Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! t7527: create test for fsmonitor--daemon\n\nAdd parameters to start_daemon() and handle subshell and logging args.\n\nRemove /dev/null from commands.\n\nFix &&-chaining of functions.\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/t7527-builtin-fsmonitor.sh | 217 ++++++++++++++++++-----------------\n 1 file changed, 111 insertions(+), 106 deletions(-)\n\ndiff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh\nindex 0ccbfb9616f..026382a0d86 100755\n--- a/t/t7527-builtin-fsmonitor.sh\n+++ b/t/t7527-builtin-fsmonitor.sh\n@@ -11,30 +11,85 @@ then\n fi\n \n stop_daemon_delete_repo () {\n-\tr=$1\n-\tgit -C $r fsmonitor--daemon stop >/dev/null 2>/dev/null\n+\tr=$1 &&\n+\ttest_might_fail git -C $r fsmonitor--daemon stop &&\n \trm -rf $1\n-\treturn 0\n }\n \n start_daemon () {\n-\tcase \"$#\" in\n-\t\t1) r=\"-C $1\";;\n-\t\t*) r=\"\";\n-\tesac\n+\tr=\"\" &&\n+\ttf=\"\" &&\n+\tt2=\"\" &&\n+\ttk=\"\" &&\n \n-\tgit $r fsmonitor--daemon start || return $?\n-\tgit $r fsmonitor--daemon status || return $?\n+\twhile test \"$#\" -ne 0\n+\tdo\n+\t\tcase \"$1\" in\n+\t\t-C)\n+\t\t\tshift;\n+\t\t\ttest \"$#\" -ne 0 ||\n+\t\t\t\t{ echo >&2 \"error: -C requires arg\"; exit 1; }\n+\t\t\tr=\"-C $1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t-tf)\n+\t\t\tshift;\n+\t\t\ttest \"$#\" -ne 0 ||\n+\t\t\t\t{ echo >&2 \"error: -tf requires arg\"; exit 1; }\n+\t\t\ttf=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t-t2)\n+\t\t\tshift;\n+\t\t\ttest \"$#\" -ne 0 ||\n+\t\t\t\t{ echo >&2 \"error: -t2 requires arg\"; exit 1; }\n+\t\t\tt2=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t-tk)\n+\t\t\tshift;\n+\t\t\ttest \"$#\" -ne 0 ||\n+\t\t\t\t{ echo >&2 \"error: -tk requires arg\"; exit 1; }\n+\t\t\ttk=\"$1\"\n+\t\t\tshift\n+\t\t\t;;\n+\t\t*)\n+\t\t\techo >&2 \"error: unknown option: '$1'\"\n+\t\t\texit 1\n+\t\t\t;;\n+\t\tesac\n+\tdone &&\n+\n+\t(\n+\t\tif test ! -z \"$tf\"\n+\t\tthen\n+\t\t\tGIT_TRACE_FSMONITOR=\"$tf\"\n+\t\t\texport GIT_TRACE_FSMONITOR\n+\t\tfi &&\n+\n+\t\tif test ! -z \"$t2\"\n+\t\tthen\n+\t\t\tGIT_TRACE2_PERF=\"$t2\"\n+\t\t\texport GIT_TRACE2_PERF\n+\t\tfi &&\n+\n+\t\tif test ! -z \"$tk\"\n+\t\tthen\n+\t\t\tGIT_TEST_FSMONITOR_TOKEN=\"$tk\"\n+\t\t\texport GIT_TEST_FSMONITOR_TOKEN\n+\t\tfi &&\n \n-\treturn 0\n+\t\tgit $r fsmonitor--daemon start &&\n+\t\tgit $r fsmonitor--daemon status\n+\t)\n }\n \n # Is a Trace2 data event present with the given catetory and key?\n # We do not care what the value is.\n #\n have_t2_data_event () {\n-\tc=$1\n-\tk=$2\n+\tc=$1 &&\n+\tk=$2 &&\n \n \tgrep -e '\"event\":\"data\".*\"category\":\"'\"$c\"'\".*\"key\":\"'\"$k\"'\"'\n }\n@@ -43,7 +98,7 @@ test_expect_success 'explicit daemon start and stop' '\n \ttest_when_finished \"stop_daemon_delete_repo test_explicit\" &&\n \n \tgit init test_explicit &&\n-\tstart_daemon test_explicit &&\n+\tstart_daemon -C test_explicit &&\n \n \tgit -C test_explicit fsmonitor--daemon stop &&\n \ttest_must_fail git -C test_explicit fsmonitor--daemon status\n@@ -63,7 +118,7 @@ test_expect_success 'implicit daemon start' '\n \t# but this test case is only concerned with whether the daemon was\n \t# implicitly started.)\n \n-\tGIT_TRACE2_EVENT=\"$(pwd)/.git/trace\" \\\n+\tGIT_TRACE2_EVENT=\"$PWD/.git/trace\" \\\n \t\ttest-tool -C test_implicit fsmonitor-client query --token 0 >actual &&\n \tnul_to_q <actual >actual.filtered &&\n \tgrep \"builtin:\" actual.filtered &&\n@@ -86,7 +141,7 @@ test_expect_success 'implicit daemon stop (delete .git)' '\n \n \tgit init test_implicit_1 &&\n \n-\tstart_daemon test_implicit_1 &&\n+\tstart_daemon -C test_implicit_1 &&\n \n \t# deleting the .git directory will implicitly stop the daemon.\n \trm -rf test_implicit_1/.git &&\n@@ -110,7 +165,7 @@ test_expect_success 'implicit daemon stop (rename .git)' '\n \n \tgit init test_implicit_2 &&\n \n-\tstart_daemon test_implicit_2 &&\n+\tstart_daemon -C test_implicit_2 &&\n \n \t# renaming the .git directory will implicitly stop the daemon.\n \tmv test_implicit_2/.git test_implicit_2/.xxx &&\n@@ -128,7 +183,7 @@ test_expect_success 'cannot start multiple daemons' '\n \n \tgit init test_multiple &&\n \n-\tstart_daemon test_multiple &&\n+\tstart_daemon -C test_multiple &&\n \n \ttest_must_fail git -C test_multiple fsmonitor--daemon start 2>actual &&\n \tgrep \"fsmonitor--daemon is already running\" actual &&\n@@ -177,8 +232,7 @@ test_expect_success 'setup' '\n # This is here in case something else fails first.\n #\n redundant_stop_daemon () {\n-\tgit fsmonitor--daemon stop\n-\treturn 0\n+\ttest_might_fail git fsmonitor--daemon stop\n }\n \n test_expect_success 'update-index implicitly starts daemon' '\n@@ -186,7 +240,7 @@ test_expect_success 'update-index implicitly starts daemon' '\n \n \ttest_must_fail git fsmonitor--daemon status &&\n \n-\tGIT_TRACE2_EVENT=\"$(pwd)/.git/trace_implicit_1\" \\\n+\tGIT_TRACE2_EVENT=\"$PWD/.git/trace_implicit_1\" \\\n \t\tgit update-index --fsmonitor &&\n \n \tgit fsmonitor--daemon status &&\n@@ -202,7 +256,7 @@ test_expect_success 'status implicitly starts daemon' '\n \n \ttest_must_fail git fsmonitor--daemon status &&\n \n-\tGIT_TRACE2_EVENT=\"$(pwd)/.git/trace_implicit_2\" \\\n+\tGIT_TRACE2_EVENT=\"$PWD/.git/trace_implicit_2\" \\\n \t\tgit status >actual &&\n \n \tgit fsmonitor--daemon status &&\n@@ -214,38 +268,38 @@ test_expect_success 'status implicitly starts daemon' '\n '\n \n edit_files () {\n-\techo 1 >modified\n-\techo 2 >dir1/modified\n-\techo 3 >dir2/modified\n+\techo 1 >modified &&\n+\techo 2 >dir1/modified &&\n+\techo 3 >dir2/modified &&\n \t>dir1/untracked\n }\n \n delete_files () {\n-\trm -f delete\n-\trm -f dir1/delete\n+\trm -f delete &&\n+\trm -f dir1/delete &&\n \trm -f dir2/delete\n }\n \n create_files () {\n-\techo 1 >new\n-\techo 2 >dir1/new\n+\techo 1 >new &&\n+\techo 2 >dir1/new &&\n \techo 3 >dir2/new\n }\n \n rename_files () {\n-\tmv rename renamed\n-\tmv dir1/rename dir1/renamed\n+\tmv rename renamed &&\n+\tmv dir1/rename dir1/renamed &&\n \tmv dir2/rename dir2/renamed\n }\n \n file_to_directory () {\n-\trm -f delete\n-\tmkdir delete\n+\trm -f delete &&\n+\tmkdir delete &&\n \techo 1 >delete/new\n }\n \n directory_to_file () {\n-\trm -rf dir1\n+\trm -rf dir1 &&\n \techo 1 >dir1\n }\n \n@@ -272,25 +326,20 @@ verify_status () {\n # daemon) because these commands might implicitly restart the daemon.\n \n clean_up_repo_and_stop_daemon () {\n-\tgit reset --hard HEAD\n-\tgit clean -fd\n-\tgit fsmonitor--daemon stop\n+\tgit reset --hard HEAD &&\n+\tgit clean -fd &&\n+\ttest_might_fail git fsmonitor--daemon stop &&\n \trm -f .git/trace\n }\n \n test_expect_success 'edit some files' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \tedit_files &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: dir1/modified$\"  .git/trace &&\n \tgrep \"^event: dir2/modified$\"  .git/trace &&\n@@ -301,16 +350,11 @@ test_expect_success 'edit some files' '\n test_expect_success 'create some files' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \tcreate_files &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: dir1/new$\" .git/trace &&\n \tgrep \"^event: dir2/new$\" .git/trace &&\n@@ -320,16 +364,11 @@ test_expect_success 'create some files' '\n test_expect_success 'delete some files' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \tdelete_files &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: dir1/delete$\" .git/trace &&\n \tgrep \"^event: dir2/delete$\" .git/trace &&\n@@ -339,16 +378,11 @@ test_expect_success 'delete some files' '\n test_expect_success 'rename some files' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \trename_files &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: dir1/rename$\"  .git/trace &&\n \tgrep \"^event: dir2/rename$\"  .git/trace &&\n@@ -361,16 +395,11 @@ test_expect_success 'rename some files' '\n test_expect_success 'rename directory' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \tmv dirtorename dirrenamed &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: dirtorename/*$\" .git/trace &&\n \tgrep \"^event: dirrenamed/*$\"  .git/trace\n@@ -379,16 +408,11 @@ test_expect_success 'rename directory' '\n test_expect_success 'file changes to directory' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \tfile_to_directory &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: delete$\"     .git/trace &&\n \tgrep \"^event: delete/new$\" .git/trace\n@@ -397,16 +421,11 @@ test_expect_success 'file changes to directory' '\n test_expect_success 'directory changes to a file' '\n \ttest_when_finished clean_up_repo_and_stop_daemon &&\n \n-\t(\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon\n-\t) &&\n+\tstart_daemon -tf \"$PWD/.git/trace\" &&\n \n \tdirectory_to_file &&\n \n-\ttest-tool fsmonitor-client query --token 0 >/dev/null 2>&1 &&\n+\ttest-tool fsmonitor-client query --token 0 &&\n \n \tgrep \"^event: dir1$\" .git/trace\n '\n@@ -424,15 +443,7 @@ test_expect_success 'flush cached data' '\n \n \tgit init test_flush &&\n \n-\t(\n-\t\tGIT_TEST_FSMONITOR_TOKEN=true &&\n-\t\texport GIT_TEST_FSMONITOR_TOKEN &&\n-\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/.git/trace_daemon\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon test_flush\n-\t) &&\n+\tstart_daemon -C test_flush -tf \"$PWD/.git/trace_daemon\" -tk true &&\n \n \t# The daemon should have an initial token with no events in _0 and\n \t# then a few (probably platform-specific number of) events in _1.\n@@ -441,8 +452,8 @@ test_expect_success 'flush cached data' '\n \ttest-tool -C test_flush fsmonitor-client query --token \"builtin:test_00000001:0\" >actual_0 &&\n \tnul_to_q <actual_0 >actual_q0 &&\n \n-\ttouch test_flush/file_1 &&\n-\ttouch test_flush/file_2 &&\n+\t> test_flush/file_1 &&\n+\t> test_flush/file_2 &&\n \n \ttest-tool -C test_flush fsmonitor-client query --token \"builtin:test_00000001:0\" >actual_1 &&\n \tnul_to_q <actual_1 >actual_q1 &&\n@@ -462,7 +473,7 @@ test_expect_success 'flush cached data' '\n \n \tgrep \"^builtin:test_00000002:0Q$\" actual_q2 &&\n \n-\ttouch test_flush/file_3 &&\n+\t> test_flush/file_3 &&\n \n \ttest-tool -C test_flush fsmonitor-client query --token \"builtin:test_00000002:0\" >actual_3 &&\n \tnul_to_q <actual_3 >actual_q3 &&\n@@ -485,15 +496,9 @@ test_expect_success 'setup worktree base' '\n test_expect_success 'worktree with .git file' '\n \tgit -C wt-base worktree add ../wt-secondary &&\n \n-\t(\n-\t\tGIT_TRACE2_PERF=\"$(pwd)/trace2_wt_secondary\" &&\n-\t\texport GIT_TRACE2_PERF &&\n-\n-\t\tGIT_TRACE_FSMONITOR=\"$(pwd)/trace_wt_secondary\" &&\n-\t\texport GIT_TRACE_FSMONITOR &&\n-\n-\t\tstart_daemon wt-secondary\n-\t) &&\n+\tstart_daemon -C wt-secondary \\\n+\t\t-tf \"$PWD/trace_wt_secondary\" \\\n+\t\t-t2 \"$PWD/trace2_wt_secondary\" &&\n \n \tgit -C wt-secondary fsmonitor--daemon stop &&\n \ttest_must_fail git -C wt-secondary fsmonitor--daemon status\n-- \ngitgitgadget\n\n"},{"id":"451181","messageId":"578c3682e2fb35af86087e6a0c277aa8766919d7.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 04/16] t/helper/fsmonitor-client: cleanup call to parse_options()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:14:51Z","receivedAt":"2022-03-11T22:59:34Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! t/helper/fsmonitor-client: create IPC client to talk to \\\nFSMonitor Daemon\n\nElminate unnecessary code in cmd__fsmonitor_client() WRT\nparsing of options.\n\nFix name of test-tool in usage.\n\nDon't localize die() message.\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n t/helper/test-fsmonitor-client.c | 17 ++++++-----------\n 1 file changed, 6 insertions(+), 11 deletions(-)\n\ndiff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\nindex f7a5b3a32fa..d59a640f1f9 100644\n--- a/t/helper/test-fsmonitor-client.c\n+++ b/t/helper/test-fsmonitor-client.c\n@@ -49,7 +49,7 @@ static int do_send_query(const char *token)\n \n \tret = fsmonitor_ipc__send_query(token, &answer);\n \tif (ret < 0)\n-\t\tdie(_(\"could not query fsmonitor--daemon\"));\n+\t\tdie(\"could not query fsmonitor--daemon\");\n \n \twrite_in_full(1, answer.buf, answer.len);\n \tstrbuf_release(&answer);\n@@ -85,8 +85,8 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n \tconst char *token = NULL;\n \n \tconst char * const fsmonitor_client_usage[] = {\n-\t\tN_(\"test-helper fsmonitor-client query [<token>]\"),\n-\t\tN_(\"test-helper fsmonitor-client flush\"),\n+\t\tN_(\"test-tool fsmonitor-client query [<token>]\"),\n+\t\tN_(\"test-tool fsmonitor-client flush\"),\n \t\tNULL,\n \t};\n \n@@ -96,17 +96,12 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n \t\tOPT_END()\n \t};\n \n-\tif (argc < 2)\n-\t\tusage_with_options(fsmonitor_client_usage, options);\n+\targc = parse_options(argc, argv, NULL, options, fsmonitor_client_usage, 0);\n \n-\tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n+\tif (argc != 1)\n \t\tusage_with_options(fsmonitor_client_usage, options);\n \n-\tsubcmd = argv[1];\n-\targv--;\n-\targc++;\n-\n-\targc = parse_options(argc, argv, NULL, options, fsmonitor_client_usage, 0);\n+\tsubcmd = argv[0];\n \n \tsetup_git_directory();\n \n-- \ngitgitgadget\n\n"},{"id":"451186","messageId":"cc7c92f7760b93d2c6a45ce87ca2c9aafc57f20f.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 13/16] compat/fsmonitor/fsm-listen-win32: add _() to calls to error()","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:15:00Z","receivedAt":"2022-03-11T23:13:03Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! compat/fsmonitor/fsm-listen-win32: implement FSMonitor backend \\\non Windows\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n compat/fsmonitor/fsm-listen-win32.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/compat/fsmonitor/fsm-listen-win32.c b/compat/fsmonitor/fsm-listen-win32.c\nindex c2d11acbc1e..5b928ab66e5 100644\n--- a/compat/fsmonitor/fsm-listen-win32.c\n+++ b/compat/fsmonitor/fsm-listen-win32.c\n@@ -82,7 +82,7 @@ static int normalize_path_in_utf8(FILE_NOTIFY_INFORMATION *info,\n \t\tif (len > 0)\n \t\t\tgoto normalize;\n \t\tif (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {\n-\t\t\terror(\"[GLE %ld] could not convert path to UTF-8: '%.*ls'\",\n+\t\t\terror(_(\"[GLE %ld] could not convert path to UTF-8: '%.*ls'\"),\n \t\t\t      GetLastError(),\n \t\t\t      (int)(info->FileNameLength / sizeof(WCHAR)),\n \t\t\t      info->FileName);\n@@ -185,7 +185,7 @@ static int start_rdcw_watch(struct fsmonitor_daemon_backend_data *data,\n \tif (watch->is_active)\n \t\treturn 0;\n \n-\terror(\"ReadDirectoryChangedW failed on '%s' [GLE %ld]\",\n+\terror(_(\"ReadDirectoryChangedW failed on '%s' [GLE %ld]\"),\n \t      watch->path.buf, GetLastError());\n \treturn -1;\n }\n@@ -228,7 +228,7 @@ static int recv_rdcw_watch(struct one_watch *watch)\n \t * sure it is worth it.\n \t */\n \n-\terror(\"GetOverlappedResult failed on '%s' [GLE %ld]\",\n+\terror(_(\"GetOverlappedResult failed on '%s' [GLE %ld]\"),\n \t      watch->path.buf, gle);\n \treturn -1;\n }\n-- \ngitgitgadget\n\n"},{"id":"451194","messageId":"432f9ff9d92ff55216555864cb3571c94a2c6db9.1647033303.git.gitgitgadget@gmail.com","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"[PATCH 16/16] fsmonitor-settings: simplify initialization of settings data","fromName":"Jeff Hostetler via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-03-11T21:15:03Z","receivedAt":"2022-03-12T00:15:09Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"From: Jeff Hostetler <jeffhost@microsoft.com>\n\nfixup! fsmonitor: config settings are repository-specific\n\nSigned-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n---\n fsmonitor-settings.c | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/fsmonitor-settings.c b/fsmonitor-settings.c\nindex 3b54e7a51f6..757d230d538 100644\n--- a/fsmonitor-settings.c\n+++ b/fsmonitor-settings.c\n@@ -22,11 +22,10 @@ static void lookup_fsmonitor_settings(struct repository *r)\n \t\treturn;\n \n \tCALLOC_ARRAY(s, 1);\n+\ts->mode = FSMONITOR_MODE_DISABLED;\n \n \tr->settings.fsmonitor = s;\n \n-\tfsm_settings__set_disabled(r);\n-\n \t/*\n \t * Overload the existing \"core.fsmonitor\" config setting (which\n \t * has historically been either unset or a hook pathname) to\n-- \ngitgitgadget\n"},{"id":"451238","messageId":"xmqq35jmwa98.fsf@gitster.g","threadId":"57542","inReplyTo":"pull.1174.git.1647033303.gitgitgadget@gmail.com","subject":"Re: [PATCH 00/16] Builtin FSMonitor Part 2.5","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-13T08:02:27Z","receivedAt":"2022-03-13T08:02:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> I'm calling this series part 2.5. It should be inserted between parts 2 and\n> 3. I'll send a new version of part 3 after I send part 2.5.\n>\n> This series is a bunch of \"fixup!\" commits for part 2. It addresses feedback\n> on part 2 that wasn't received until after part 2 had graduated to \"next\".\n\nBetter late than never, but I am sensing that part 2 was\nunder-reviewed and we pushed it too hastily?\n\n> I was originally planning to include them at the beginning of part 3, but\n> since there are so many, I thought it would be easier to add a fixup series\n> in the middle.\n\nI think that is prudent.  Let's give part 3 (which ought to be more\ninteresting than part 2.5) a more solid ground to build upon, and to\nprepare for that, let's first avoid repeating the mistake of merging\na series in an under-reviewed state to 'next'.\n\nWill queue (but not tonight).\n\nThanks.\n\n"},{"id":"451281","messageId":"xmqqa6dtt6oo.fsf@gitster.g","threadId":"57542","inReplyTo":"6750cc17bc439c14e752606fbb7271086a802eaf.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 01/16] t/test-lib: avoid using git on LHS of pipe","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-14T06:00:07Z","receivedAt":"2022-03-14T06:00:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! help: include fsmonitor--daemon feature flag in version info\n\nDo you want me to kick part-2 out of 'next' so that these can be\nsquashed into the original commits that need fixing?  If not, you\nwould want to have a real commit log message instead.\n\nThe patch text looks good, even though I had to see if 'output' may\nclobber or collide with names used in tests that want the\nprerequisite.\n\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  t/test-lib.sh | 3 ++-\n>  1 file changed, 2 insertions(+), 1 deletion(-)\n>\n> diff --git a/t/test-lib.sh b/t/test-lib.sh\n> index 46cd596e7f5..5d819c1bc11 100644\n> --- a/t/test-lib.sh\n> +++ b/t/test-lib.sh\n> @@ -1803,5 +1803,6 @@ GIT_TEST_MAINT_SCHEDULER=\"none:exit 1\"\n>  # Does this platform support `git fsmonitor--daemon`\n>  #\n>  test_lazy_prereq FSMONITOR_DAEMON '\n> -\tgit version --build-options | grep \"feature:\" | grep \"fsmonitor--daemon\"\n> +\tgit version --build-options >output &&\n> +\tgrep \"feature: fsmonitor--daemon\" output\n>  '\n"},{"id":"451282","messageId":"xmqq5yoht6an.fsf@gitster.g","threadId":"57542","inReplyTo":"b120972a441d3081519af0e31bb0c639df148287.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 02/16] update-index: convert advise() messages back to warning()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-14T06:08:32Z","receivedAt":"2022-03-14T06:08:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! update-index: convert fsmonitor warnings to advise\n\nSame comment as 01/16 applies here.  \"convert ... back to ...\" in\nthe title refers to the fact that builtin-fsmonitor-part2 topic\nturned warning() into advise() without a good justification, I\nthink.  Flipping and flopping between warning and advise, without\ngiving any justification going either direction, is not a good move.\n\nI only have looked at one eighth of this part 2.5, but it starts to\nlook that ejecting part-2 and redoing it may result in a cleaner\ncode that is easier to understand, perhaps?  For example, instead of\napplying this patch, we can just get rid of 1a9241e1 (update-index:\nconvert fsmonitor warnings to advise, 2022-03-01).  As I read more,\nmy impression will certainly change, I would expect.  Let's see.\n\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  builtin/update-index.c | 12 ++++++------\n>  1 file changed, 6 insertions(+), 6 deletions(-)\n>\n> diff --git a/builtin/update-index.c b/builtin/update-index.c\n> index d335f1ac72a..75d646377cc 100644\n> --- a/builtin/update-index.c\n> +++ b/builtin/update-index.c\n> @@ -1238,18 +1238,18 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>  \tif (fsmonitor > 0) {\n>  \t\tenum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);\n>  \t\tif (fsm_mode == FSMONITOR_MODE_DISABLED) {\n> -\t\t\tadvise(_(\"core.fsmonitor is unset; \"\n> -\t\t\t\t \"set it if you really want to \"\n> -\t\t\t\t \"enable fsmonitor\"));\n> +\t\t\twarning(_(\"core.fsmonitor is unset; \"\n> +\t\t\t\t  \"set it if you really want to \"\n> +\t\t\t\t  \"enable fsmonitor\"));\n>  \t\t}\n>  \t\tadd_fsmonitor(&the_index);\n>  \t\treport(_(\"fsmonitor enabled\"));\n>  \t} else if (!fsmonitor) {\n>  \t\tenum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);\n>  \t\tif (fsm_mode > FSMONITOR_MODE_DISABLED)\n> -\t\t\tadvise(_(\"core.fsmonitor is set; \"\n> -\t\t\t\t \"remove it if you really want to \"\n> -\t\t\t\t \"disable fsmonitor\"));\n> +\t\t\twarning(_(\"core.fsmonitor is set; \"\n> +\t\t\t\t  \"remove it if you really want to \"\n> +\t\t\t\t  \"disable fsmonitor\"));\n>  \t\tremove_fsmonitor(&the_index);\n>  \t\treport(_(\"fsmonitor disabled\"));\n>  \t}\n"},{"id":"451283","messageId":"xmqq1qz5t5zp.fsf@gitster.g","threadId":"57542","inReplyTo":"903643c449821f24d80c999b50031945c79a0a7e.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 09/16] t7527: fix && chaining in matrix_try()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-14T06:15:06Z","receivedAt":"2022-03-14T06:15:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! t7527: test status with untracked-cache and fsmonitor--daemon\n>\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  t/t7527-builtin-fsmonitor.sh | 6 +++---\n>  1 file changed, 3 insertions(+), 3 deletions(-)\n>\n> diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh\n> index 026382a0d86..f60e211dbab 100755\n> --- a/t/t7527-builtin-fsmonitor.sh\n> +++ b/t/t7527-builtin-fsmonitor.sh\n> @@ -536,9 +536,9 @@ matrix_clean_up_repo () {\n>  }\n>  \n>  matrix_try () {\n> -\tuc=$1\n> -\tfsm=$2\n> -\tfn=$3\n> +\tuc=$1 &&\n> +\tfsm=$2 &&\n> +\tfn=$3 &&\n\nAfter seeing up to this step, I am reasonably well convinced that\nwhat we want is to kick the jh/builtin-fsmonitor-part2 topic back to\n'seen', and you send instead of part2.5 an updated part2, with\nrange-diff since the last round and this final iteration.  A change\nlike the above will be seen in the range-diff in the cover letter\nand most of them, like the above, will become trivial improvements,\nand then the result can hopefully be placed back in 'next' reasonably\nfast.\n\nOpinions?\n"},{"id":"451293","messageId":"220314.86fsnlezgv.gmgdl@evledraar.gmail.com","threadId":"57542","inReplyTo":"578c3682e2fb35af86087e6a0c277aa8766919d7.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 04/16] t/helper/fsmonitor-client: cleanup call to parse_options()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-14T07:58:53Z","receivedAt":"2022-03-14T08:05:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! t/helper/fsmonitor-client: create IPC client to talk to \\\n> FSMonitor Daemon\n>\n> Elminate unnecessary code in cmd__fsmonitor_client() WRT\n> parsing of options.\n>\n> Fix name of test-tool in usage.\n>\n> Don't localize die() message.\n>\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  t/helper/test-fsmonitor-client.c | 17 ++++++-----------\n>  1 file changed, 6 insertions(+), 11 deletions(-)\n>\n> diff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c\n> index f7a5b3a32fa..d59a640f1f9 100644\n> --- a/t/helper/test-fsmonitor-client.c\n> +++ b/t/helper/test-fsmonitor-client.c\n> @@ -49,7 +49,7 @@ static int do_send_query(const char *token)\n>  \n>  \tret = fsmonitor_ipc__send_query(token, &answer);\n>  \tif (ret < 0)\n> -\t\tdie(_(\"could not query fsmonitor--daemon\"));\n> +\t\tdie(\"could not query fsmonitor--daemon\");\n\nGood, since this is just a test helper.\n\n>  \twrite_in_full(1, answer.buf, answer.len);\n>  \tstrbuf_release(&answer);\n> @@ -85,8 +85,8 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n>  \tconst char *token = NULL;\n>  \n>  \tconst char * const fsmonitor_client_usage[] = {\n> -\t\tN_(\"test-helper fsmonitor-client query [<token>]\"),\n> -\t\tN_(\"test-helper fsmonitor-client flush\"),\n> +\t\tN_(\"test-tool fsmonitor-client query [<token>]\"),\n> +\t\tN_(\"test-tool fsmonitor-client flush\"),\n\nThese are still marked for N_() translation.\n\nEven if tehse were built-ins only the one containing <token> should have\nN_(), as the other one is a literal command whose translation won't\nchange.\n\n>  \t\tNULL,\n>  \t};\n>  \n> @@ -96,17 +96,12 @@ int cmd__fsmonitor_client(int argc, const char **argv)\n>  \t\tOPT_END()\n>  \t};\n>  \n> -\tif (argc < 2)\n> -\t\tusage_with_options(fsmonitor_client_usage, options);\n> +\targc = parse_options(argc, argv, NULL, options, fsmonitor_client_usage, 0);\n>  \n> -\tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n> +\tif (argc != 1)\n>  \t\tusage_with_options(fsmonitor_client_usage, options);\n>  \n> -\tsubcmd = argv[1];\n> -\targv--;\n> -\targc++;\n> -\n> -\targc = parse_options(argc, argv, NULL, options, fsmonitor_client_usage, 0);\n> +\tsubcmd = argv[0];\n>  \n>  \tsetup_git_directory();\n\nLooks good.\n"},{"id":"451294","messageId":"220314.867d8xezbc.gmgdl@evledraar.gmail.com","threadId":"57542","inReplyTo":"3482fb79a517d4703b5aa888a8c3d4890d034cf7.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 07/16] t/perf/p7519: cleanup coding style","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-14T08:01:48Z","receivedAt":"2022-03-14T08:05:26Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n\n> Fix code style of added \"if then\".\n\n*nod*\n\n> Add body of builtin test to a test_expect_success.\n>\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  t/perf/p7519-fsmonitor.sh | 21 +++++++++++----------\n>  1 file changed, 11 insertions(+), 10 deletions(-)\n>\n> diff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh\n> index 5f97edf6a11..7a7981b0e61 100755\n> --- a/t/perf/p7519-fsmonitor.sh\n> +++ b/t/perf/p7519-fsmonitor.sh\n> @@ -141,7 +141,7 @@ test_expect_success \"one time repo setup\" '\n>  \tfi\n>  '\n>  \n> -setup_for_fsmonitor () {\n> +setup_for_fsmonitor_hook () {\n>  \t# set INTEGRATION_SCRIPT depending on the environment\n>  \tif test -n \"$INTEGRATION_PATH\"\n>  \tthen\n> @@ -182,8 +182,7 @@ test_perf_w_drop_caches () {\n>  }\n>  \n>  test_fsmonitor_suite () {\n> -\tif test -n \"$USE_FSMONITOR_DAEMON\"\n> -\tthen\n> +\tif test -n \"$USE_FSMONITOR_DAEMON\"; then\n>  \t\tDESC=\"builtin fsmonitor--daemon\"\n\nThis \"; then\" etc. still uses the non-standard style (and this was added\nin aa072da617e (t/perf/p7519: add fsmonitor--daemon test cases,\n2022-03-01).\n"},{"id":"451295","messageId":"220314.86bky9ezdw.gmgdl@evledraar.gmail.com","threadId":"57542","inReplyTo":"84df95be620c76afed73d1679722459e2ff32018.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 05/16] fsmonitor--daemon: refactor cookie handling for readability","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-14T08:00:36Z","receivedAt":"2022-03-14T08:05:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! fsmonitor--daemon: use a cookie file to sync with file system\n>\n> Use implicit definitions for FCIR_ enum values.\n>\n> Remove const from cookie->name.\n>\n> Reverse if then and else branches around open() to ease readability.\n>\n> Document that we don't care about errors from close() and unlink().\n>\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  builtin/fsmonitor--daemon.c | 53 +++++++++++++++++++++----------------\n>  1 file changed, 30 insertions(+), 23 deletions(-)\n>\n> diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c\n> index 97ca2a356e5..02a99ce98a2 100644\n> --- a/builtin/fsmonitor--daemon.c\n> +++ b/builtin/fsmonitor--daemon.c\n> @@ -109,14 +109,14 @@ static int do_as_client__status(void)\n>  \n>  enum fsmonitor_cookie_item_result {\n>  \tFCIR_ERROR = -1, /* could not create cookie file ? */\n> -\tFCIR_INIT = 0,\n> +\tFCIR_INIT,\n>  \tFCIR_SEEN,\n>  \tFCIR_ABORT,\n>  };\n>  \n>  struct fsmonitor_cookie_item {\n>  \tstruct hashmap_entry entry;\n> -\tconst char *name;\n> +\tchar *name;\n>  \tenum fsmonitor_cookie_item_result result;\n>  };\n>  \n> @@ -166,37 +166,44 @@ static enum fsmonitor_cookie_item_result with_lock__wait_for_cookie(\n>  \t * that the listener thread has seen it.\n>  \t */\n>  \tfd = open(cookie_pathname.buf, O_WRONLY | O_CREAT | O_EXCL, 0600);\n> -\tif (fd >= 0) {\n> -\t\tclose(fd);\n> -\t\tunlink(cookie_pathname.buf);\n> -\n> -\t\t/*\n> -\t\t * Technically, this is an infinite wait (well, unless another\n> -\t\t * thread sends us an abort).  I'd like to change this to\n> -\t\t * use `pthread_cond_timedwait()` and return an error/timeout\n> -\t\t * and let the caller do the trivial response thing, but we\n> -\t\t * don't have that routine in our thread-utils.\n> -\t\t *\n> -\t\t * After extensive beta testing I'm not really worried about\n> -\t\t * this.  Also note that the above open() and unlink() calls\n> -\t\t * will cause at least two FS events on that path, so the odds\n> -\t\t * of getting stuck are pretty slim.\n> -\t\t */\n> -\t\twhile (cookie->result == FCIR_INIT)\n> -\t\t\tpthread_cond_wait(&state->cookies_cond,\n> -\t\t\t\t\t  &state->main_lock);\n> -\t} else {\n> +\tif (fd < 0) {\n>  \t\terror_errno(_(\"could not create fsmonitor cookie '%s'\"),\n>  \t\t\t    cookie->name);\n>  \n>  \t\tcookie->result = FCIR_ERROR;\n> +\t\tgoto done;\n>  \t}\n>  \n> +\t/*\n> +\t * Technically, close() and unlink() can fail, but we don't\n> +\t * care here.  We only created the file to trigger a watch\n> +\t * event from the FS to know that when we're up to date.\n> +\t */\n> +\tclose(fd);\n\nIt still seems odd to explicitly want to ignore close() return values.\n\nI realize that we do in (too many) existing places, but why wouldn't we\nwant to e.g. catch an I/O error here early?\n"},{"id":"451296","messageId":"220314.8635jlez4c.gmgdl@evledraar.gmail.com","threadId":"57542","inReplyTo":"6693900600f5b27525dfe7de78e73900306e0ab5.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 08/16] t7527: add parameters to start_daemon to handle args and subshell","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-03-14T08:03:36Z","receivedAt":"2022-03-14T08:07:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! t7527: create test for fsmonitor--daemon\n>\n> Add parameters to start_daemon() and handle subshell and logging args.\n>\n> Remove /dev/null from commands.\n>\n> Fix &&-chaining of functions.\n>\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  t/t7527-builtin-fsmonitor.sh | 217 ++++++++++++++++++-----------------\n>  1 file changed, 111 insertions(+), 106 deletions(-)\n>\n> diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh\n> index 0ccbfb9616f..026382a0d86 100755\n> --- a/t/t7527-builtin-fsmonitor.sh\n> +++ b/t/t7527-builtin-fsmonitor.sh\n> @@ -11,30 +11,85 @@ then\n>  fi\n>  \n>  stop_daemon_delete_repo () {\n> -\tr=$1\n> -\tgit -C $r fsmonitor--daemon stop >/dev/null 2>/dev/null\n> +\tr=$1 &&\n> +\ttest_might_fail git -C $r fsmonitor--daemon stop &&\n>  \trm -rf $1\n> -\treturn 0\n>  }\n>  \n>  start_daemon () {\n> -\tcase \"$#\" in\n> -\t\t1) r=\"-C $1\";;\n> -\t\t*) r=\"\";\n> -\tesac\n> +\tr=\"\" &&\n> +\ttf=\"\" &&\n> +\tt2=\"\" &&\n> +\ttk=\"\" &&\n\nWe usually just do : \n\n\tx= &&\n\nNot:\n\n\tx=\"\" &&\n\nI.e. no need for the \"\".\n\n>  \n> -\tgit $r fsmonitor--daemon start || return $?\n> -\tgit $r fsmonitor--daemon status || return $?\n> +\twhile test \"$#\" -ne 0\n> +\tdo\n> +\t\tcase \"$1\" in\n> +\t\t-C)\n> +\t\t\tshift;\n> +\t\t\ttest \"$#\" -ne 0 ||\n> +\t\t\t\t{ echo >&2 \"error: -C requires arg\"; exit 1; }\n\nIMO this exhaustive checking is better just skipped, we e.g.don't do\nthis in \"test_commit\". Can't you just...\n\n> +\t\t\tr=\"-C $1\"\n> +\t\t\tshift\n\n...properly &&-chain these whole things and have the \"shift too many\"\nand exit code from \"shift\" catch this?\n\n> +\t\t\t;;\n> +\t\t-tf)\n> +\t\t\tshift;\n> +\t\t\ttest \"$#\" -ne 0 ||\n> +\t\t\t\t{ echo >&2 \"error: -tf requires arg\"; exit 1; }\n> +\t\t\ttf=\"$1\"\n> +\t\t\tshift\n> +\t\t\t;;\n> +\t\t-t2)\n> +\t\t\tshift;\n> +\t\t\ttest \"$#\" -ne 0 ||\n> +\t\t\t\t{ echo >&2 \"error: -t2 requires arg\"; exit 1; }\n> +\t\t\tt2=\"$1\"\n> +\t\t\tshift\n> +\t\t\t;;\n> +\t\t-tk)\n> +\t\t\tshift;\n> +\t\t\ttest \"$#\" -ne 0 ||\n> +\t\t\t\t{ echo >&2 \"error: -tk requires arg\"; exit 1; }\n> +\t\t\ttk=\"$1\"\n> +\t\t\tshift\n> +\t\t\t;;\n> +\t\t*)\n\nditto.\n\n> +\t\t\techo >&2 \"error: unknown option: '$1'\"\n> +\t\t\texit 1\n\nBut this sort of case is needed, but should use BUG \"...\"\n\n> +\t\t\t;;\n> +\t\tesac\n> +\tdone &&\n> +\n> +\t(\n> +\t\tif test ! -z \"$tf\"\n\nInstead of \"! -z x\" use \"-n x\" ?\n\n> +\t\tthen\n> +\t\t\tGIT_TRACE_FSMONITOR=\"$tf\"\n> +\t\t\texport GIT_TRACE_FSMONITOR\n> +\t\tfi &&\n> +\n> +\t\tif test ! -z \"$t2\"\n> +\t\tthen\n> +\t\t\tGIT_TRACE2_PERF=\"$t2\"\n> +\t\t\texport GIT_TRACE2_PERF\n> +\t\tfi &&\n> +\n> +\t\tif test ! -z \"$tk\"\n\nditto.\n\n> +\t\tthen\n> +\t\t\tGIT_TEST_FSMONITOR_TOKEN=\"$tk\"\n> +\t\t\texport GIT_TEST_FSMONITOR_TOKEN\n\n> +\t\tfi &&\n> -\ttouch test_flush/file_1 &&\n> -\ttouch test_flush/file_2 &&\n> +\t> test_flush/file_1 &&\n> +\t> test_flush/file_2 &&\n\nstyle: \">x\" not \"> x\" (ditto below).\n"},{"id":"451312","messageId":"7ddeffc4-3442-b4a1-e6f4-e68b3aa3f5ec@github.com","threadId":"57542","inReplyTo":"220314.86bky9ezdw.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH 05/16] fsmonitor--daemon: refactor cookie handling for readability","fromName":"Derrick Stolee","fromEmail":"derrickstolee@github.com","sentAt":"2022-03-14T14:49:18Z","receivedAt":"2022-03-14T14:49:23Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 3/14/2022 4:00 AM, Ævar Arnfjörð Bjarmason wrote:\n> \n> On Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n\n>> +\t/*\n>> +\t * Technically, close() and unlink() can fail, but we don't\n>> +\t * care here.  We only created the file to trigger a watch\n>> +\t * event from the FS to know that when we're up to date.\n>> +\t */\n>> +\tclose(fd);\n> \n> It still seems odd to explicitly want to ignore close() return values.\n> \n> I realize that we do in (too many) existing places, but why wouldn't we\n> want to e.g. catch an I/O error here early?\n\nWhat exactly do you propose we do here if there is an I/O error\nduring close()?\n\nThanks,\n-Stolee\n"},{"id":"451332","messageId":"xmqqo828s9xw.fsf@gitster.g","threadId":"57542","inReplyTo":"7ddeffc4-3442-b4a1-e6f4-e68b3aa3f5ec@github.com","subject":"Re: [PATCH 05/16] fsmonitor--daemon: refactor cookie handling for readability","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-14T17:47:23Z","receivedAt":"2022-03-14T17:47:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Derrick Stolee <derrickstolee@github.com> writes:\n\n> On 3/14/2022 4:00 AM, Ævar Arnfjörð Bjarmason wrote:\n>> \n>> On Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n>\n>>> +\t/*\n>>> +\t * Technically, close() and unlink() can fail, but we don't\n>>> +\t * care here.  We only created the file to trigger a watch\n>>> +\t * event from the FS to know that when we're up to date.\n>>> +\t */\n>>> +\tclose(fd);\n>> \n>> It still seems odd to explicitly want to ignore close() return values.\n>> \n>> I realize that we do in (too many) existing places, but why wouldn't we\n>> want to e.g. catch an I/O error here early?\n>\n> What exactly do you propose we do here if there is an I/O error\n> during close()?\n\nWe created the file to trigger a watch event, but now we have a\nreason to suspect that the wished-for watch event may not come.\n\nWe only did so to know that when we're up to date.  Now we may never\nknow?  We may go without realizing we are already up to date a bit\nlonger than the reality?\n\nHow much damage would it cause us to miss a watch event in this\ncase?  Very little?  Is it a thing that sysadmins may care if we see\ntoo many of, but there is nothing the end user can immediately do\nabout?  If it is, perhaps a trace2 event to report it (and other \"we\ndo not care here\" syscalls that fail)?\n\n\n\n"},{"id":"451337","messageId":"xmqqpmmoqpp5.fsf@gitster.g","threadId":"57542","inReplyTo":"432f9ff9d92ff55216555864cb3571c94a2c6db9.1647033303.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 16/16] fsmonitor-settings: simplify initialization of settings data","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-14T19:49:58Z","receivedAt":"2022-03-14T19:51:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Jeff Hostetler <jeffhost@microsoft.com>\n>\n> fixup! fsmonitor: config settings are repository-specific\n\nI cannot tell the validity of this change alone without the base\ncommit in part2 to choose between setting s->mode directly or\ncalling __set_disabled(r).\n\nI've read all the 16 patches here, and I found that the majority of\nthem (except for \"it is hard to tell why we are changing in 2.5; it\nneeds a better justification\" ones like this) are \"oops, the part2\npatches had these obvious and trivial mistakes that we should have\nfixed before we merged them to 'next', or even sending them to the\nlist in the first place\" fixes.\n\nLet's kick part2 out of 'next', and replace it with a corrected set\nof patches and have people review them, this time for real, before\nmerging it back to 'next'.  I just do not get the good feel that the\nseries was adequately reviewed---if we have this many \"oops\" fixups\nneeded after getting merged to 'next'.\n\nThanks.\n\n\n\n> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>\n> ---\n>  fsmonitor-settings.c | 3 +--\n>  1 file changed, 1 insertion(+), 2 deletions(-)\n>\n> diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c\n> index 3b54e7a51f6..757d230d538 100644\n> --- a/fsmonitor-settings.c\n> +++ b/fsmonitor-settings.c\n> @@ -22,11 +22,10 @@ static void lookup_fsmonitor_settings(struct repository *r)\n>  \t\treturn;\n>  \n>  \tCALLOC_ARRAY(s, 1);\n> +\ts->mode = FSMONITOR_MODE_DISABLED;\n>  \n>  \tr->settings.fsmonitor = s;\n>  \n> -\tfsm_settings__set_disabled(r);\n> -\n>  \t/*\n>  \t * Overload the existing \"core.fsmonitor\" config setting (which\n>  \t * has historically been either unset or a hook pathname) to\n"},{"id":"451409","messageId":"33a9f751-6254-9b3e-6eb7-7844ac664e00@jeffhostetler.com","threadId":"57542","inReplyTo":"xmqqpmmoqpp5.fsf@gitster.g","subject":"Re: [PATCH 16/16] fsmonitor-settings: simplify initialization of settings data","fromName":"Jeff Hostetler","fromEmail":"git@jeffhostetler.com","sentAt":"2022-03-15T18:26:04Z","receivedAt":"2022-03-15T18:26:10Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"\n\nOn 3/14/22 3:49 PM, Junio C Hamano wrote:\n> \"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> From: Jeff Hostetler <jeffhost@microsoft.com>\n>>\n>> fixup! fsmonitor: config settings are repository-specific\n> \n> \n> Let's kick part2 out of 'next', and replace it with a corrected set\n> of patches and have people review them, this time for real, before\n> merging it back to 'next'.  I just do not get the good feel that the\n> series was adequately reviewed---if we have this many \"oops\" fixups\n> needed after getting merged to 'next'.\n\nYeah if you haven't merged part2 to master yet, wait and i'll\nsend a V7 of part2 that squashes in these fixups.\n\nand addresses any other comments on part2.5 itself.\n\nThanks and sorry.\nJeff\n\n"},{"id":"451415","messageId":"xmqqee33dohh.fsf@gitster.g","threadId":"57542","inReplyTo":"33a9f751-6254-9b3e-6eb7-7844ac664e00@jeffhostetler.com","subject":"Re: [PATCH 16/16] fsmonitor-settings: simplify initialization of settings data","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-03-15T19:06:50Z","receivedAt":"2022-03-15T19:07:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff Hostetler <git@jeffhostetler.com> writes:\n\n> Yeah if you haven't merged part2 to master yet, wait and i'll\n> send a V7 of part2 that squashes in these fixups.\n>\n> and addresses any other comments on part2.5 itself.\n\nThanks.  I think that would be cleaner in the end.\n\n\n"},{"id":"451746","messageId":"3ba50173-8739-3741-7226-0299ea941e00@jeffhostetler.com","threadId":"57542","inReplyTo":"xmqq5yoht6an.fsf@gitster.g","subject":"Re: [PATCH 02/16] update-index: convert advise() messages back to warning()","fromName":"Jeff Hostetler","fromEmail":"git@jeffhostetler.com","sentAt":"2022-03-21T18:47:20Z","receivedAt":"2022-03-21T18:47:26Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"\n\nOn 3/14/22 2:08 AM, Junio C Hamano wrote:\n> \"Jeff Hostetler via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> From: Jeff Hostetler <jeffhost@microsoft.com>\n>>\n>> fixup! update-index: convert fsmonitor warnings to advise\n> \n> Same comment as 01/16 applies here.  \"convert ... back to ...\" in\n> the title refers to the fact that builtin-fsmonitor-part2 topic\n> turned warning() into advise() without a good justification, I\n> think.  Flipping and flopping between warning and advise, without\n> giving any justification going either direction, is not a good move.\n\nSorry for not including the backstory.\n\nBen wrote the original warning message back in 2017.\n\nIn my original version of part 2 I added a more detailed warning message\nbecause of the new `core.useBuiltinFSMonitor` config settings and\nhow it interacted with `core.fsmonitor`.  And we talked about making\nthat longer message advise rather than a warning.  So I changed them\nto advise().\n\nBut then we decided to remove `core.useBuiltinFSMonitor` and overload\n`core.fsmonitor` to take a boolean, so the original text of the message\nwas sufficient and correct.  So to minimize the diff, I reverted the\ntext change and kept the change from warning() to advise().\n\nBut then there were comments from AEvar on either changing all of\nthe nearby warning() calls to advise() *and* to change them to use\nthe `advise_type` enum.  That seemed like a large/disruptive change\nat this point.\n\nAlso, I wasn't really sure of the need for Ben's original warning\nmessage, so I'd rather leave it as is than expand the scope.\n\nSo I basically reverted the change for this series.  If (in a later\nseries) we want to revisit all of the warnings in update-index.c,\nthen we can think about this.\n\nJeff\n"},{"id":"451753","messageId":"49f2dbd2-b596-7378-ca65-ca5104121af5@jeffhostetler.com","threadId":"57542","inReplyTo":"xmqqo828s9xw.fsf@gitster.g","subject":"Re: [PATCH 05/16] fsmonitor--daemon: refactor cookie handling for readability","fromName":"Jeff Hostetler","fromEmail":"git@jeffhostetler.com","sentAt":"2022-03-21T19:26:14Z","receivedAt":"2022-03-21T19:26:20Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"\n\nOn 3/14/22 1:47 PM, Junio C Hamano wrote:\n> Derrick Stolee <derrickstolee@github.com> writes:\n> \n>> On 3/14/2022 4:00 AM, Ævar Arnfjörð Bjarmason wrote:\n>>>\n>>> On Fri, Mar 11 2022, Jeff Hostetler via GitGitGadget wrote:\n>>\n>>>> +\t/*\n>>>> +\t * Technically, close() and unlink() can fail, but we don't\n>>>> +\t * care here.  We only created the file to trigger a watch\n>>>> +\t * event from the FS to know that when we're up to date.\n>>>> +\t */\n>>>> +\tclose(fd);\n>>>\n>>> It still seems odd to explicitly want to ignore close() return values.\n>>>\n>>> I realize that we do in (too many) existing places, but why wouldn't we\n>>> want to e.g. catch an I/O error here early?\n>>\n>> What exactly do you propose we do here if there is an I/O error\n>> during close()?\n> \n> We created the file to trigger a watch event, but now we have a\n> reason to suspect that the wished-for watch event may not come.\n> \n> We only did so to know that when we're up to date.  Now we may never\n> know?  We may go without realizing we are already up to date a bit\n> longer than the reality?\n> \n> How much damage would it cause us to miss a watch event in this\n> case?  Very little?  Is it a thing that sysadmins may care if we see\n> too many of, but there is nothing the end user can immediately do\n> about?  If it is, perhaps a trace2 event to report it (and other \"we\n> do not care here\" syscalls that fail)?\n> \n> \n> \n\nThe open(... O_CREAT ...) succeeded, so we actually created a\nnew file and expect a FS event for it.  That FS event (when seen\nby the FS listener thread) will cause our condition to be\nsignaled and allow this thread to wake up and respond to the client.\n\nThe odds of the close() failing on a plain file (after a successful\nopen()) are very slim.  And there's nothing that we can do about\nthe failure anyway.  (And we're not relying on an FS event from the\nclose() succeeding, so it really doesn't matter.)   Technically, it\nis possible that the daemon could run out of fd's if this close()\nfails often, so at some point the daemon might not be able to create\nnew cookie files.  But the daemon currently defaults to sending a\ntrivial response to the client -- if this turns out to be a real\nissue, we could have the daemon restart or something, but I'm not\ngoing to worry about that right now.\n\nThe odds of a failure in unlink() is a little more interesting.\nThis would mean that a stale cookie file would be left in the\ncookie directory (and waste a little disk space).  But that is\nnot likely either (for a plain file that we just created).\nSince we're not relying on the FS event for the unlink(), the\nfailure here won't block the current thread either.  Deleting\nstale cookie files is something that we could try to address\nin the future if it turns out to be a problem.\n\nJeff\n\n"}]}