Skip to content

Commit a05b20c

Browse files
jeffhostetlerdscho
authored andcommitted
fsmonitor: config settings are repository-specific
Move FSMonitor config settings to a new `struct fsmonitor_settings` structure. Add a lazily-loaded pointer to `struct repo_settings`. Create `fsm_settings__get_*()` getters to lazily look up fsmonitor- related config settings. Get rid of the `core_fsmonitor` global variable, and add support for the new `core.useBuiltinFSMonitor` config setting. Move config code to lookup the existing `core.fsmonitor` value to `fsmonitor-settings.[ch]`. The `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 will lead to confusion when we add support for a builtin FSMonitor based on IPC, since the builtin FSMonitor doesn't need the hook pathname. Replace the boolean usage with an `enum fsmonitor_mode` to represent the state of FSMonitor. And only set the pathname when in HOOK mode. Signed-off-by: Jeff Hostetler <[email protected]>
1 parent 7dec29d commit a05b20c

13 files changed

+194
-51
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ LIB_OBJS += fmt-merge-msg.o
904904
LIB_OBJS += fsck.o
905905
LIB_OBJS += fsmonitor.o
906906
LIB_OBJS += fsmonitor-ipc.o
907+
LIB_OBJS += fsmonitor-settings.o
907908
LIB_OBJS += gettext.o
908909
LIB_OBJS += gpg-interface.o
909910
LIB_OBJS += graph.o

builtin/update-index.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,14 +1214,25 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
12141214
}
12151215

12161216
if (fsmonitor > 0) {
1217-
if (git_config_get_fsmonitor() == 0)
1217+
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
1218+
1219+
if (fsm_mode == FSMONITOR_MODE_DISABLED) {
1220+
warning(_("core.useBuiltinFSMonitor is unset; "
1221+
"set it if you really want to enable the "
1222+
"builtin fsmonitor"));
12181223
warning(_("core.fsmonitor is unset; "
1219-
"set it if you really want to "
1220-
"enable fsmonitor"));
1224+
"set it if you really want to enable the "
1225+
"hook-based fsmonitor"));
1226+
}
12211227
add_fsmonitor(&the_index);
12221228
report(_("fsmonitor enabled"));
12231229
} else if (!fsmonitor) {
1224-
if (git_config_get_fsmonitor() == 1)
1230+
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
1231+
if (fsm_mode == FSMONITOR_MODE_IPC)
1232+
warning(_("core.useBuiltinFSMonitor is set; "
1233+
"remove it if you really want to "
1234+
"disable fsmonitor"));
1235+
if (fsm_mode == FSMONITOR_MODE_HOOK)
12251236
warning(_("core.fsmonitor is set; "
12261237
"remove it if you really want to "
12271238
"disable fsmonitor"));

cache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,6 @@ extern int core_preload_index;
989989
extern int precomposed_unicode;
990990
extern int protect_hfs;
991991
extern int protect_ntfs;
992-
extern const char *core_fsmonitor;
993992

994993
extern int core_apply_sparse_checkout;
995994
extern int core_sparse_checkout_cone;

config.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,20 +2514,6 @@ int git_config_get_max_percent_split_change(void)
25142514
return -1; /* default value */
25152515
}
25162516

2517-
int git_config_get_fsmonitor(void)
2518-
{
2519-
if (git_config_get_pathname("core.fsmonitor", &core_fsmonitor))
2520-
core_fsmonitor = getenv("GIT_TEST_FSMONITOR");
2521-
2522-
if (core_fsmonitor && !*core_fsmonitor)
2523-
core_fsmonitor = NULL;
2524-
2525-
if (core_fsmonitor)
2526-
return 1;
2527-
2528-
return 0;
2529-
}
2530-
25312517
int git_config_get_index_threads(int *dest)
25322518
{
25332519
int is_bool, val;

config.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,6 @@ int git_config_get_index_threads(int *dest);
610610
int git_config_get_untracked_cache(void);
611611
int git_config_get_split_index(void);
612612
int git_config_get_max_percent_split_change(void);
613-
int git_config_get_fsmonitor(void);
614613

615614
/* This dies if the configured or default date is in the future */
616615
int git_config_get_expiry(const char *key, const char **output);

environment.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ int protect_hfs = PROTECT_HFS_DEFAULT;
8383
#define PROTECT_NTFS_DEFAULT 1
8484
#endif
8585
int protect_ntfs = PROTECT_NTFS_DEFAULT;
86-
const char *core_fsmonitor;
8786

8887
/*
8988
* The character that begins a commented line in user-editable file

fsmonitor-settings.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include "cache.h"
2+
#include "config.h"
3+
#include "repository.h"
4+
#include "fsmonitor-settings.h"
5+
6+
/*
7+
* We keep this structure defintion private and have getters
8+
* for all fields so that we can lazy load it as needed.
9+
*/
10+
struct fsmonitor_settings {
11+
enum fsmonitor_mode mode;
12+
char *hook_path;
13+
};
14+
15+
void fsm_settings__set_ipc(struct repository *r)
16+
{
17+
struct fsmonitor_settings *s = r->settings.fsmonitor;
18+
19+
s->mode = FSMONITOR_MODE_IPC;
20+
}
21+
22+
void fsm_settings__set_hook(struct repository *r, const char *path)
23+
{
24+
struct fsmonitor_settings *s = r->settings.fsmonitor;
25+
26+
s->mode = FSMONITOR_MODE_HOOK;
27+
s->hook_path = strdup(path);
28+
}
29+
30+
void fsm_settings__set_disabled(struct repository *r)
31+
{
32+
struct fsmonitor_settings *s = r->settings.fsmonitor;
33+
34+
s->mode = FSMONITOR_MODE_DISABLED;
35+
FREE_AND_NULL(s->hook_path);
36+
}
37+
38+
static int check_for_ipc(struct repository *r)
39+
{
40+
int value;
41+
42+
if (!repo_config_get_bool(r, "core.usebuiltinfsmonitor", &value) &&
43+
value) {
44+
fsm_settings__set_ipc(r);
45+
return 1;
46+
}
47+
48+
return 0;
49+
}
50+
51+
static int check_for_hook(struct repository *r)
52+
{
53+
const char *const_str;
54+
55+
if (repo_config_get_pathname(r, "core.fsmonitor", &const_str))
56+
const_str = getenv("GIT_TEST_FSMONITOR");
57+
58+
if (const_str && *const_str) {
59+
fsm_settings__set_hook(r, const_str);
60+
return 1;
61+
}
62+
63+
return 0;
64+
}
65+
66+
static void lookup_fsmonitor_settings(struct repository *r)
67+
{
68+
struct fsmonitor_settings *s;
69+
70+
CALLOC_ARRAY(s, 1);
71+
72+
r->settings.fsmonitor = s;
73+
74+
if (check_for_ipc(r))
75+
return;
76+
77+
if (check_for_hook(r))
78+
return;
79+
80+
fsm_settings__set_disabled(r);
81+
}
82+
83+
enum fsmonitor_mode fsm_settings__get_mode(struct repository *r)
84+
{
85+
if (!r->settings.fsmonitor)
86+
lookup_fsmonitor_settings(r);
87+
88+
return r->settings.fsmonitor->mode;
89+
}
90+
91+
const char *fsm_settings__get_hook_path(struct repository *r)
92+
{
93+
if (!r->settings.fsmonitor)
94+
lookup_fsmonitor_settings(r);
95+
96+
return r->settings.fsmonitor->hook_path;
97+
}

fsmonitor-settings.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef FSMONITOR_SETTINGS_H
2+
#define FSMONITOR_SETTINGS_H
3+
4+
struct repository;
5+
6+
enum fsmonitor_mode {
7+
FSMONITOR_MODE_DISABLED = 0,
8+
FSMONITOR_MODE_HOOK = 1, /* core.fsmonitor */
9+
FSMONITOR_MODE_IPC = 2, /* core.useBuiltinFSMonitor */
10+
};
11+
12+
void fsm_settings__set_ipc(struct repository *r);
13+
void fsm_settings__set_hook(struct repository *r, const char *path);
14+
void fsm_settings__set_disabled(struct repository *r);
15+
16+
enum fsmonitor_mode fsm_settings__get_mode(struct repository *r);
17+
const char *fsm_settings__get_hook_path(struct repository *r);
18+
19+
struct fsmonitor_settings;
20+
21+
#endif /* FSMONITOR_SETTINGS_H */

fsmonitor.c

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "dir.h"
44
#include "ewah/ewok.h"
55
#include "fsmonitor.h"
6+
#include "fsmonitor-ipc.h"
67
#include "run-command.h"
78
#include "strbuf.h"
89

@@ -148,15 +149,18 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
148149
/*
149150
* Call the query-fsmonitor hook passing the last update token of the saved results.
150151
*/
151-
static int query_fsmonitor(int version, const char *last_update, struct strbuf *query_result)
152+
static int query_fsmonitor_hook(struct repository *r,
153+
int version,
154+
const char *last_update,
155+
struct strbuf *query_result)
152156
{
153157
struct child_process cp = CHILD_PROCESS_INIT;
154158
int result;
155159

156-
if (!core_fsmonitor)
160+
if (fsm_settings__get_mode(r) != FSMONITOR_MODE_HOOK)
157161
return -1;
158162

159-
strvec_push(&cp.args, core_fsmonitor);
163+
strvec_push(&cp.args, fsm_settings__get_hook_path(r));
160164
strvec_pushf(&cp.args, "%d", version);
161165
strvec_pushf(&cp.args, "%s", last_update);
162166
cp.use_shell = 1;
@@ -238,31 +242,43 @@ void refresh_fsmonitor(struct index_state *istate)
238242
struct strbuf last_update_token = STRBUF_INIT;
239243
char *buf;
240244
unsigned int i;
245+
struct repository *r = istate->repo ? istate->repo : the_repository;
246+
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
241247

242-
if (!core_fsmonitor || istate->fsmonitor_has_run_once)
248+
if (fsm_mode <= FSMONITOR_MODE_DISABLED ||
249+
istate->fsmonitor_has_run_once)
243250
return;
244251

245-
hook_version = fsmonitor_hook_version();
246-
247252
istate->fsmonitor_has_run_once = 1;
248253

249254
trace_printf_key(&trace_fsmonitor, "refresh fsmonitor");
255+
256+
if (fsm_mode == FSMONITOR_MODE_IPC) {
257+
/* TODO */
258+
return;
259+
}
260+
261+
assert(fsm_mode == FSMONITOR_MODE_HOOK);
262+
263+
hook_version = fsmonitor_hook_version();
264+
250265
/*
251-
* This could be racy so save the date/time now and query_fsmonitor
266+
* This could be racy so save the date/time now and query_fsmonitor_hook
252267
* should be inclusive to ensure we don't miss potential changes.
253268
*/
254269
last_update = getnanotime();
255270
if (hook_version == HOOK_INTERFACE_VERSION1)
256271
strbuf_addf(&last_update_token, "%"PRIu64"", last_update);
257272

258273
/*
259-
* If we have a last update token, call query_fsmonitor for the set of
274+
* If we have a last update token, call query_fsmonitor_hook for the set of
260275
* changes since that token, else assume everything is possibly dirty
261276
* and check it all.
262277
*/
263278
if (istate->fsmonitor_last_update) {
264279
if (hook_version == -1 || hook_version == HOOK_INTERFACE_VERSION2) {
265-
query_success = !query_fsmonitor(HOOK_INTERFACE_VERSION2,
280+
query_success = !query_fsmonitor_hook(
281+
r, HOOK_INTERFACE_VERSION2,
266282
istate->fsmonitor_last_update, &query_result);
267283

268284
if (query_success) {
@@ -292,13 +308,17 @@ void refresh_fsmonitor(struct index_state *istate)
292308
}
293309

294310
if (hook_version == HOOK_INTERFACE_VERSION1) {
295-
query_success = !query_fsmonitor(HOOK_INTERFACE_VERSION1,
311+
query_success = !query_fsmonitor_hook(
312+
r, HOOK_INTERFACE_VERSION1,
296313
istate->fsmonitor_last_update, &query_result);
297314
}
298315

299-
trace_performance_since(last_update, "fsmonitor process '%s'", core_fsmonitor);
300-
trace_printf_key(&trace_fsmonitor, "fsmonitor process '%s' returned %s",
301-
core_fsmonitor, query_success ? "success" : "failure");
316+
trace_performance_since(last_update, "fsmonitor process '%s'",
317+
fsm_settings__get_hook_path(r));
318+
trace_printf_key(&trace_fsmonitor,
319+
"fsmonitor process '%s' returned %s",
320+
fsm_settings__get_hook_path(r),
321+
query_success ? "success" : "failure");
302322
}
303323

304324
/*
@@ -434,7 +454,8 @@ void remove_fsmonitor(struct index_state *istate)
434454
void tweak_fsmonitor(struct index_state *istate)
435455
{
436456
unsigned int i;
437-
int fsmonitor_enabled = git_config_get_fsmonitor();
457+
struct repository *r = istate->repo ? istate->repo : the_repository;
458+
int fsmonitor_enabled = (fsm_settings__get_mode(r) > FSMONITOR_MODE_DISABLED);
438459

439460
if (istate->fsmonitor_dirty) {
440461
if (fsmonitor_enabled) {
@@ -454,16 +475,8 @@ void tweak_fsmonitor(struct index_state *istate)
454475
istate->fsmonitor_dirty = NULL;
455476
}
456477

457-
switch (fsmonitor_enabled) {
458-
case -1: /* keep: do nothing */
459-
break;
460-
case 0: /* false */
461-
remove_fsmonitor(istate);
462-
break;
463-
case 1: /* true */
478+
if (fsmonitor_enabled)
464479
add_fsmonitor(istate);
465-
break;
466-
default: /* unknown value: do nothing */
467-
break;
468-
}
480+
else
481+
remove_fsmonitor(istate);
469482
}

fsmonitor.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "cache.h"
55
#include "dir.h"
6+
#include "fsmonitor-settings.h"
67

78
extern struct trace_key trace_fsmonitor;
89

@@ -57,7 +58,11 @@ int fsmonitor_is_trivial_response(const struct strbuf *query_result);
5758
*/
5859
static inline int is_fsmonitor_refreshed(const struct index_state *istate)
5960
{
60-
return !core_fsmonitor || istate->fsmonitor_has_run_once;
61+
struct repository *r = istate->repo ? istate->repo : the_repository;
62+
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
63+
64+
return fsm_mode <= FSMONITOR_MODE_DISABLED ||
65+
istate->fsmonitor_has_run_once;
6166
}
6267

6368
/*
@@ -67,7 +72,11 @@ static inline int is_fsmonitor_refreshed(const struct index_state *istate)
6772
*/
6873
static inline void mark_fsmonitor_valid(struct index_state *istate, struct cache_entry *ce)
6974
{
70-
if (core_fsmonitor && !(ce->ce_flags & CE_FSMONITOR_VALID)) {
75+
struct repository *r = istate->repo ? istate->repo : the_repository;
76+
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
77+
78+
if (fsm_mode > FSMONITOR_MODE_DISABLED &&
79+
!(ce->ce_flags & CE_FSMONITOR_VALID)) {
7180
istate->cache_changed = 1;
7281
ce->ce_flags |= CE_FSMONITOR_VALID;
7382
trace_printf_key(&trace_fsmonitor, "mark_fsmonitor_clean '%s'", ce->name);
@@ -83,7 +92,10 @@ static inline void mark_fsmonitor_valid(struct index_state *istate, struct cache
8392
*/
8493
static inline void mark_fsmonitor_invalid(struct index_state *istate, struct cache_entry *ce)
8594
{
86-
if (core_fsmonitor) {
95+
struct repository *r = istate->repo ? istate->repo : the_repository;
96+
enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r);
97+
98+
if (fsm_mode > FSMONITOR_MODE_DISABLED) {
8799
ce->ce_flags &= ~CE_FSMONITOR_VALID;
88100
untracked_cache_invalidate_path(istate, ce->name, 1);
89101
trace_printf_key(&trace_fsmonitor, "mark_fsmonitor_invalid '%s'", ce->name);

0 commit comments

Comments
 (0)