summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/fsmonitor--daemon.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c
index 69dd39121a..1ce00b7c15 100644
--- a/builtin/fsmonitor--daemon.c
+++ b/builtin/fsmonitor--daemon.c
@@ -134,6 +134,87 @@ static int handle_client(void *data,
return result;
}
+#define FSMONITOR_COOKIE_PREFIX ".fsmonitor-daemon-"
+
+enum fsmonitor_path_type fsmonitor_classify_path_workdir_relative(
+ const char *rel)
+{
+ if (fspathncmp(rel, ".git", 4))
+ return IS_WORKDIR_PATH;
+ rel += 4;
+
+ if (!*rel)
+ return IS_DOT_GIT;
+ if (*rel != '/')
+ return IS_WORKDIR_PATH; /* e.g. .gitignore */
+ rel++;
+
+ if (!fspathncmp(rel, FSMONITOR_COOKIE_PREFIX,
+ strlen(FSMONITOR_COOKIE_PREFIX)))
+ return IS_INSIDE_DOT_GIT_WITH_COOKIE_PREFIX;
+
+ return IS_INSIDE_DOT_GIT;
+}
+
+enum fsmonitor_path_type fsmonitor_classify_path_gitdir_relative(
+ const char *rel)
+{
+ if (!fspathncmp(rel, FSMONITOR_COOKIE_PREFIX,
+ strlen(FSMONITOR_COOKIE_PREFIX)))
+ return IS_INSIDE_GITDIR_WITH_COOKIE_PREFIX;
+
+ return IS_INSIDE_GITDIR;
+}
+
+static enum fsmonitor_path_type try_classify_workdir_abs_path(
+ struct fsmonitor_daemon_state *state,
+ const char *path)
+{
+ const char *rel;
+
+ if (fspathncmp(path, state->path_worktree_watch.buf,
+ state->path_worktree_watch.len))
+ return IS_OUTSIDE_CONE;
+
+ rel = path + state->path_worktree_watch.len;
+
+ if (!*rel)
+ return IS_WORKDIR_PATH; /* it is the root dir exactly */
+ if (*rel != '/')
+ return IS_OUTSIDE_CONE;
+ rel++;
+
+ return fsmonitor_classify_path_workdir_relative(rel);
+}
+
+enum fsmonitor_path_type fsmonitor_classify_path_absolute(
+ struct fsmonitor_daemon_state *state,
+ const char *path)
+{
+ const char *rel;
+ enum fsmonitor_path_type t;
+
+ t = try_classify_workdir_abs_path(state, path);
+ if (state->nr_paths_watching == 1)
+ return t;
+ if (t != IS_OUTSIDE_CONE)
+ return t;
+
+ if (fspathncmp(path, state->path_gitdir_watch.buf,
+ state->path_gitdir_watch.len))
+ return IS_OUTSIDE_CONE;
+
+ rel = path + state->path_gitdir_watch.len;
+
+ if (!*rel)
+ return IS_GITDIR; /* it is the <gitdir> exactly */
+ if (*rel != '/')
+ return IS_OUTSIDE_CONE;
+ rel++;
+
+ return fsmonitor_classify_path_gitdir_relative(rel);
+}
+
static void *fsm_listen__thread_proc(void *_state)
{
struct fsmonitor_daemon_state *state = _state;