path: move enter_repo() into "setup.c"

The function `enter_repo()` is used to enter a repository at a given
path. As such it sits way closer to setting up a repository than it does
with handling paths, but regardless of that it's located in "path.c"
instead of in "setup.c".

Move the function into "setup.c".

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2025-11-19 08:50:49 +01:00
committed by Junio C Hamano
parent c6def6a055
commit 831e02340b
8 changed files with 123 additions and 118 deletions

100
path.c
View File

@@ -738,106 +738,6 @@ return_null:
return NULL;
}
/*
* First, one directory to try is determined by the following algorithm.
*
* (0) If "strict" is given, the path is used as given and no DWIM is
* done. Otherwise:
* (1) "~/path" to mean path under the running user's home directory;
* (2) "~user/path" to mean path under named user's home directory;
* (3) "relative/path" to mean cwd relative directory; or
* (4) "/absolute/path" to mean absolute directory.
*
* Unless "strict" is given, we check "%s/.git", "%s", "%s.git/.git", "%s.git"
* in this order. We select the first one that is a valid git repository, and
* chdir() to it. If none match, or we fail to chdir, we return NULL.
*
* If all goes well, we return the directory we used to chdir() (but
* before ~user is expanded), avoiding getcwd() resolving symbolic
* links. User relative paths are also returned as they are given,
* except DWIM suffixing.
*/
const char *enter_repo(const char *path, unsigned flags)
{
static struct strbuf validated_path = STRBUF_INIT;
static struct strbuf used_path = STRBUF_INIT;
if (!path)
return NULL;
if (!(flags & ENTER_REPO_STRICT)) {
static const char *suffix[] = {
"/.git", "", ".git/.git", ".git", NULL,
};
const char *gitfile;
int len = strlen(path);
int i;
while ((1 < len) && (path[len-1] == '/'))
len--;
/*
* We can handle arbitrary-sized buffers, but this remains as a
* sanity check on untrusted input.
*/
if (PATH_MAX <= len)
return NULL;
strbuf_reset(&used_path);
strbuf_reset(&validated_path);
strbuf_add(&used_path, path, len);
strbuf_add(&validated_path, path, len);
if (used_path.buf[0] == '~') {
char *newpath = interpolate_path(used_path.buf, 0);
if (!newpath)
return NULL;
strbuf_attach(&used_path, newpath, strlen(newpath),
strlen(newpath));
}
for (i = 0; suffix[i]; i++) {
struct stat st;
size_t baselen = used_path.len;
strbuf_addstr(&used_path, suffix[i]);
if (!stat(used_path.buf, &st) &&
(S_ISREG(st.st_mode) ||
(S_ISDIR(st.st_mode) && is_git_directory(used_path.buf)))) {
strbuf_addstr(&validated_path, suffix[i]);
break;
}
strbuf_setlen(&used_path, baselen);
}
if (!suffix[i])
return NULL;
gitfile = read_gitfile(used_path.buf);
if (!(flags & ENTER_REPO_ANY_OWNER_OK))
die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
if (gitfile) {
strbuf_reset(&used_path);
strbuf_addstr(&used_path, gitfile);
}
if (chdir(used_path.buf))
return NULL;
path = validated_path.buf;
}
else {
const char *gitfile = read_gitfile(path);
if (!(flags & ENTER_REPO_ANY_OWNER_OK))
die_upon_dubious_ownership(gitfile, NULL, path);
if (gitfile)
path = gitfile;
if (chdir(path))
return NULL;
}
if (is_git_directory(".")) {
set_git_dir(".", 0);
check_repository_format(NULL);
return path;
}
return NULL;
}
int calc_shared_perm(struct repository *repo,
int mode)
{