3 #include "repository.h"
4 #include "fsmonitor-settings.h"
7 * We keep this structure defintion private and have getters
8 * for all fields so that we can lazy load it as needed.
10 struct fsmonitor_settings
{
11 enum fsmonitor_mode mode
;
12 enum fsmonitor_reason reason
;
16 static enum fsmonitor_reason
check_for_incompatible(struct repository
*r
)
20 * Bare repositories don't have a working directory and
21 * therefore have nothing to watch.
23 return FSMONITOR_REASON_BARE
;
26 #ifdef HAVE_FSMONITOR_OS_SETTINGS
28 enum fsmonitor_reason reason
;
30 reason
= fsm_os__incompatible(r
);
31 if (reason
!= FSMONITOR_REASON_OK
)
36 return FSMONITOR_REASON_OK
;
39 static struct fsmonitor_settings
*alloc_settings(void)
41 struct fsmonitor_settings
*s
;
44 s
->mode
= FSMONITOR_MODE_DISABLED
;
45 s
->reason
= FSMONITOR_REASON_UNTESTED
;
50 static void lookup_fsmonitor_settings(struct repository
*r
)
52 const char *const_str
;
55 if (r
->settings
.fsmonitor
)
59 * Overload the existing "core.fsmonitor" config setting (which
60 * has historically been either unset or a hook pathname) to
61 * now allow a boolean value to enable the builtin FSMonitor
62 * or to turn everything off. (This does imply that you can't
63 * use a hook script named "true" or "false", but that's OK.)
65 switch (repo_config_get_maybe_bool(r
, "core.fsmonitor", &bool_value
)) {
67 case 0: /* config value was set to <bool> */
69 fsm_settings__set_ipc(r
);
71 fsm_settings__set_disabled(r
);
74 case 1: /* config value was unset */
75 const_str
= getenv("GIT_TEST_FSMONITOR");
78 case -1: /* config value set to an arbitrary string */
79 if (repo_config_get_pathname(r
, "core.fsmonitor", &const_str
))
80 return; /* should not happen */
83 default: /* should not happen */
87 if (const_str
&& *const_str
)
88 fsm_settings__set_hook(r
, const_str
);
90 fsm_settings__set_disabled(r
);
93 enum fsmonitor_mode
fsm_settings__get_mode(struct repository
*r
)
97 if (!r
->settings
.fsmonitor
)
98 lookup_fsmonitor_settings(r
);
100 return r
->settings
.fsmonitor
->mode
;
103 const char *fsm_settings__get_hook_path(struct repository
*r
)
107 if (!r
->settings
.fsmonitor
)
108 lookup_fsmonitor_settings(r
);
110 return r
->settings
.fsmonitor
->hook_path
;
113 void fsm_settings__set_ipc(struct repository
*r
)
115 enum fsmonitor_reason reason
= check_for_incompatible(r
);
117 if (reason
!= FSMONITOR_REASON_OK
) {
118 fsm_settings__set_incompatible(r
, reason
);
123 * Caller requested IPC explicitly, so avoid (possibly
124 * recursive) config lookup.
128 if (!r
->settings
.fsmonitor
)
129 r
->settings
.fsmonitor
= alloc_settings();
131 r
->settings
.fsmonitor
->mode
= FSMONITOR_MODE_IPC
;
132 r
->settings
.fsmonitor
->reason
= reason
;
133 FREE_AND_NULL(r
->settings
.fsmonitor
->hook_path
);
136 void fsm_settings__set_hook(struct repository
*r
, const char *path
)
138 enum fsmonitor_reason reason
= check_for_incompatible(r
);
140 if (reason
!= FSMONITOR_REASON_OK
) {
141 fsm_settings__set_incompatible(r
, reason
);
146 * Caller requested hook explicitly, so avoid (possibly
147 * recursive) config lookup.
151 if (!r
->settings
.fsmonitor
)
152 r
->settings
.fsmonitor
= alloc_settings();
154 r
->settings
.fsmonitor
->mode
= FSMONITOR_MODE_HOOK
;
155 r
->settings
.fsmonitor
->reason
= reason
;
156 FREE_AND_NULL(r
->settings
.fsmonitor
->hook_path
);
157 r
->settings
.fsmonitor
->hook_path
= strdup(path
);
160 void fsm_settings__set_disabled(struct repository
*r
)
164 if (!r
->settings
.fsmonitor
)
165 r
->settings
.fsmonitor
= alloc_settings();
167 r
->settings
.fsmonitor
->mode
= FSMONITOR_MODE_DISABLED
;
168 r
->settings
.fsmonitor
->reason
= FSMONITOR_REASON_OK
;
169 FREE_AND_NULL(r
->settings
.fsmonitor
->hook_path
);
172 void fsm_settings__set_incompatible(struct repository
*r
,
173 enum fsmonitor_reason reason
)
177 if (!r
->settings
.fsmonitor
)
178 r
->settings
.fsmonitor
= alloc_settings();
180 r
->settings
.fsmonitor
->mode
= FSMONITOR_MODE_INCOMPATIBLE
;
181 r
->settings
.fsmonitor
->reason
= reason
;
182 FREE_AND_NULL(r
->settings
.fsmonitor
->hook_path
);
185 enum fsmonitor_reason
fsm_settings__get_reason(struct repository
*r
)
189 if (!r
->settings
.fsmonitor
)
190 lookup_fsmonitor_settings(r
);
192 return r
->settings
.fsmonitor
->reason
;
195 char *fsm_settings__get_incompatible_msg(const struct repository
*r
,
196 enum fsmonitor_reason reason
)
198 struct strbuf msg
= STRBUF_INIT
;
201 case FSMONITOR_REASON_UNTESTED
:
202 case FSMONITOR_REASON_OK
:
205 case FSMONITOR_REASON_BARE
: {
206 char *cwd
= xgetcwd();
209 _("bare repository '%s' is incompatible with fsmonitor"),
215 case FSMONITOR_REASON_ERROR
:
217 _("repository '%s' is incompatible with fsmonitor due to errors"),
221 case FSMONITOR_REASON_REMOTE
:
223 _("remote repository '%s' is incompatible with fsmonitor"),
227 case FSMONITOR_REASON_VFS4GIT
:
229 _("virtual repository '%s' is incompatible with fsmonitor"),
233 case FSMONITOR_REASON_NOSOCKETS
:
235 _("repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"),
240 BUG("Unhandled case in fsm_settings__get_incompatible_msg: '%d'",
244 return strbuf_detach(&msg
, NULL
);