]> git.ipfire.org Git - thirdparty/git.git/commitdiff
path: move `enter_repo()` into "setup.c"
authorPatrick Steinhardt <ps@pks.im>
Wed, 19 Nov 2025 07:50:49 +0000 (08:50 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 20 Nov 2025 01:41:03 +0000 (17:41 -0800)
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>
builtin/receive-pack.c
builtin/upload-archive.c
builtin/upload-pack.c
http-backend.c
path.c
path.h
setup.c
setup.h

index c9288a9c7e382bd19193d8b94268e0d0bec2c7f8..79a0fd4756665d8db734d0afb4b666a04ef9f8c2 100644 (file)
@@ -34,7 +34,6 @@
 #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"
@@ -42,6 +41,7 @@
 #include "trace2.h"
 #include "worktree.h"
 #include "shallow.h"
+#include "setup.h"
 #include "parse-options.h"
 
 static const char * const receive_pack_usage[] = {
index 97d7c9522f98684c9f749351798839f7935dcee8..25312bb2a528878a03071bddcbc7ced7eb479d0d 100644 (file)
@@ -4,8 +4,8 @@
 #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"
index c2bbc035ab0c91baf5d66cee8bb370ecf1640505..30498fafea3a8b024b5cc8a8d2da7948325ac6c5 100644 (file)
@@ -5,11 +5,11 @@
 #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"
 
index 52f0483dd309d73a1866a1b63161df0fe63d389f..e9d1ef92bd8dc1a45b9ab949322fb6cf2a17f70a 100644 (file)
@@ -16,6 +16,7 @@
 #include "run-command.h"
 #include "string-list.h"
 #include "url.h"
+#include "setup.h"
 #include "strvec.h"
 #include "packfile.h"
 #include "odb.h"
diff --git a/path.c b/path.c
index 7f56eaf9930374274042b5af8cfb7219659d1272..d726537622cda67f222229358b8b7edd25c34f1b 100644 (file)
--- a/path.c
+++ b/path.c
@@ -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)
 {
diff --git a/path.h b/path.h
index e67348f25397cc53bfa24c1908283e6f5420a2c3..0ec95a0b079c905ec82b0f5455b8663827b70db7 100644 (file)
--- a/path.h
+++ b/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);
 
-/* 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);
diff --git a/setup.c b/setup.c
index 7086741e6c2d1f5c73e484b76e1a1272f7d0697d..98c6fd8ee4c02d542746a40e2c94dd90a8bb3e62 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -1703,6 +1703,87 @@ void set_git_dir(const char *path, int make_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;
 
 /*
diff --git a/setup.h b/setup.h
index 8522fa8575da7123d0a9dc57dbabf08677a58eaa..bfea199bcd8769658ffd6e7fcd4def894f667801 100644 (file)
--- a/setup.h
+++ b/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_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);