static struct common_dir common_list[] = {
{ 0, 1, 0, "branches" },
+ { 0, 1, 0, "common" },
{ 0, 1, 0, "hooks" },
{ 0, 1, 0, "info" },
{ 0, 0, 1, "info/sparse-checkout" },
{ 0, 1, 0, "objects" },
{ 0, 1, 0, "refs" },
{ 0, 1, 1, "refs/bisect" },
+ { 0, 1, 1, "refs/worktree" },
{ 0, 1, 0, "remotes" },
{ 0, 1, 0, "worktrees" },
{ 0, 1, 0, "rr-cache" },
strbuf_splice(buf, 0, buf->len,
repo->index_file, strlen(repo->index_file));
else if (dir_prefix(base, "objects"))
- replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
+ replace_dir(buf, git_dir_len + 7, repo->objects->odb->path);
else if (git_hooks_path && dir_prefix(base, "hooks"))
replace_dir(buf, git_dir_len + 5, git_hooks_path);
else if (repo->different_commondir)
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])) {
}
}
+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] & 0x80) {
+ /*
+ * 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] == '-';
return NULL;
}
-GIT_PATH_FUNC(git_path_cherry_pick_head, "CHERRY_PICK_HEAD")
-GIT_PATH_FUNC(git_path_revert_head, "REVERT_HEAD")
-GIT_PATH_FUNC(git_path_squash_msg, "SQUASH_MSG")
-GIT_PATH_FUNC(git_path_merge_msg, "MERGE_MSG")
-GIT_PATH_FUNC(git_path_merge_rr, "MERGE_RR")
-GIT_PATH_FUNC(git_path_merge_mode, "MERGE_MODE")
-GIT_PATH_FUNC(git_path_merge_head, "MERGE_HEAD")
-GIT_PATH_FUNC(git_path_fetch_head, "FETCH_HEAD")
-GIT_PATH_FUNC(git_path_shallow, "shallow")
+REPO_GIT_PATH_FUNC(cherry_pick_head, "CHERRY_PICK_HEAD")
+REPO_GIT_PATH_FUNC(revert_head, "REVERT_HEAD")
+REPO_GIT_PATH_FUNC(squash_msg, "SQUASH_MSG")
+REPO_GIT_PATH_FUNC(merge_msg, "MERGE_MSG")
+REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR")
+REPO_GIT_PATH_FUNC(merge_mode, "MERGE_MODE")
+REPO_GIT_PATH_FUNC(merge_head, "MERGE_HEAD")
+REPO_GIT_PATH_FUNC(fetch_head, "FETCH_HEAD")
+REPO_GIT_PATH_FUNC(shallow, "shallow")