Skip to content

Commit

Permalink
Merge pull request git-for-windows#3472 from dscho/expand-runtime-prefix
Browse files Browse the repository at this point in the history
Re-do the path interpolation support regarding RUNTIME_PREFIX
  • Loading branch information
dscho authored Oct 15, 2021
2 parents c7d0a86 + 6319bce commit 3f28c5f
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 34 deletions.
9 changes: 9 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,15 @@ pathname::
tilde expansion happens to such a string: `~/`
is expanded to the value of `$HOME`, and `~user/` to the
specified user's home directory.
+
If a path starts with `%(prefix)/`, the remainder is interpreted as a
path relative to Git's "runtime prefix", i.e. relative to the location
where Git itself was installed. For example, `%(prefix)/bin/` refers to
the directory in which the Git executable itself lives. If Git was
compiled without runtime prefix support, the compiled-in prefix will be
subsituted instead. In the unlikely event that a literal path needs to
be specified that should _not_ be expanded, it needs to be prefixed by
`./`, like so: `./%(prefix)/bin`.


Variables
Expand Down
2 changes: 1 addition & 1 deletion builtin/credential-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static char *get_socket_path(void)
{
struct stat sb;
char *old_dir, *socket;
old_dir = expand_user_path("~/.git-credential-cache", 0);
old_dir = interpolate_path("~/.git-credential-cache", 0);
if (old_dir && !stat(old_dir, &sb) && S_ISDIR(sb.st_mode))
socket = xstrfmt("%s/socket", old_dir);
else
Expand Down
2 changes: 1 addition & 1 deletion builtin/credential-store.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ int cmd_credential_store(int argc, const char **argv, const char *prefix)
if (file) {
string_list_append(&fns, file);
} else {
if ((file = expand_user_path("~/.git-credentials", 0)))
if ((file = interpolate_path("~/.git-credentials", 0)))
string_list_append_nodup(&fns, file);
file = xdg_config_home("credentials");
if (file)
Expand Down
2 changes: 1 addition & 1 deletion builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1542,7 +1542,7 @@ static char *launchctl_service_filename(const char *name)
struct strbuf filename = STRBUF_INIT;
strbuf_addf(&filename, "~/Library/LaunchAgents/%s.plist", name);

expanded = expand_user_path(filename.buf, 1);
expanded = interpolate_path(filename.buf, 1);
if (!expanded)
die(_("failed to expand path '%s'"), filename.buf);

Expand Down
4 changes: 3 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,9 @@ typedef int create_file_fn(const char *path, void *cb);
int raceproof_create_file(const char *path, create_file_fn fn, void *cb);

int mkdir_in_gitdir(const char *path);
char *expand_user_path(const char *path, int real_home);
char *interpolate_path(const char *path, int real_home);
/* NEEDSWORK: remove this synonym once in-flight topics have migrated */
#define expand_user_path interpolate_path
const char *enter_repo(const char *path, int strict);
static inline int is_absolute_path(const char *path)
{
Expand Down
8 changes: 4 additions & 4 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc
if (!path)
return config_error_nonbool("include.path");

expanded = expand_user_path(path, 0);
expanded = interpolate_path(path, 0);
if (!expanded)
return error(_("could not expand include path '%s'"), path);
path = expanded;
Expand Down Expand Up @@ -184,7 +184,7 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
char *expanded;
int prefix = 0;

expanded = expand_user_path(pat->buf, 1);
expanded = interpolate_path(pat->buf, 1);
if (expanded) {
strbuf_reset(pat);
strbuf_addstr(pat, expanded);
Expand Down Expand Up @@ -1269,7 +1269,7 @@ int git_config_pathname(const char **dest, const char *var, const char *value)
{
if (!value)
return config_error_nonbool(var);
*dest = expand_user_path(value, 0);
*dest = interpolate_path(value, 0);
if (!*dest)
die(_("failed to expand user dir in: '%s'"), value);
return 0;
Expand Down Expand Up @@ -1842,7 +1842,7 @@ void git_global_config(char **user_out, char **xdg_out)
char *xdg_config = NULL;

if (!user_config) {
user_config = expand_user_path("~/.gitconfig", 0);
user_config = interpolate_path("~/.gitconfig", 0);
xdg_config = xdg_config_home("config");
}

Expand Down
22 changes: 15 additions & 7 deletions path.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,22 +720,30 @@ static struct passwd *getpw_str(const char *username, size_t len)
}

/*
* Return a string with ~ and ~user expanded via getpw*. If buf != NULL,
* then it is a newly allocated string. Returns NULL on getpw failure or
* if path is NULL.
* Return a string with ~ and ~user expanded via getpw*. Returns NULL on getpw
* failure or if path is NULL.
*
* If real_home is true, strbuf_realpath($HOME) is used in the expansion.
* If real_home is true, strbuf_realpath($HOME) is used in the `~/` expansion.
*
* If the path starts with `%(prefix)/`, the remainder is interpreted as
* relative to where Git is installed, and expanded to the absolute path.
*/
char *expand_user_path(const char *path, int real_home)
char *interpolate_path(const char *path, int real_home)
{
struct strbuf user_path = STRBUF_INIT;
const char *to_copy = path;

if (path == NULL)
goto return_null;

if (skip_prefix(path, "%(prefix)/", &path))
return system_path(path);

#ifdef __MINGW32__
if (path[0] == '/')
if (path[0] == '/') {
warning(_("encountered old-style '%s' that should be '%%(prefix)%s'"), path, path);
return system_path(path + 1);
}
#endif
if (path[0] == '~') {
const char *first_slash = strchrnul(path, '/');
Expand Down Expand Up @@ -817,7 +825,7 @@ const char *enter_repo(const char *path, int strict)
strbuf_add(&validated_path, path, len);

if (used_path.buf[0] == '~') {
char *newpath = expand_user_path(used_path.buf, 0);
char *newpath = interpolate_path(used_path.buf, 0);
if (!newpath)
return NULL;
strbuf_attach(&used_path, newpath, strlen(newpath),
Expand Down
2 changes: 1 addition & 1 deletion sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ N_("Your name and email address were configured automatically based\n"

static const char *implicit_ident_advice(void)
{
char *user_config = expand_user_path("~/.gitconfig", 0);
char *user_config = interpolate_path("~/.gitconfig", 0);
char *xdg_config = xdg_config_home("config");
int config_exists = file_exists(user_config) || file_exists(xdg_config);

Expand Down
44 changes: 26 additions & 18 deletions t/t0060-path-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,32 @@ test_expect_success MINGW 'is_valid_path() on Windows' '
"PRN./abc"
'

test_lazy_prereq RUNTIME_PREFIX '
test true = "$RUNTIME_PREFIX"
'

test_lazy_prereq CAN_EXEC_IN_PWD '
cp "$GIT_EXEC_PATH"/git$X ./ &&
./git rev-parse
'

test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
mkdir -p pretend/bin pretend/libexec/git-core &&
echo "echo HERE" | write_script pretend/libexec/git-core/git-here &&
cp "$GIT_EXEC_PATH"/git$X pretend/bin/ &&
GIT_EXEC_PATH= ./pretend/bin/git here >actual &&
echo HERE >expect &&
test_cmp expect actual'

test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' '
mkdir -p pretend/bin &&
cp "$GIT_EXEC_PATH"/git$X pretend/bin/ &&
git config yes.path "%(prefix)/yes" &&
GIT_EXEC_PATH= ./pretend/bin/git config --path yes.path >actual &&
echo "$(pwd)/pretend/yes" >expect &&
test_cmp expect actual
'

test_expect_success MINGW 'MSYSTEM/PATH is adjusted if necessary' '
mkdir -p "$HOME"/bin pretend/mingw64/bin \
pretend/mingw64/libexec/git-core pretend/usr/bin &&
Expand All @@ -545,22 +571,4 @@ test_expect_success MINGW 'MSYSTEM/PATH is adjusted if necessary' '
test_cmp expect actual
'

test_lazy_prereq RUNTIME_PREFIX '
test true = "$RUNTIME_PREFIX"
'

test_lazy_prereq CAN_EXEC_IN_PWD '
cp "$GIT_EXEC_PATH"/git$X ./ &&
./git rev-parse
'

test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
mkdir -p pretend/git pretend/libexec/git-core &&
echo "echo HERE" | write_script pretend/libexec/git-core/git-here &&
cp "$GIT_EXEC_PATH"/git$X pretend/git/ &&
GIT_EXEC_PATH= ./pretend/git/git here >actual &&
echo HERE >expect &&
test_cmp expect actual
'

test_done

0 comments on commit 3f28c5f

Please sign in to comment.