diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2023-02-20 08:08:13 -0800 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2023-02-20 09:29:08 -0800 |
commit | be3a78cc933169bab12dccdfcbb173cb48261103 (patch) | |
tree | 88502891803a2a23ce65a33e045a142202115278 /src | |
parent | 1be70649432afc0dbac4fdd7d3d50d4881f3c634 (diff) | |
download | libgit2-be3a78cc933169bab12dccdfcbb173cb48261103.tar.gz |
repo: support safe.directory with %(prefix)/
Git for Windows does some truly bizarre things with
paths that start with a forward slash; and expects you
to escape that with `%(prefix)`. This syntax generally
means to add the prefix that Git was installed to -- eg
`/usr/local` -- unless it's an absolute path, in which
case the leading `%(prefix)/` is just removed. And Git
for Windows expects you to use this syntax for absolute
Unix-style paths (in "Git Bash" or Windows Subsystem for
Linux).
Worse, the behavior used to be that a leading `/` was
not absolute. It would indicate that Git for Windows
should add the prefix. So `//` is required for absolute
Unix-style paths. Yes, this is truly horrifying.
Emulate that behavior, I guess, but only for absolute
paths. We won't deal with the Git install prefix. Also,
give WSL users an escape hatch where they don't have to
think about this and can use the literal path that the
filesystem APIs provide (`//wsl.localhost/...`).
Diffstat (limited to 'src')
-rw-r--r-- | src/libgit2/repository.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index c02662bda..186b3d4ec 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -496,14 +496,47 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload) { validate_ownership_data *data = payload; - if (strcmp(entry->value, "") == 0) + if (strcmp(entry->value, "") == 0) { *data->is_safe = false; - - if (strcmp(entry->value, "*") == 0) - *data->is_safe = true; - else if (git_fs_path_prettify_dir(&data->tmp, entry->value, NULL) == 0 && - strcmp(data->tmp.ptr, data->repo_path) == 0) + } else if (strcmp(entry->value, "*") == 0) { *data->is_safe = true; + } else { + const char *test_path = entry->value; + +#ifdef GIT_WIN32 + /* + * Git for Windows does some truly bizarre things with + * paths that start with a forward slash; and expects you + * to escape that with `%(prefix)`. This syntax generally + * means to add the prefix that Git was installed to -- eg + * `/usr/local` -- unless it's an absolute path, in which + * case the leading `%(prefix)/` is just removed. And Git + * for Windows expects you to use this syntax for absolute + * Unix-style paths (in "Git Bash" or Windows Subsystem for + * Linux). + * + * Worse, the behavior used to be that a leading `/` was + * not absolute. It would indicate that Git for Windows + * should add the prefix. So `//` is required for absolute + * Unix-style paths. Yes, this is truly horrifying. + * + * Emulate that behavior, I guess, but only for absolute + * paths. We won't deal with the Git install prefix. Also, + * give WSL users an escape hatch where they don't have to + * think about this and can use the literal path that the + * filesystem APIs provide (`//wsl.localhost/...`). + */ + if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0) + test_path += strlen("%(prefix)/"); + else if (strncmp(test_path, "//", 2) == 0 && + strncmp(test_path, "//wsl.localhost/", strlen("//wsl.localhost/")) != 0) + test_path++; +#endif + + if (git_fs_path_prettify_dir(&data->tmp, test_path, NULL) == 0 && + strcmp(data->tmp.ptr, data->repo_path) == 0) + *data->is_safe = true; + } return 0; } |