#include "object-file.h"
#include "object-name.h"
#include "odb.h"
-#include "path.h"
#include "protocol.h"
#include "commit-reach.h"
#include "server-info.h"
#include "trace2.h"
#include "worktree.h"
#include "shallow.h"
+#include "setup.h"
#include "parse-options.h"
static const char * const receive_pack_usage[] = {
#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "archive.h"
-#include "path.h"
#include "pkt-line.h"
+#include "setup.h"
#include "sideband.h"
#include "run-command.h"
#include "strvec.h"
#include "gettext.h"
#include "pkt-line.h"
#include "parse-options.h"
-#include "path.h"
#include "protocol.h"
#include "replace-object.h"
#include "upload-pack.h"
#include "serve.h"
+#include "setup.h"
#include "commit.h"
#include "environment.h"
#include "run-command.h"
#include "string-list.h"
#include "url.h"
+#include "setup.h"
#include "strvec.h"
#include "packfile.h"
#include "odb.h"
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)
{
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 *relative_path(const char *in, const char *prefix, struct strbuf *sb);
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
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;
/*
void set_git_dir(const char *path, int make_realpath);
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(void);
char *prefix_path(const char *prefix, int len, const char *path);