fsmonitor: refactor refresh callback for non-directory events

Move the code that handles unqualified FSEvents (without a trailing slash) into a helper function. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Feb 26, 2024 at 21:39 UTC 8687c2b067a89e0c91a65b46b4f5eccf041e6718
1 file changed +39 -28
fsmonitor.c
+39 -28
@@ -183,6 +183,43 @@ static int query_fsmonitor_hook(struct repository *r,
183 return result;
184 }
185
186 +static void handle_path_without_trailing_slash(
187 + struct index_state *istate, const char *name, int pos)
188 +{
189 + int i;
190 +
191 + if (pos >= 0) {
192 + /*
193 + * We have an exact match for this path and can just
194 + * invalidate it.
195 + */
196 + istate->cache[pos]->ce_flags &= ~CE_FSMONITOR_VALID;
197 + } else {
198 + /*
199 + * The path is not a tracked file -or- it is a
200 + * directory event on a platform that cannot
201 + * distinguish between file and directory events in
202 + * the event handler, such as Windows.
203 + *
204 + * Scan as if it is a directory and invalidate the
205 + * cone under it. (But remember to ignore items
206 + * between "name" and "name/", such as "name-" and
207 + * "name.".
208 + */
209 + int len = strlen(name);
210 + pos = -pos - 1;
211 +
212 + for (i = pos; i < istate->cache_nr; i++) {
213 + if (!starts_with(istate->cache[i]->name, name))
214 + break;
215 + if ((unsigned char)istate->cache[i]->name[len] > '/')
216 + break;
217 + if (istate->cache[i]->name[len] == '/')
218 + istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
219 + }
220 + }
221 +}
222 +
223 /*
224 * The daemon can decorate directory events, such as a move or rename,
225 * by adding a trailing slash to the observed name. Use this to
@@ -225,7 +262,7 @@ static void handle_path_with_trailing_slash(
262
263 static void fsmonitor_refresh_callback(struct index_state *istate, char *name)
264 {
228 - int i, len = strlen(name);
265 + int len = strlen(name);
266 int pos = index_name_pos(istate, name, len);
267
268 trace_printf_key(&trace_fsmonitor,
@@ -240,34 +277,8 @@ static void fsmonitor_refresh_callback(struct index_state *istate, char *name)
277 * for the untracked cache.
278 */
279 name[len - 1] = '\0';
243 - } else if (pos >= 0) {
244 - /*
245 - * We have an exact match for this path and can just
246 - * invalidate it.
247 - */
248 - istate->cache[pos]->ce_flags &= ~CE_FSMONITOR_VALID;
280 } else {
250 - /*
251 - * The path is not a tracked file -or- it is a
252 - * directory event on a platform that cannot
253 - * distinguish between file and directory events in
254 - * the event handler, such as Windows.
255 - *
256 - * Scan as if it is a directory and invalidate the
257 - * cone under it. (But remember to ignore items
258 - * between "name" and "name/", such as "name-" and
259 - * "name.".
260 - */
261 - pos = -pos - 1;
262 -
263 - for (i = pos; i < istate->cache_nr; i++) {
264 - if (!starts_with(istate->cache[i]->name, name))
265 - break;
266 - if ((unsigned char)istate->cache[i]->name[len] > '/')
267 - break;
268 - if (istate->cache[i]->name[len] == '/')
269 - istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
270 - }
281 + handle_path_without_trailing_slash(istate, name, pos);
282 }
283
284 /*