mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
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:
committed by
Junio C Hamano
parent
c6def6a055
commit
831e02340b
@@ -34,7 +34,6 @@
|
|||||||
#include "object-file.h"
|
#include "object-file.h"
|
||||||
#include "object-name.h"
|
#include "object-name.h"
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
#include "path.h"
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "commit-reach.h"
|
#include "commit-reach.h"
|
||||||
#include "server-info.h"
|
#include "server-info.h"
|
||||||
@@ -42,6 +41,7 @@
|
|||||||
#include "trace2.h"
|
#include "trace2.h"
|
||||||
#include "worktree.h"
|
#include "worktree.h"
|
||||||
#include "shallow.h"
|
#include "shallow.h"
|
||||||
|
#include "setup.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
|
||||||
static const char * const receive_pack_usage[] = {
|
static const char * const receive_pack_usage[] = {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
#define USE_THE_REPOSITORY_VARIABLE
|
#define USE_THE_REPOSITORY_VARIABLE
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "path.h"
|
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
|
#include "setup.h"
|
||||||
#include "sideband.h"
|
#include "sideband.h"
|
||||||
#include "run-command.h"
|
#include "run-command.h"
|
||||||
#include "strvec.h"
|
#include "strvec.h"
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
#include "path.h"
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "replace-object.h"
|
#include "replace-object.h"
|
||||||
#include "upload-pack.h"
|
#include "upload-pack.h"
|
||||||
#include "serve.h"
|
#include "serve.h"
|
||||||
|
#include "setup.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "run-command.h"
|
#include "run-command.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
#include "setup.h"
|
||||||
#include "strvec.h"
|
#include "strvec.h"
|
||||||
#include "packfile.h"
|
#include "packfile.h"
|
||||||
#include "odb.h"
|
#include "odb.h"
|
||||||
|
|||||||
100
path.c
100
path.c
@@ -738,106 +738,6 @@ return_null:
|
|||||||
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 calc_shared_perm(struct repository *repo,
|
||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
|
|||||||
15
path.h
15
path.h
@@ -146,21 +146,6 @@ int adjust_shared_perm(struct repository *repo, const char *path);
|
|||||||
|
|
||||||
char *interpolate_path(const char *path, int real_home);
|
char *interpolate_path(const char *path, int real_home);
|
||||||
|
|
||||||
/* The bits are as follows:
|
|
||||||
*
|
|
||||||
* - ENTER_REPO_STRICT: callers that require exact paths (as opposed
|
|
||||||
* to allowing known suffixes like ".git", ".git/.git" to be
|
|
||||||
* omitted) can set this bit.
|
|
||||||
*
|
|
||||||
* - ENTER_REPO_ANY_OWNER_OK: callers that are willing to run without
|
|
||||||
* ownership check can set this bit.
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
ENTER_REPO_STRICT = (1<<0),
|
|
||||||
ENTER_REPO_ANY_OWNER_OK = (1<<1),
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *enter_repo(const char *path, unsigned flags);
|
|
||||||
const char *remove_leading_path(const char *in, const char *prefix);
|
const char *remove_leading_path(const char *in, const char *prefix);
|
||||||
const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
|
const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
|
||||||
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
|
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
|
||||||
|
|||||||
81
setup.c
81
setup.c
@@ -1703,6 +1703,87 @@ void set_git_dir(const char *path, int make_realpath)
|
|||||||
strbuf_release(&realpath);
|
strbuf_release(&realpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
static int git_work_tree_initialized;
|
static int git_work_tree_initialized;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
38
setup.h
38
setup.h
@@ -97,6 +97,44 @@ static inline int discover_git_directory(struct strbuf *commondir,
|
|||||||
void set_git_dir(const char *path, int make_realpath);
|
void set_git_dir(const char *path, int make_realpath);
|
||||||
void set_git_work_tree(const char *tree);
|
void set_git_work_tree(const char *tree);
|
||||||
|
|
||||||
|
/* Flags that can be passed to `enter_repo()`. */
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* Callers that require exact paths (as opposed to allowing known
|
||||||
|
* suffixes like ".git", ".git/.git" to be omitted) can set this bit.
|
||||||
|
*/
|
||||||
|
ENTER_REPO_STRICT = (1<<0),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callers that are willing to run without ownership check can set this
|
||||||
|
* bit.
|
||||||
|
*/
|
||||||
|
ENTER_REPO_ANY_OWNER_OK = (1<<1),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Discover and enter a repository.
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
|
||||||
const char *setup_git_directory_gently(int *);
|
const char *setup_git_directory_gently(int *);
|
||||||
const char *setup_git_directory(void);
|
const char *setup_git_directory(void);
|
||||||
char *prefix_path(const char *prefix, int len, const char *path);
|
char *prefix_path(const char *prefix, int len, const char *path);
|
||||||
|
|||||||
Reference in New Issue
Block a user