183
return result;
184
}
185
186
+static size_t handle_path_with_trailing_slash(
187
+ struct index_state *istate, const char *name, int pos);
188
+
189
+/*
190
+ * The daemon sent an observed pathname without a trailing slash.
191
+ * (This is the normal case.) We do not know if it is a tracked or
192
+ * untracked file, a sparse-directory, or a populated directory (on a
193
+ * platform such as Windows where FSEvents are not qualified).
194
+ *
195
+ * The pathname contains the observed case reported by the FS. We
196
+ * do not know it is case-correct or -incorrect.
197
+ *
198
+ * Assume it is case-correct and try an exact match.
199
+ */
200
static void handle_path_without_trailing_slash(
201
struct index_state *istate, const char *name, int pos)
202
{
189
- int i;
190
-
203
/*
204
* Mark the untracked cache dirty for this path (regardless of
205
* whether or not we find an exact match for it in the index).
212
213
if (pos >= 0) {
214
/*
203
- * We have an exact match for this path and can just
204
- * invalidate it.
215
+ * An exact match on a tracked file. We assume that we
216
+ * do not need to scan forward for a sparse-directory
217
+ * cache-entry with the same pathname, nor for a cone
218
+ * at that directory. (That is, assume no D/F conflicts.)
219
*/
220
istate->cache[pos]->ce_flags &= ~CE_FSMONITOR_VALID;
221
} else {
222
+ struct strbuf work_path = STRBUF_INIT;
223
+
224
/*
209
- * The path is not a tracked file -or- it is a
210
- * directory event on a platform that cannot
211
- * distinguish between file and directory events in
212
- * the event handler, such as Windows.
213
- *
214
- * Scan as if it is a directory and invalidate the
215
- * cone under it. (But remember to ignore items
216
- * between "name" and "name/", such as "name-" and
217
- * "name.".
225
+ * The negative "pos" gives us the suggested insertion
226
+ * point for the pathname (without the trailing slash).
227
+ * We need to see if there is a directory with that
228
+ * prefix, but there can be lots of pathnames between
229
+ * "foo" and "foo/" like "foo-" or "foo-bar", so we
230
+ * don't want to do our own scan.
231
*/
219
- int len = strlen(name);
220
- pos = -pos - 1;
221
-
222
- for (i = pos; i < istate->cache_nr; i++) {
223
- if (!starts_with(istate->cache[i]->name, name))
224
- break;
225
- if ((unsigned char)istate->cache[i]->name[len] > '/')
226
- break;
227
- if (istate->cache[i]->name[len] == '/')
228
- istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
229
- }
232
+ strbuf_add(&work_path, name, strlen(name));
233
+ strbuf_addch(&work_path, '/');
234
+ pos = index_name_pos(istate, work_path.buf, work_path.len);
235
+ handle_path_with_trailing_slash(istate, work_path.buf, pos);
236
+ strbuf_release(&work_path);
237
}
238
}
239