Don't hard code path to git-crypt in .git/config on Linux

There's a tradeoff.  When the path is hardcoded, it's guaranteed that
git-crypt will be found no matter where you run git or what your $PATH is.
On the other hand, hardcoding means that things break if git-crypt changes
location, which could easily happen if you copy a repository to a different system
(see https://github.com/AGWA/git-crypt/issues/71 for example).

In hindsight, I think this was a bad tradeoff.  Now, if git-crypt is
invoked as a bare filename (no slashes), the bare filename is placed
in .git/config under the assumption that it can be found via $PATH
(this assumption will be true as long as git-crypt wasn't resolved via
a relative path in $PATH).  This logic was already being used on
non-Linux OSes and it seemed to work fine.
This commit is contained in:
Andrew Ayer
2015-12-26 13:01:35 -08:00
parent c63a727177
commit b47176e6a8

View File

@@ -125,40 +125,20 @@ void mkdir_parent (const std::string& path)
}
}
static std::string readlink (const char* pathname)
{
std::vector<char> buffer(64);
ssize_t len;
while ((len = ::readlink(pathname, &buffer[0], buffer.size())) == static_cast<ssize_t>(buffer.size())) {
// buffer may have been truncated - grow and try again
buffer.resize(buffer.size() * 2);
}
if (len == -1) {
throw System_error("readlink", pathname, errno);
}
return std::string(buffer.begin(), buffer.begin() + len);
}
std::string our_exe_path ()
{
try {
return readlink("/proc/self/exe");
} catch (const System_error&) {
if (argv0[0] == '/') {
// argv[0] starts with / => it's an absolute path
return argv0;
} else if (std::strchr(argv0, '/')) {
// argv[0] contains / => it a relative path that should be resolved
char* resolved_path_p = realpath(argv0, NULL);
std::string resolved_path(resolved_path_p);
free(resolved_path_p);
return resolved_path;
} else {
// argv[0] is just a bare filename => not much we can do
return argv0;
}
if (argv0[0] == '/') {
// argv[0] starts with / => it's an absolute path
return argv0;
} else if (std::strchr(argv0, '/')) {
// argv[0] contains / => it a relative path that should be resolved
char* resolved_path_p = realpath(argv0, NULL);
std::string resolved_path(resolved_path_p);
free(resolved_path_p);
return resolved_path;
} else {
// argv[0] is just a bare filename => not much we can do
return argv0;
}
}