static int inside_git_dir = -1;
static int inside_work_tree = -1;
+static int work_tree_config_is_bogus;
/*
* The input parameter must contain an absolute path, and it must already be
if (arg[2] == '\0') /* ":/" is root dir, always exists */
return 1;
name = arg + 2;
- } else if (prefix)
+ } else if (!no_wildcard(arg))
+ return 1;
+ else if (prefix)
name = prefix_filename(prefix, strlen(prefix), arg);
else
name = arg;
"'git <command> [<revision>...] -- [<file>...]'", arg);
}
-static void get_common_dir(struct strbuf *sb, const char *gitdir)
+int get_common_dir(struct strbuf *sb, const char *gitdir)
{
struct strbuf data = STRBUF_INIT;
struct strbuf path = STRBUF_INIT;
const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+ int ret = 0;
if (git_common_dir) {
strbuf_addstr(sb, git_common_dir);
- return;
+ return 1;
}
strbuf_addf(&path, "%s/commondir", gitdir);
if (file_exists(path.buf)) {
strbuf_addf(&path, "%s/", gitdir);
strbuf_addbuf(&path, &data);
strbuf_addstr(sb, real_path(path.buf));
+ ret = 1;
} else
strbuf_addstr(sb, gitdir);
strbuf_release(&data);
strbuf_release(&path);
+ return ret;
}
/*
if (initialized)
return;
+
+ if (work_tree_config_is_bogus)
+ die("unable to set up work tree using invalid config");
+
work_tree = get_git_work_tree();
git_dir = get_git_dir();
if (!is_absolute_path(git_dir))
initialized = 1;
}
+static int check_repo_format(const char *var, const char *value, void *cb)
+{
+ if (strcmp(var, "core.repositoryformatversion") == 0)
+ repository_format_version = git_config_int(var, value);
+ else if (strcmp(var, "core.sharedrepository") == 0)
+ shared_repository = git_config_perm(var, value);
+ return 0;
+}
+
static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
{
struct strbuf sb = STRBUF_INIT;
const char *repo_config;
+ config_fn_t fn;
int ret = 0;
- get_common_dir(&sb, gitdir);
+ if (get_common_dir(&sb, gitdir))
+ fn = check_repo_format;
+ else
+ fn = check_repository_format_version;
strbuf_addstr(&sb, "/config");
repo_config = sb.buf;
* Use a gentler version of git_config() to check if this repo
* is a good one.
*/
- git_config_early(check_repository_format_version, NULL, repo_config);
+ git_config_early(fn, NULL, repo_config);
if (GIT_REPO_VERSION < repository_format_version) {
if (!nongit_ok)
die ("Expected git repo version <= %d, found %d",
return ret;
}
+static void update_linked_gitdir(const char *gitfile, const char *gitdir)
+{
+ struct strbuf path = STRBUF_INIT;
+ struct stat st;
+
+ strbuf_addf(&path, "%s/gitdir", gitdir);
+ if (stat(path.buf, &st) || st.st_mtime + 24 * 3600 < time(NULL))
+ write_file(path.buf, 1, "%s\n", gitfile);
+ strbuf_release(&path);
+}
+
/*
* Try to read the location of the git directory from the .git file,
* return path to git directory if found.
if (!is_git_directory(dir))
die("Not a git repository: %s", dir);
+
+ update_linked_gitdir(path, dir);
path = real_path(dir);
free(buf);
if (work_tree_env)
set_git_work_tree(work_tree_env);
else if (is_bare_repository_cfg > 0) {
- if (git_work_tree_cfg) /* #22.2, #30 */
- die("core.bare and core.worktree do not make sense");
+ if (git_work_tree_cfg) {
+ /* #22.2, #30 */
+ warning("core.bare and core.worktree do not make sense");
+ work_tree_config_is_bogus = 1;
+ }
/* #18, #26 */
set_git_dir(gitdirenv);
int check_repository_format_version(const char *var, const char *value, void *cb)
{
- if (strcmp(var, "core.repositoryformatversion") == 0)
- repository_format_version = git_config_int(var, value);
- else if (strcmp(var, "core.sharedrepository") == 0)
- shared_repository = git_config_perm(var, value);
- else if (strcmp(var, "core.bare") == 0) {
+ int ret = check_repo_format(var, value, cb);
+ if (ret)
+ return ret;
+ if (strcmp(var, "core.bare") == 0) {
is_bare_repository_cfg = git_config_bool(var, value);
if (is_bare_repository_cfg == 1)
inside_work_tree = -1;