Skip to content

Commit 831e023

Browse files
pks-tgitster
authored andcommitted
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>
1 parent c6def6a commit 831e023

8 files changed

Lines changed: 123 additions & 118 deletions

File tree

builtin/receive-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434
#include "object-file.h"
3535
#include "object-name.h"
3636
#include "odb.h"
37-
#include "path.h"
3837
#include "protocol.h"
3938
#include "commit-reach.h"
4039
#include "server-info.h"
4140
#include "trace.h"
4241
#include "trace2.h"
4342
#include "worktree.h"
4443
#include "shallow.h"
44+
#include "setup.h"
4545
#include "parse-options.h"
4646

4747
static const char * const receive_pack_usage[] = {

builtin/upload-archive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#define USE_THE_REPOSITORY_VARIABLE
55
#include "builtin.h"
66
#include "archive.h"
7-
#include "path.h"
87
#include "pkt-line.h"
8+
#include "setup.h"
99
#include "sideband.h"
1010
#include "run-command.h"
1111
#include "strvec.h"

builtin/upload-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
#include "gettext.h"
66
#include "pkt-line.h"
77
#include "parse-options.h"
8-
#include "path.h"
98
#include "protocol.h"
109
#include "replace-object.h"
1110
#include "upload-pack.h"
1211
#include "serve.h"
12+
#include "setup.h"
1313
#include "commit.h"
1414
#include "environment.h"
1515

http-backend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "run-command.h"
1717
#include "string-list.h"
1818
#include "url.h"
19+
#include "setup.h"
1920
#include "strvec.h"
2021
#include "packfile.h"
2122
#include "odb.h"

path.c

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -738,106 +738,6 @@ char *interpolate_path(const char *path, int real_home)
738738
return NULL;
739739
}
740740

741-
/*
742-
* First, one directory to try is determined by the following algorithm.
743-
*
744-
* (0) If "strict" is given, the path is used as given and no DWIM is
745-
* done. Otherwise:
746-
* (1) "~/path" to mean path under the running user's home directory;
747-
* (2) "~user/path" to mean path under named user's home directory;
748-
* (3) "relative/path" to mean cwd relative directory; or
749-
* (4) "/absolute/path" to mean absolute directory.
750-
*
751-
* Unless "strict" is given, we check "%s/.git", "%s", "%s.git/.git", "%s.git"
752-
* in this order. We select the first one that is a valid git repository, and
753-
* chdir() to it. If none match, or we fail to chdir, we return NULL.
754-
*
755-
* If all goes well, we return the directory we used to chdir() (but
756-
* before ~user is expanded), avoiding getcwd() resolving symbolic
757-
* links. User relative paths are also returned as they are given,
758-
* except DWIM suffixing.
759-
*/
760-
const char *enter_repo(const char *path, unsigned flags)
761-
{
762-
static struct strbuf validated_path = STRBUF_INIT;
763-
static struct strbuf used_path = STRBUF_INIT;
764-
765-
if (!path)
766-
return NULL;
767-
768-
if (!(flags & ENTER_REPO_STRICT)) {
769-
static const char *suffix[] = {
770-
"/.git", "", ".git/.git", ".git", NULL,
771-
};
772-
const char *gitfile;
773-
int len = strlen(path);
774-
int i;
775-
while ((1 < len) && (path[len-1] == '/'))
776-
len--;
777-
778-
/*
779-
* We can handle arbitrary-sized buffers, but this remains as a
780-
* sanity check on untrusted input.
781-
*/
782-
if (PATH_MAX <= len)
783-
return NULL;
784-
785-
strbuf_reset(&used_path);
786-
strbuf_reset(&validated_path);
787-
strbuf_add(&used_path, path, len);
788-
strbuf_add(&validated_path, path, len);
789-
790-
if (used_path.buf[0] == '~') {
791-
char *newpath = interpolate_path(used_path.buf, 0);
792-
if (!newpath)
793-
return NULL;
794-
strbuf_attach(&used_path, newpath, strlen(newpath),
795-
strlen(newpath));
796-
}
797-
for (i = 0; suffix[i]; i++) {
798-
struct stat st;
799-
size_t baselen = used_path.len;
800-
strbuf_addstr(&used_path, suffix[i]);
801-
if (!stat(used_path.buf, &st) &&
802-
(S_ISREG(st.st_mode) ||
803-
(S_ISDIR(st.st_mode) && is_git_directory(used_path.buf)))) {
804-
strbuf_addstr(&validated_path, suffix[i]);
805-
break;
806-
}
807-
strbuf_setlen(&used_path, baselen);
808-
}
809-
if (!suffix[i])
810-
return NULL;
811-
gitfile = read_gitfile(used_path.buf);
812-
if (!(flags & ENTER_REPO_ANY_OWNER_OK))
813-
die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
814-
if (gitfile) {
815-
strbuf_reset(&used_path);
816-
strbuf_addstr(&used_path, gitfile);
817-
}
818-
if (chdir(used_path.buf))
819-
return NULL;
820-
path = validated_path.buf;
821-
}
822-
else {
823-
const char *gitfile = read_gitfile(path);
824-
if (!(flags & ENTER_REPO_ANY_OWNER_OK))
825-
die_upon_dubious_ownership(gitfile, NULL, path);
826-
if (gitfile)
827-
path = gitfile;
828-
if (chdir(path))
829-
return NULL;
830-
}
831-
832-
if (is_git_directory(".")) {
833-
set_git_dir(".", 0);
834-
check_repository_format(NULL);
835-
return path;
836-
}
837-
838-
return NULL;
839-
}
840-
841741
int calc_shared_perm(struct repository *repo,
842742
int mode)
843743
{

path.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,6 @@ int adjust_shared_perm(struct repository *repo, const char *path);
146146

147147
char *interpolate_path(const char *path, int real_home);
148148

149-
/* The bits are as follows:
150-
*
151-
* - ENTER_REPO_STRICT: callers that require exact paths (as opposed
152-
* to allowing known suffixes like ".git", ".git/.git" to be
153-
* omitted) can set this bit.
154-
*
155-
* - ENTER_REPO_ANY_OWNER_OK: callers that are willing to run without
156-
* ownership check can set this bit.
157-
*/
158-
enum {
159-
ENTER_REPO_STRICT = (1<<0),
160-
ENTER_REPO_ANY_OWNER_OK = (1<<1),
161-
};
162-
163-
const char *enter_repo(const char *path, unsigned flags);
164149
const char *remove_leading_path(const char *in, const char *prefix);
165150
const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
166151
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);

setup.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,87 @@ void set_git_dir(const char *path, int make_realpath)
17031703
strbuf_release(&realpath);
17041704
}
17051705

1706+
const char *enter_repo(const char *path, unsigned flags)
1707+
{
1708+
static struct strbuf validated_path = STRBUF_INIT;
1709+
static struct strbuf used_path = STRBUF_INIT;
1710+
1711+
if (!path)
1712+
return NULL;
1713+
1714+
if (!(flags & ENTER_REPO_STRICT)) {
1715+
static const char *suffix[] = {
1716+
"/.git", "", ".git/.git", ".git", NULL,
1717+
};
1718+
const char *gitfile;
1719+
int len = strlen(path);
1720+
int i;
1721+
while ((1 < len) && (path[len-1] == '/'))
1722+
len--;
1723+
1724+
/*
1725+
* We can handle arbitrary-sized buffers, but this remains as a
1726+
* sanity check on untrusted input.
1727+
*/
1728+
if (PATH_MAX <= len)
1729+
return NULL;
1730+
1731+
strbuf_reset(&used_path);
1732+
strbuf_reset(&validated_path);
1733+
strbuf_add(&used_path, path, len);
1734+
strbuf_add(&validated_path, path, len);
1735+
1736+
if (used_path.buf[0] == '~') {
1737+
char *newpath = interpolate_path(used_path.buf, 0);
1738+
if (!newpath)
1739+
return NULL;
1740+
strbuf_attach(&used_path, newpath, strlen(newpath),
1741+
strlen(newpath));
1742+
}
1743+
for (i = 0; suffix[i]; i++) {
1744+
struct stat st;
1745+
size_t baselen = used_path.len;
1746+
strbuf_addstr(&used_path, suffix[i]);
1747+
if (!stat(used_path.buf, &st) &&
1748+
(S_ISREG(st.st_mode) ||
1749+
(S_ISDIR(st.st_mode) && is_git_directory(used_path.buf)))) {
1750+
strbuf_addstr(&validated_path, suffix[i]);
1751+
break;
1752+
}
1753+
strbuf_setlen(&used_path, baselen);
1754+
}
1755+
if (!suffix[i])
1756+
return NULL;
1757+
gitfile = read_gitfile(used_path.buf);
1758+
if (!(flags & ENTER_REPO_ANY_OWNER_OK))
1759+
die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
1760+
if (gitfile) {
1761+
strbuf_reset(&used_path);
1762+
strbuf_addstr(&used_path, gitfile);
1763+
}
1764+
if (chdir(used_path.buf))
1765+
return NULL;
1766+
path = validated_path.buf;
1767+
}
1768+
else {
1769+
const char *gitfile = read_gitfile(path);
1770+
if (!(flags & ENTER_REPO_ANY_OWNER_OK))
1771+
die_upon_dubious_ownership(gitfile, NULL, path);
1772+
if (gitfile)
1773+
path = gitfile;
1774+
if (chdir(path))
1775+
return NULL;
1776+
}
1777+
1778+
if (is_git_directory(".")) {
1779+
set_git_dir(".", 0);
1780+
check_repository_format(NULL);
1781+
return path;
1782+
}
1783+
1784+
return NULL;
1785+
}
1786+
17061787
static int git_work_tree_initialized;
17071788

17081789
/*

setup.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,44 @@ static inline int discover_git_directory(struct strbuf *commondir,
9797
void set_git_dir(const char *path, int make_realpath);
9898
void set_git_work_tree(const char *tree);
9999

100+
/* Flags that can be passed to `enter_repo()`. */
101+
enum {
102+
/*
103+
* Callers that require exact paths (as opposed to allowing known
104+
* suffixes like ".git", ".git/.git" to be omitted) can set this bit.
105+
*/
106+
ENTER_REPO_STRICT = (1<<0),
107+
108+
/*
109+
* Callers that are willing to run without ownership check can set this
110+
* bit.
111+
*/
112+
ENTER_REPO_ANY_OWNER_OK = (1<<1),
113+
};
114+
115+
/*
116+
* Discover and enter a repository.
117+
*
118+
* First, one directory to try is determined by the following algorithm.
119+
*
120+
* (0) If "strict" is given, the path is used as given and no DWIM is
121+
* done. Otherwise:
122+
* (1) "~/path" to mean path under the running user's home directory;
123+
* (2) "~user/path" to mean path under named user's home directory;
124+
* (3) "relative/path" to mean cwd relative directory; or
125+
* (4) "/absolute/path" to mean absolute directory.
126+
*
127+
* Unless "strict" is given, we check "%s/.git", "%s", "%s.git/.git", "%s.git"
128+
* in this order. We select the first one that is a valid git repository, and
129+
* chdir() to it. If none match, or we fail to chdir, we return NULL.
130+
*
131+
* If all goes well, we return the directory we used to chdir() (but
132+
* before ~user is expanded), avoiding getcwd() resolving symbolic
133+
* links. User relative paths are also returned as they are given,
134+
* except DWIM suffixing.
135+
*/
136+
const char *enter_repo(const char *path, unsigned flags);
137+
100138
const char *setup_git_directory_gently(int *);
101139
const char *setup_git_directory(void);
102140
char *prefix_path(const char *prefix, int len, const char *path);

0 commit comments

Comments
 (0)