@@ -720,22 +720,30 @@ static struct passwd *getpw_str(const char *username, size_t len)
720720}
721721
722722/*
723- * Return a string with ~ and ~user expanded via getpw*. If buf != NULL,
724- * then it is a newly allocated string. Returns NULL on getpw failure or
725- * if path is NULL.
723+ * Return a string with ~ and ~user expanded via getpw*. Returns NULL on getpw
724+ * failure or if path is NULL.
726725 *
727- * If real_home is true, strbuf_realpath($HOME) is used in the expansion.
726+ * If real_home is true, strbuf_realpath($HOME) is used in the `~/` expansion.
727+ *
728+ * If the path starts with `%(prefix)/`, the remainder is interpreted as
729+ * relative to where Git is installed, and expanded to the absolute path.
728730 */
729- char * expand_user_path (const char * path , int real_home )
731+ char * interpolate_path (const char * path , int real_home )
730732{
731733 struct strbuf user_path = STRBUF_INIT ;
732734 const char * to_copy = path ;
733735
734736 if (path == NULL )
735737 goto return_null ;
738+
739+ if (skip_prefix (path , "%(prefix)/" , & path ))
740+ return system_path (path );
741+
736742#ifdef __MINGW32__
737- if (path [0 ] == '/' )
743+ if (path [0 ] == '/' ) {
744+ warning (_ ("encountered old-style '%s' that should be '%%(prefix)%s'" ), path , path );
738745 return system_path (path + 1 );
746+ }
739747#endif
740748 if (path [0 ] == '~' ) {
741749 const char * first_slash = strchrnul (path , '/' );
@@ -817,7 +825,7 @@ const char *enter_repo(const char *path, int strict)
817825 strbuf_add (& validated_path , path , len );
818826
819827 if (used_path .buf [0 ] == '~' ) {
820- char * newpath = expand_user_path (used_path .buf , 0 );
828+ char * newpath = interpolate_path (used_path .buf , 0 );
821829 if (!newpath )
822830 return NULL ;
823831 strbuf_attach (& used_path , newpath , strlen (newpath ),
0 commit comments