Sync with Git 2.17.1

* maint: (25 commits)
  Git 2.17.1
  Git 2.16.4
  Git 2.15.2
  Git 2.14.4
  Git 2.13.7
  fsck: complain when .gitmodules is a symlink
  index-pack: check .gitmodules files with --strict
  unpack-objects: call fsck_finish() after fscking objects
  fsck: call fsck_finish() after fscking objects
  fsck: check .gitmodules content
  fsck: handle promisor objects in .gitmodules check
  fsck: detect gitmodules files
  fsck: actually fsck blob data
  fsck: simplify ".git" check
  index-pack: make fsck error message more specific
  verify_path: disallow symlinks in .gitmodules
  update-index: stat updated files earlier
  verify_dotfile: mention case-insensitivity in comment
  verify_path: drop clever fallthrough
  skip_prefix: add case-insensitive variant
  ...
This commit is contained in:
Junio C Hamano
2018-05-29 17:09:58 +09:00
28 changed files with 801 additions and 79 deletions

86
path.c
View File

@ -1306,7 +1306,7 @@ static int only_spaces_and_periods(const char *path, size_t len, size_t skip)
int is_ntfs_dotgit(const char *name)
{
int len;
size_t len;
for (len = 0; ; len++)
if (!name[len] || name[len] == '\\' || is_dir_sep(name[len])) {
@ -1323,6 +1323,90 @@ int is_ntfs_dotgit(const char *name)
}
}
static int is_ntfs_dot_generic(const char *name,
const char *dotgit_name,
size_t len,
const char *dotgit_ntfs_shortname_prefix)
{
int saw_tilde;
size_t i;
if ((name[0] == '.' && !strncasecmp(name + 1, dotgit_name, len))) {
i = len + 1;
only_spaces_and_periods:
for (;;) {
char c = name[i++];
if (!c)
return 1;
if (c != ' ' && c != '.')
return 0;
}
}
/*
* Is it a regular NTFS short name, i.e. shortened to 6 characters,
* followed by ~1, ... ~4?
*/
if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' &&
name[7] >= '1' && name[7] <= '4') {
i = 8;
goto only_spaces_and_periods;
}
/*
* Is it a fall-back NTFS short name (for details, see
* https://en.wikipedia.org/wiki/8.3_filename?
*/
for (i = 0, saw_tilde = 0; i < 8; i++)
if (name[i] == '\0')
return 0;
else if (saw_tilde) {
if (name[i] < '0' || name[i] > '9')
return 0;
} else if (name[i] == '~') {
if (name[++i] < '1' || name[i] > '9')
return 0;
saw_tilde = 1;
} else if (i >= 6)
return 0;
else if (name[i] < 0) {
/*
* We know our needles contain only ASCII, so we clamp
* here to make the results of tolower() sane.
*/
return 0;
} else if (tolower(name[i]) != dotgit_ntfs_shortname_prefix[i])
return 0;
goto only_spaces_and_periods;
}
/*
* Inline helper to make sure compiler resolves strlen() on literals at
* compile time.
*/
static inline int is_ntfs_dot_str(const char *name, const char *dotgit_name,
const char *dotgit_ntfs_shortname_prefix)
{
return is_ntfs_dot_generic(name, dotgit_name, strlen(dotgit_name),
dotgit_ntfs_shortname_prefix);
}
int is_ntfs_dotgitmodules(const char *name)
{
return is_ntfs_dot_str(name, "gitmodules", "gi7eba");
}
int is_ntfs_dotgitignore(const char *name)
{
return is_ntfs_dot_str(name, "gitignore", "gi250a");
}
int is_ntfs_dotgitattributes(const char *name)
{
return is_ntfs_dot_str(name, "gitattributes", "gi7d29");
}
int looks_like_command_line_option(const char *str)
{
return str && str[0] == '-';