const char *name;
struct stat st;
- name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
+ if (!prefixcmp(arg, ":/")) {
+ if (arg[2] == '\0') /* ":/" is root dir, always exists */
+ return 1;
+ name = arg + 2;
+ } else if (prefix)
+ name = prefix_filename(prefix, strlen(prefix), arg);
+ else
+ name = arg;
if (!lstat(name, &st))
return 1; /* file exists */
if (errno == ENOENT || errno == ENOTDIR)
*copyfrom && *copyfrom != ')';
copyfrom = nextat) {
size_t len = strcspn(copyfrom, ",)");
- if (copyfrom[len] == ')')
- nextat = copyfrom + len;
- else
+ if (copyfrom[len] == ',')
nextat = copyfrom + len + 1;
+ else
+ /* handle ')' and '\0' */
+ nextat = copyfrom + len;
if (!len)
continue;
for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
die("Invalid pathspec magic '%.*s' in '%s'",
(int) len, copyfrom, elt);
}
- if (*copyfrom == ')')
- copyfrom++;
+ if (*copyfrom != ')')
+ die("Missing ')' at the end of pathspec magic in '%s'", elt);
+ copyfrom++;
} else {
/* shorthand */
for (copyfrom = elt + 1;
return prefix_path(prefix, prefixlen, copyfrom);
}
+/*
+ * N.B. get_pathspec() is deprecated in favor of the "struct pathspec"
+ * based interface - see pathspec_magic above.
+ *
+ * Arguments:
+ * - prefix - a path relative to the root of the working tree
+ * - pathspec - a list of paths underneath the prefix path
+ *
+ * Iterates over pathspec, prepending each path with prefix,
+ * and return the resulting list.
+ *
+ * If pathspec is empty, return a singleton list containing prefix.
+ *
+ * If pathspec and prefix are both empty, return an empty list.
+ *
+ * This is typically used by built-in commands such as add.c, in order
+ * to normalize argv arguments provided to the built-in into a list of
+ * paths to process, all relative to the root of the working tree.
+ */
const char **get_pathspec(const char *prefix, const char **pathspec)
{
const char *entry = *pathspec;
void setup_work_tree(void)
{
+ struct strbuf sb = STRBUF_INIT;
const char *work_tree, *git_dir;
static int initialized = 0;
if (getenv(GIT_WORK_TREE_ENVIRONMENT))
setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
- set_git_dir(relative_path(git_dir, work_tree));
+ set_git_dir(relative_path(git_dir, work_tree, &sb));
initialized = 1;
+
+ strbuf_release(&sb);
}
static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
set_git_work_tree(core_worktree);
}
}
+ else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
+ /* #16d */
+ set_git_dir(gitdirenv);
+ free(gitfile);
+ return NULL;
+ }
else /* #2, #10 */
set_git_work_tree(".");
if (check_repository_format_gently(".", nongit_ok))
return NULL;
+ setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
+
/* --work-tree is set without --git-dir; use discovered one */
if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
const char *gitdir;
prefix = setup_git_directory_gently_1(nongit_ok);
if (prefix)
- setenv("GIT_PREFIX", prefix, 1);
+ setenv(GIT_PREFIX_ENVIRONMENT, prefix, 1);
else
- setenv("GIT_PREFIX", "", 1);
+ setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
if (startup_info) {
startup_info->have_repository = !nongit_ok || !*nongit_ok;