summaryrefslogtreecommitdiff
path: root/fsmonitor-settings.c
diff options
context:
space:
mode:
authorJeff Hostetler <jeffhost@microsoft.com>2022-03-25 18:02:46 (GMT)
committerJunio C Hamano <gitster@pobox.com>2022-03-25 23:04:15 (GMT)
commit1e0ea5c4316d2241dd76ef430a2779db9a097dfb (patch)
tree7c2aed530bcba080e9eea01515018b517f6edef5 /fsmonitor-settings.c
parentd2bd862e7a4a791d88740cc81aad14cdcd90dd2c (diff)
downloadgit-1e0ea5c4316d2241dd76ef430a2779db9a097dfb.zip
git-1e0ea5c4316d2241dd76ef430a2779db9a097dfb.tar.gz
git-1e0ea5c4316d2241dd76ef430a2779db9a097dfb.tar.bz2
fsmonitor: config settings are repository-specific
Move fsmonitor config settings to a new and opaque `struct fsmonitor_settings` structure. Add a lazily-loaded pointer to this into `struct repo_settings` Create an `enum fsmonitor_mode` type in `struct fsmonitor_settings` to represent the state of fsmonitor. This lets us represent which, if any, fsmonitor provider (hook or IPC) is enabled. Create `fsm_settings__get_*()` getters to lazily look up fsmonitor- related config settings. Get rid of the `core_fsmonitor` global variable. Move the code to lookup the existing `core.fsmonitor` config value into the fsmonitor settings. Create a hook pathname variable in `struct fsmonitor-settings` and only set it when in hook mode. Extend the definition of `core.fsmonitor` to be either a boolean or a hook pathname. When true, the builtin FSMonitor is used. When false or unset, no FSMonitor (neither builtin nor hook) is used. The existing `core_fsmonitor` global variable was used to store the pathname to the fsmonitor hook *and* it was used as a boolean to see if fsmonitor was enabled. This dual usage and global visibility leads to confusion when we add the IPC-based provider. So lets hide the details in fsmonitor-settings.c and let it decide which provider to use in the case of multiple settings. This avoids cluttering up repo-settings.c with these private details. A future commit in builtin-fsmonitor series will add the ability to disqualify worktrees for various reasons, such as being mounted from a remote volume, where fsmonitor should not be started. Having the config settings hidden in fsmonitor-settings.c allows such worktree restrictions to override the config values used. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'fsmonitor-settings.c')
-rw-r--r--fsmonitor-settings.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c
new file mode 100644
index 0000000..757d230
--- /dev/null
+++ b/fsmonitor-settings.c
@@ -0,0 +1,114 @@
+#include "cache.h"
+#include "config.h"
+#include "repository.h"
+#include "fsmonitor-settings.h"
+
+/*
+ * We keep this structure defintion private and have getters
+ * for all fields so that we can lazy load it as needed.
+ */
+struct fsmonitor_settings {
+ enum fsmonitor_mode mode;
+ char *hook_path;
+};
+
+static void lookup_fsmonitor_settings(struct repository *r)
+{
+ struct fsmonitor_settings *s;
+ const char *const_str;
+ int bool_value;
+
+ if (r->settings.fsmonitor)
+ return;
+
+ CALLOC_ARRAY(s, 1);
+ s->mode = FSMONITOR_MODE_DISABLED;
+
+ r->settings.fsmonitor = s;
+
+ /*
+ * Overload the existing "core.fsmonitor" config setting (which
+ * has historically been either unset or a hook pathname) to
+ * now allow a boolean value to enable the builtin FSMonitor
+ * or to turn everything off. (This does imply that you can't
+ * use a hook script named "true" or "false", but that's OK.)
+ */
+ switch (repo_config_get_maybe_bool(r, "core.fsmonitor", &bool_value)) {
+
+ case 0: /* config value was set to <bool> */
+ if (bool_value)
+ fsm_settings__set_ipc(r);
+ return;
+
+ case 1: /* config value was unset */
+ const_str = getenv("GIT_TEST_FSMONITOR");
+ break;
+
+ case -1: /* config value set to an arbitrary string */
+ if (repo_config_get_pathname(r, "core.fsmonitor", &const_str))
+ return; /* should not happen */
+ break;
+
+ default: /* should not happen */
+ return;
+ }
+
+ if (!const_str || !*const_str)
+ return;
+
+ fsm_settings__set_hook(r, const_str);
+}
+
+enum fsmonitor_mode fsm_settings__get_mode(struct repository *r)
+{
+ if (!r)
+ r = the_repository;
+
+ lookup_fsmonitor_settings(r);
+
+ return r->settings.fsmonitor->mode;
+}
+
+const char *fsm_settings__get_hook_path(struct repository *r)
+{
+ if (!r)
+ r = the_repository;
+
+ lookup_fsmonitor_settings(r);
+
+ return r->settings.fsmonitor->hook_path;
+}
+
+void fsm_settings__set_ipc(struct repository *r)
+{
+ if (!r)
+ r = the_repository;
+
+ lookup_fsmonitor_settings(r);
+
+ r->settings.fsmonitor->mode = FSMONITOR_MODE_IPC;
+ FREE_AND_NULL(r->settings.fsmonitor->hook_path);
+}
+
+void fsm_settings__set_hook(struct repository *r, const char *path)
+{
+ if (!r)
+ r = the_repository;
+
+ lookup_fsmonitor_settings(r);
+
+ r->settings.fsmonitor->mode = FSMONITOR_MODE_HOOK;
+ FREE_AND_NULL(r->settings.fsmonitor->hook_path);
+ r->settings.fsmonitor->hook_path = strdup(path);
+}
+
+void fsm_settings__set_disabled(struct repository *r)
+{
+ if (!r)
+ r = the_repository;
+
+ lookup_fsmonitor_settings(r);
+
+ r->settings.fsmonitor->mode = FSMONITOR_MODE_DISABLED;
+ FREE_AND_NULL(r->settings.fsmonitor->hook_path);
+}