1288
}
1289
}
1290
1291
-static int only_spaces_and_periods(const char *path, size_t len, size_t skip)
1292
-{
1293
- if (len < skip)
1294
- return 0;
1295
- len -= skip;
1296
- path += skip;
1297
- while (len-- > 0) {
1298
- char c = *(path++);
1299
- if (c != ' ' && c != '.')
1300
- return 0;
1301
- }
1302
- return 1;
1303
-}
1304
-
1291
/*
1292
* On NTFS, we need to be careful to disallow certain synonyms of the `.git/`
1293
* directory:
1327
*/
1328
int is_ntfs_dotgit(const char *name)
1329
{
1344
- size_t len;
1330
+ char c;
1331
1346
- for (len = 0; ; len++)
1347
- if (!name[len] || name[len] == '\\' || is_dir_sep(name[len]) ||
1348
- name[len] == ':') {
1349
- if (only_spaces_and_periods(name, len, 4) &&
1350
- !strncasecmp(name, ".git", 4))
1351
- return 1;
1352
- if (only_spaces_and_periods(name, len, 5) &&
1353
- !strncasecmp(name, "git~1", 5))
1354
- return 1;
1332
+ /*
1333
+ * Note that when we don't find `.git` or `git~1` we end up with `name`
1334
+ * advanced partway through the string. That's okay, though, as we
1335
+ * return immediately in those cases, without looking at `name` any
1336
+ * further.
1337
+ */
1338
+ c = *(name++);
1339
+ if (c == '.') {
1340
+ /* .git */
1341
+ if (((c = *(name++)) != 'g' && c != 'G') ||
1342
+ ((c = *(name++)) != 'i' && c != 'I') ||
1343
+ ((c = *(name++)) != 't' && c != 'T'))
1344
return 0;
1356
- }
1345
+ } else if (c == 'g' || c == 'G') {
1346
+ /* git ~1 */
1347
+ if (((c = *(name++)) != 'i' && c != 'I') ||
1348
+ ((c = *(name++)) != 't' && c != 'T') ||
1349
+ *(name++) != '~' ||
1350
+ *(name++) != '1')
1351
+ return 0;
1352
+ } else
1353
+ return 0;
1354
+
1355
+ for (;;) {
1356
+ c = *(name++);
1357
+ if (!c || c == '\\' || c == '/' || c == ':')
1358
+ return 1;
1359
+ if (c != '.' && c != ' ')
1360
+ return 0;
1361
+ }
1362
}
1363
1364
static int is_ntfs_dot_generic(const char *name,