static int inside_git_dir = -1;
static int inside_work_tree = -1;
-const char *prefix_path(const char *prefix, int len, const char *path)
+char *prefix_path(const char *prefix, int len, const char *path)
{
const char *orig = path;
- char *sanitized = xmalloc(len + strlen(path) + 1);
- if (is_absolute_path(orig))
- strcpy(sanitized, path);
- else {
+ char *sanitized;
+ if (is_absolute_path(orig)) {
+ const char *temp = make_absolute_path(path);
+ sanitized = xmalloc(len + strlen(temp) + 1);
+ strcpy(sanitized, temp);
+ } else {
+ sanitized = xmalloc(len + strlen(path) + 1);
if (len)
memcpy(sanitized, prefix, len);
strcpy(sanitized + len, path);
{
static char path[PATH_MAX];
#ifndef WIN32
- if (!pfx || !*pfx || is_absolute_path(arg))
+ if (!pfx_len || is_absolute_path(arg))
return arg;
memcpy(path, pfx, pfx_len);
strcpy(path + pfx_len, arg);
/* don't add prefix to absolute paths, but still replace '\' by '/' */
if (is_absolute_path(arg))
pfx_len = 0;
- else
+ else if (pfx_len)
memcpy(path, pfx, pfx_len);
strcpy(path + pfx_len, arg);
for (p = path + pfx_len; *p; p++)
git_dir = make_absolute_path(git_dir);
if (!work_tree || chdir(work_tree))
die("This operation must be run in a work tree");
+
+ /*
+ * Make sure subsequent git processes find correct worktree
+ * if $GIT_WORK_TREE is set relative
+ */
+ if (getenv(GIT_WORK_TREE_ENVIRONMENT))
+ setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
+
set_git_dir(make_relative_path(git_dir, work_tree));
initialized = 1;
}
if (check_repository_format_gently(gitdir, nongit_ok))
return NULL;
+ /* --work-tree is set without --git-dir; use discovered one */
+ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
+ if (offset != len && !is_absolute_path(gitdir))
+ gitdir = xstrdup(make_absolute_path(gitdir));
+ if (chdir(cwd))
+ die_errno("Could not come back to cwd");
+ return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
+ }
+
/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
if (is_bare_repository_cfg > 0) {
set_git_dir(offset == len ? gitdir : make_absolute_path(gitdir));
if (check_repository_format_gently(".", nongit_ok))
return NULL;
+ /* --work-tree is set without --git-dir; use discovered one */
+ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
+ const char *gitdir;
+
+ gitdir = offset == len ? "." : xmemdupz(cwd, offset);
+ if (chdir(cwd))
+ die_errno("Could not come back to cwd");
+ return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
+ }
+
inside_git_dir = 1;
inside_work_tree = 0;
if (offset != len) {
const char *prefix;
prefix = setup_git_directory_gently_1(nongit_ok);
- if (startup_info)
+ if (startup_info) {
startup_info->have_repository = !nongit_ok || !*nongit_ok;
+ startup_info->prefix = prefix;
+ }
return prefix;
}