Merge branch 'js/expand-runtime-prefix'
Pathname expansion (like "~username/") learned a way to specify a location relative to Git installation (e.g. its $sharedir which is $(prefix)/share), with "%(prefix)". * js/expand-runtime-prefix: expand_user_path: allow in-flight topics to keep using the old name interpolate_path(): allow specifying paths relative to the runtime prefix Use a better name for the function interpolating paths expand_user_path(): clarify the role of the `real_home` parameter expand_user_path(): remove stale part of the comment tests: exercise the RUNTIME_PREFIX featuremaint
						commit
						aab0eeaba5
					
				|  | @ -298,6 +298,15 @@ pathname:: | ||||||
| 	tilde expansion happens to such a string: `~/` | 	tilde expansion happens to such a string: `~/` | ||||||
| 	is expanded to the value of `$HOME`, and `~user/` to the | 	is expanded to the value of `$HOME`, and `~user/` to the | ||||||
| 	specified user's home directory. | 	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 | Variables | ||||||
|  |  | ||||||
							
								
								
									
										5
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										5
									
								
								Makefile
								
								
								
								
							|  | @ -2848,6 +2848,11 @@ ifdef GIT_TEST_INDEX_VERSION | ||||||
| endif | endif | ||||||
| ifdef GIT_TEST_PERL_FATAL_WARNINGS | ifdef GIT_TEST_PERL_FATAL_WARNINGS | ||||||
| 	@echo GIT_TEST_PERL_FATAL_WARNINGS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_PERL_FATAL_WARNINGS)))'\' >>$@+ | 	@echo GIT_TEST_PERL_FATAL_WARNINGS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_PERL_FATAL_WARNINGS)))'\' >>$@+ | ||||||
|  | endif | ||||||
|  | ifdef RUNTIME_PREFIX | ||||||
|  | 	@echo RUNTIME_PREFIX=\'true\' >>$@+ | ||||||
|  | else | ||||||
|  | 	@echo RUNTIME_PREFIX=\'false\' >>$@+ | ||||||
| endif | endif | ||||||
| 	@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi | 	@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -90,7 +90,7 @@ static char *get_socket_path(void) | ||||||
| { | { | ||||||
| 	struct stat sb; | 	struct stat sb; | ||||||
| 	char *old_dir, *socket; | 	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)) | 	if (old_dir && !stat(old_dir, &sb) && S_ISDIR(sb.st_mode)) | ||||||
| 		socket = xstrfmt("%s/socket", old_dir); | 		socket = xstrfmt("%s/socket", old_dir); | ||||||
| 	else | 	else | ||||||
|  |  | ||||||
|  | @ -173,7 +173,7 @@ int cmd_credential_store(int argc, const char **argv, const char *prefix) | ||||||
| 	if (file) { | 	if (file) { | ||||||
| 		string_list_append(&fns, file); | 		string_list_append(&fns, file); | ||||||
| 	} else { | 	} else { | ||||||
| 		if ((file = expand_user_path("~/.git-credentials", 0))) | 		if ((file = interpolate_path("~/.git-credentials", 0))) | ||||||
| 			string_list_append_nodup(&fns, file); | 			string_list_append_nodup(&fns, file); | ||||||
| 		file = xdg_config_home("credentials"); | 		file = xdg_config_home("credentials"); | ||||||
| 		if (file) | 		if (file) | ||||||
|  |  | ||||||
|  | @ -1542,7 +1542,7 @@ static char *launchctl_service_filename(const char *name) | ||||||
| 	struct strbuf filename = STRBUF_INIT; | 	struct strbuf filename = STRBUF_INIT; | ||||||
| 	strbuf_addf(&filename, "~/Library/LaunchAgents/%s.plist", name); | 	strbuf_addf(&filename, "~/Library/LaunchAgents/%s.plist", name); | ||||||
|  |  | ||||||
| 	expanded = expand_user_path(filename.buf, 1); | 	expanded = interpolate_path(filename.buf, 1); | ||||||
| 	if (!expanded) | 	if (!expanded) | ||||||
| 		die(_("failed to expand path '%s'"), filename.buf); | 		die(_("failed to expand path '%s'"), filename.buf); | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										4
									
								
								cache.h
								
								
								
								
							|  | @ -1255,7 +1255,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 raceproof_create_file(const char *path, create_file_fn fn, void *cb); | ||||||
|  |  | ||||||
| int mkdir_in_gitdir(const char *path); | 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); | const char *enter_repo(const char *path, int strict); | ||||||
| static inline int is_absolute_path(const char *path) | static inline int is_absolute_path(const char *path) | ||||||
| { | { | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								config.c
								
								
								
								
							
							
						
						
									
										8
									
								
								config.c
								
								
								
								
							|  | @ -137,7 +137,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc | ||||||
| 	if (!path) | 	if (!path) | ||||||
| 		return config_error_nonbool("include.path"); | 		return config_error_nonbool("include.path"); | ||||||
|  |  | ||||||
| 	expanded = expand_user_path(path, 0); | 	expanded = interpolate_path(path, 0); | ||||||
| 	if (!expanded) | 	if (!expanded) | ||||||
| 		return error(_("could not expand include path '%s'"), path); | 		return error(_("could not expand include path '%s'"), path); | ||||||
| 	path = expanded; | 	path = expanded; | ||||||
|  | @ -185,7 +185,7 @@ static int prepare_include_condition_pattern(struct strbuf *pat) | ||||||
| 	char *expanded; | 	char *expanded; | ||||||
| 	int prefix = 0; | 	int prefix = 0; | ||||||
|  |  | ||||||
| 	expanded = expand_user_path(pat->buf, 1); | 	expanded = interpolate_path(pat->buf, 1); | ||||||
| 	if (expanded) { | 	if (expanded) { | ||||||
| 		strbuf_reset(pat); | 		strbuf_reset(pat); | ||||||
| 		strbuf_addstr(pat, expanded); | 		strbuf_addstr(pat, expanded); | ||||||
|  | @ -1270,7 +1270,7 @@ int git_config_pathname(const char **dest, const char *var, const char *value) | ||||||
| { | { | ||||||
| 	if (!value) | 	if (!value) | ||||||
| 		return config_error_nonbool(var); | 		return config_error_nonbool(var); | ||||||
| 	*dest = expand_user_path(value, 0); | 	*dest = interpolate_path(value, 0); | ||||||
| 	if (!*dest) | 	if (!*dest) | ||||||
| 		die(_("failed to expand user dir in: '%s'"), value); | 		die(_("failed to expand user dir in: '%s'"), value); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -1845,7 +1845,7 @@ void git_global_config(char **user_out, char **xdg_out) | ||||||
| 	char *xdg_config = NULL; | 	char *xdg_config = NULL; | ||||||
|  |  | ||||||
| 	if (!user_config) { | 	if (!user_config) { | ||||||
| 		user_config = expand_user_path("~/.gitconfig", 0); | 		user_config = interpolate_path("~/.gitconfig", 0); | ||||||
| 		xdg_config = xdg_config_home("config"); | 		xdg_config = xdg_config_home("config"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								path.c
								
								
								
								
							
							
						
						
									
										19
									
								
								path.c
								
								
								
								
							|  | @ -12,6 +12,7 @@ | ||||||
| #include "packfile.h" | #include "packfile.h" | ||||||
| #include "object-store.h" | #include "object-store.h" | ||||||
| #include "lockfile.h" | #include "lockfile.h" | ||||||
|  | #include "exec-cmd.h" | ||||||
|  |  | ||||||
| static int get_st_mode_bits(const char *path, int *mode) | static int get_st_mode_bits(const char *path, int *mode) | ||||||
| { | { | ||||||
|  | @ -719,19 +720,25 @@ static struct passwd *getpw_str(const char *username, size_t len) | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Return a string with ~ and ~user expanded via getpw*.  If buf != NULL, |  * Return a string with ~ and ~user expanded via getpw*. Returns NULL on getpw | ||||||
|  * then it is a newly allocated string. Returns NULL on getpw failure or |  * failure or if path is NULL. | ||||||
|  * 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; | 	struct strbuf user_path = STRBUF_INIT; | ||||||
| 	const char *to_copy = path; | 	const char *to_copy = path; | ||||||
|  |  | ||||||
| 	if (path == NULL) | 	if (path == NULL) | ||||||
| 		goto return_null; | 		goto return_null; | ||||||
|  |  | ||||||
|  | 	if (skip_prefix(path, "%(prefix)/", &path)) | ||||||
|  | 		return system_path(path); | ||||||
|  |  | ||||||
| 	if (path[0] == '~') { | 	if (path[0] == '~') { | ||||||
| 		const char *first_slash = strchrnul(path, '/'); | 		const char *first_slash = strchrnul(path, '/'); | ||||||
| 		const char *username = path + 1; | 		const char *username = path + 1; | ||||||
|  | @ -812,7 +819,7 @@ const char *enter_repo(const char *path, int strict) | ||||||
| 		strbuf_add(&validated_path, path, len); | 		strbuf_add(&validated_path, path, len); | ||||||
|  |  | ||||||
| 		if (used_path.buf[0] == '~') { | 		if (used_path.buf[0] == '~') { | ||||||
| 			char *newpath = expand_user_path(used_path.buf, 0); | 			char *newpath = interpolate_path(used_path.buf, 0); | ||||||
| 			if (!newpath) | 			if (!newpath) | ||||||
| 				return NULL; | 				return NULL; | ||||||
| 			strbuf_attach(&used_path, newpath, strlen(newpath), | 			strbuf_attach(&used_path, newpath, strlen(newpath), | ||||||
|  |  | ||||||
|  | @ -1241,7 +1241,7 @@ N_("Your name and email address were configured automatically based\n" | ||||||
|  |  | ||||||
| static const char *implicit_ident_advice(void) | 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"); | 	char *xdg_config = xdg_config_home("config"); | ||||||
| 	int config_exists = file_exists(user_config) || file_exists(xdg_config); | 	int config_exists = file_exists(user_config) || file_exists(xdg_config); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -525,4 +525,30 @@ test_expect_success MINGW 'is_valid_path() on Windows' ' | ||||||
| 		"PRN./abc" | 		"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_done | test_done | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano