#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "abspath.h"
#include "copy.h"
#include "environment.h"
#include "exec-cmd.h"
#include "gettext.h"
#include "hex.h"
#include "object-file.h"
#include "object-name.h"
#include "refs.h"
#include "repository.h"
#include "config.h"
#include "dir.h"
#include "setup.h"
#include "shallow.h"
#include "string-list.h"
#include "strvec.h"
#include "chdir-notify.h"
#include "path.h"
#include "quote.h"
#include "trace.h"
#include "trace2.h"
#include "worktree.h"

enum allowed_bare_repo {
	ALLOWED_BARE_REPO_EXPLICIT = 0,
	ALLOWED_BARE_REPO_ALL,
};

static struct startup_info the_startup_info;
struct startup_info *startup_info = &the_startup_info;
const char *tmp_original_cwd;

/*
 * The input parameter must contain an absolute path, and it must already be
 * normalized.
 *
 * Find the part of an absolute path that lies inside the work tree by
 * dereferencing symlinks outside the work tree, for example:
 * /dir1/repo/dir2/file   (work tree is /dir1/repo)      -> dir2/file
 * /dir/file              (work tree is /)               -> dir/file
 * /dir/symlink1/symlink2 (symlink1 points to work tree) -> symlink2
 * /dir/repolink/file     (repolink points to /dir/repo) -> file
 * /dir/repo              (exactly equal to work tree)   -> (empty string)
 */
static int abspath_part_inside_repo(struct repository *repo, char *path)
{
	size_t len;
	size_t wtlen;
	char *path0;
	int off;
	const char *work_tree = precompose_string_if_needed(repo_get_work_tree(repo));
	struct strbuf realpath = STRBUF_INIT;

	if (!work_tree)
		return -1;
	wtlen = strlen(work_tree);
	len = strlen(path);
	off = offset_1st_component(path);

	/* check if work tree is already the prefix */
	if (wtlen <= len && !fspathncmp(path, work_tree, wtlen)) {
		if (path[wtlen] == '/') {
			memmove(path, path + wtlen + 1, len - wtlen);
			return 0;
		} else if (path[wtlen - 1] == '/' || path[wtlen] == '\0') {
			/* work tree is the root, or the whole path */
			memmove(path, path + wtlen, len - wtlen + 1);
			return 0;
		}
		/* work tree might match beginning of a symlink to work tree */
		off = wtlen;
	}
	path0 = path;
	path += off;

	/* check each '/'-terminated level */
	while (*path) {
		path++;
		if (*path == '/') {
			*path = '\0';
			strbuf_realpath(&realpath, path0, 1);
			if (fspathcmp(realpath.buf, work_tree) == 0) {
				memmove(path0, path + 1, len - (path - path0));
				strbuf_release(&realpath);
				return 0;
			}
			*path = '/';
		}
	}

	/* check whole path */
	strbuf_realpath(&realpath, path0, 1);
	if (fspathcmp(realpath.buf, work_tree) == 0) {
		*path0 = '\0';
		strbuf_release(&realpath);
		return 0;
	}

	strbuf_release(&realpath);
	return -1;
}

/*
 * Normalize "path", prepending the "prefix" for relative paths. If
 * remaining_prefix is not NULL, return the actual prefix still
 * remains in the path. For example, prefix = sub1/sub2/ and path is
 *
 *  foo          -> sub1/sub2/foo  (full prefix)
 *  ../foo       -> sub1/foo       (remaining prefix is sub1/)
 *  ../../bar    -> bar            (no remaining prefix)
 *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)
 *  `pwd`/../bar -> sub1/bar       (no remaining prefix)
 */
char *prefix_path_gently(struct repository *repo,
			 const char *prefix, int len,
			 int *remaining_prefix, const char *path)
{
	const char *orig = path;
	char *sanitized;
	if (is_absolute_path(orig)) {
		sanitized = xmallocz(strlen(path));
		if (remaining_prefix)
			*remaining_prefix = 0;
		if (normalize_path_copy_len(sanitized, path, remaining_prefix)) {
			free(sanitized);
			return NULL;
		}
		if (abspath_part_inside_repo(repo, sanitized)) {
			free(sanitized);
			return NULL;
		}
	} else {
		sanitized = xstrfmt("%.*s%s", len, len ? prefix : "", path);
		if (remaining_prefix)
			*remaining_prefix = len;
		if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix)) {
			free(sanitized);
			return NULL;
		}
	}
	return sanitized;
}

char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path)
{
	char *r = prefix_path_gently(repo, prefix, len, NULL, path);
	if (!r) {
		const char *hint_path = repo_get_work_tree(repo);
		if (!hint_path)
			hint_path = repo_get_git_dir(repo);
		die(_("'%s' is outside repository at '%s'"), path,
		    absolute_path(hint_path));
	}
	return r;
}

int path_inside_repo(struct repository *repo, const char *prefix, const char *path)
{
	int len = prefix ? strlen(prefix) : 0;
	char *r = prefix_path_gently(repo, prefix, len, NULL, path);
	if (r) {
		free(r);
		return 1;
	}
	return 0;
}

int check_filename(const char *prefix, const char *arg)
{
	char *to_free = NULL;
	struct stat st;

	if (skip_prefix(arg, ":/", &arg)) {
		if (!*arg) /* ":/" is root dir, always exists */
			return 1;
		prefix = NULL;
	} else if (skip_prefix(arg, ":!", &arg) ||
		   skip_prefix(arg, ":^", &arg)) {
		if (!*arg) /* excluding everything is silly, but allowed */
			return 1;
	}

	if (prefix)
		arg = to_free = prefix_filename(prefix, arg);

	if (!lstat(arg, &st)) {
		free(to_free);
		return 1; /* file exists */
	}
	if (is_missing_file_error(errno)) {
		free(to_free);
		return 0; /* file does not exist */
	}
	die_errno(_("failed to stat '%s'"), arg);
}

static void NORETURN die_verify_filename(struct repository *r,
					 const char *prefix,
					 const char *arg,
					 int diagnose_misspelt_rev)
{
	if (!diagnose_misspelt_rev)
		die(_("%s: no such path in the working tree.\n"
		      "Use 'git <command> -- <path>...' to specify paths that do not exist locally."),
		    arg);
	/*
	 * Saying "'(icase)foo' does not exist in the index" when the
	 * user gave us ":(icase)foo" is just stupid.  A magic pathspec
	 * begins with a colon and is followed by a non-alnum; do not
	 * let maybe_die_on_misspelt_object_name() even trigger.
	 */
	if (!(arg[0] == ':' && !isalnum(arg[1])))
		maybe_die_on_misspelt_object_name(r, arg, prefix);

	/* ... or fall back the most general message. */
	die(_("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
	      "Use '--' to separate paths from revisions, like this:\n"
	      "'git <command> [<revision>...] -- [<file>...]'"), arg);

}

/*
 * Check for arguments that don't resolve as actual files,
 * but which look sufficiently like pathspecs that we'll consider
 * them such for the purposes of rev/pathspec DWIM parsing.
 */
static int looks_like_pathspec(const char *arg)
{
	const char *p;
	int escaped = 0;

	/*
	 * Wildcard characters imply the user is looking to match pathspecs
	 * that aren't in the filesystem. Note that this doesn't include
	 * backslash even though it's a glob special; by itself it doesn't
	 * cause any increase in the match. Likewise ignore backslash-escaped
	 * wildcard characters.
	 */
	for (p = arg; *p; p++) {
		if (escaped) {
			escaped = 0;
		} else if (is_glob_special(*p)) {
			if (*p == '\\')
				escaped = 1;
			else
				return 1;
		}
	}

	/* long-form pathspec magic */
	if (starts_with(arg, ":("))
		return 1;

	return 0;
}

/*
 * Verify a filename that we got as an argument for a pathspec
 * entry. Note that a filename that begins with "-" never verifies
 * as true, because even if such a filename were to exist, we want
 * it to be preceded by the "--" marker (or we want the user to
 * use a format like "./-filename")
 *
 * The "diagnose_misspelt_rev" is used to provide a user-friendly
 * diagnosis when dying upon finding that "name" is not a pathname.
 * If set to 1, the diagnosis will try to diagnose "name" as an
 * invalid object name (e.g. HEAD:foo). If set to 0, the diagnosis
 * will only complain about an inexisting file.
 *
 * This function is typically called to check that a "file or rev"
 * argument is unambiguous. In this case, the caller will want
 * diagnose_misspelt_rev == 1 when verifying the first non-rev
 * argument (which could have been a revision), and
 * diagnose_misspelt_rev == 0 for the next ones (because we already
 * saw a filename, there's not ambiguity anymore).
 */
void verify_filename(struct repository *repo,
		     const char *prefix,
		     const char *arg,
		     int diagnose_misspelt_rev)
{
	if (*arg == '-')
		die(_("option '%s' must come before non-option arguments"), arg);
	if (looks_like_pathspec(arg) || check_filename(prefix, arg))
		return;
	die_verify_filename(repo, prefix, arg, diagnose_misspelt_rev);
}

/*
 * Opposite of the above: the command line did not have -- marker
 * and we parsed the arg as a refname.  It should not be interpretable
 * as a filename.
 */
void verify_non_filename(struct repository *repo, const char *prefix, const char *arg)
{
	if (!is_inside_work_tree(repo) || is_inside_git_dir(repo))
		return;
	if (*arg == '-')
		return; /* flag */
	if (!check_filename(prefix, arg))
		return;
	die(_("ambiguous argument '%s': both revision and filename\n"
	      "Use '--' to separate paths from revisions, like this:\n"
	      "'git <command> [<revision>...] -- [<file>...]'"), arg);
}

int get_common_dir(struct strbuf *sb, const char *gitdir)
{
	const char *git_env_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
	if (git_env_common_dir) {
		strbuf_addstr(sb, git_env_common_dir);
		return 1;
	} else {
		return get_common_dir_noenv(sb, gitdir);
	}
}

int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
{
	struct strbuf data = STRBUF_INIT;
	struct strbuf path = STRBUF_INIT;
	int ret = 0;

	strbuf_addf(&path, "%s/commondir", gitdir);
	if (file_exists(path.buf)) {
		if (strbuf_read_file(&data, path.buf, 0) <= 0)
			die_errno(_("failed to read %s"), path.buf);
		while (data.len && (data.buf[data.len - 1] == '\n' ||
				    data.buf[data.len - 1] == '\r'))
			data.len--;
		data.buf[data.len] = '\0';
		strbuf_reset(&path);
		if (!is_absolute_path(data.buf))
			strbuf_addf(&path, "%s/", gitdir);
		strbuf_addbuf(&path, &data);
		strbuf_add_real_path(sb, path.buf);
		ret = 1;
	} else {
		strbuf_addstr(sb, gitdir);
	}

	strbuf_release(&data);
	strbuf_release(&path);
	return ret;
}

static int validate_headref(const char *path)
{
	struct stat st;
	char buffer[256];
	const char *refname;
	struct object_id oid;
	int fd;
	ssize_t len;

	if (lstat(path, &st) < 0)
		return -1;

	/* Make sure it is a "refs/.." symlink */
	if (S_ISLNK(st.st_mode)) {
		len = readlink(path, buffer, sizeof(buffer)-1);
		if (len >= 5 && !memcmp("refs/", buffer, 5))
			return 0;
		return -1;
	}

	/*
	 * Anything else, just open it and try to see if it is a symbolic ref.
	 */
	fd = open(path, O_RDONLY);
	if (fd < 0)
		return -1;
	len = read_in_full(fd, buffer, sizeof(buffer)-1);
	close(fd);

	if (len < 0)
		return -1;
	buffer[len] = '\0';

	/*
	 * Is it a symbolic ref?
	 */
	if (skip_prefix(buffer, "ref:", &refname)) {
		while (isspace(*refname))
			refname++;
		if (starts_with(refname, "refs/"))
			return 0;
	}

	/*
	 * Is this a detached HEAD?
	 */
	if (get_oid_hex_any(buffer, &oid) != GIT_HASH_UNKNOWN)
		return 0;

	return -1;
}

/*
 * Test if it looks like we're at a git directory.
 * We want to see:
 *
 *  - either an objects/ directory _or_ the proper
 *    GIT_OBJECT_DIRECTORY environment variable
 *  - a refs/ directory
 *  - either a HEAD symlink or a HEAD file that is formatted as
 *    a proper "ref:", or a regular file HEAD that has a properly
 *    formatted sha1 object name.
 */
int is_git_directory(const char *suspect)
{
	struct strbuf path = STRBUF_INIT;
	int ret = 0;
	size_t len;

	/* Check worktree-related signatures */
	strbuf_addstr(&path, suspect);
	strbuf_complete(&path, '/');
	strbuf_addstr(&path, "HEAD");
	if (validate_headref(path.buf))
		goto done;

	strbuf_reset(&path);
	get_common_dir(&path, suspect);
	len = path.len;

	/* Check non-worktree-related signatures */
	if (getenv(DB_ENVIRONMENT)) {
		if (access(getenv(DB_ENVIRONMENT), X_OK))
			goto done;
	}
	else {
		strbuf_setlen(&path, len);
		strbuf_addstr(&path, "/objects");
		if (access(path.buf, X_OK))
			goto done;
	}

	strbuf_setlen(&path, len);
	strbuf_addstr(&path, "/refs");
	if (access(path.buf, X_OK))
		goto done;

	ret = 1;
done:
	strbuf_release(&path);
	return ret;
}

int is_nonbare_repository_dir(struct strbuf *path)
{
	int ret = 0;
	int gitfile_error;
	size_t orig_path_len = path->len;
	assert(orig_path_len != 0);
	strbuf_complete(path, '/');
	strbuf_addstr(path, ".git");
	if (read_gitfile_gently(path->buf, &gitfile_error) || is_git_directory(path->buf))
		ret = 1;
	if (gitfile_error == READ_GITFILE_ERR_OPEN_FAILED ||
	    gitfile_error == READ_GITFILE_ERR_READ_FAILED)
		ret = 1;
	strbuf_setlen(path, orig_path_len);
	return ret;
}

int is_inside_git_dir(struct repository *repo)
{
	struct strbuf buf = STRBUF_INIT;
	int ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));
	strbuf_release(&buf);
	return ret;
}

int is_inside_work_tree(struct repository *repo)
{
	struct strbuf buf = STRBUF_INIT;
	const char *worktree;
	int ret;

	worktree = repo_get_work_tree(repo);
	if (!worktree)
		return 0;

	ret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));

	strbuf_release(&buf);
	return ret;
}

void setup_work_tree(struct repository *repo)
{
	const char *work_tree;

	if (repo->worktree_config_is_bogus)
		die(_("unable to set up work tree using invalid config"));

	work_tree = repo_get_work_tree(repo);
	if (!work_tree || chdir_notify(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);
}

static void setup_original_cwd(struct repository *repo)
{
	struct strbuf tmp = STRBUF_INIT;
	const char *worktree = NULL;
	int offset = -1;

	if (!tmp_original_cwd)
		return;

	/*
	 * startup_info->original_cwd points to the current working
	 * directory we inherited from our parent process, which is a
	 * directory we want to avoid removing.
	 *
	 * For convenience, we would like to have the path relative to the
	 * worktree instead of an absolute path.
	 *
	 * Yes, startup_info->original_cwd is usually the same as 'prefix',
	 * but differs in two ways:
	 *   - prefix has a trailing '/'
	 *   - if the user passes '-C' to git, that modifies the prefix but
	 *     not startup_info->original_cwd.
	 */

	/* Normalize the directory */
	if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {
		trace2_data_string("setup", repo,
				   "realpath-path", tmp_original_cwd);
		trace2_data_string("setup", repo,
				   "realpath-failure", strerror(errno));
		free((char*)tmp_original_cwd);
		tmp_original_cwd = NULL;
		return;
	}

	free((char*)tmp_original_cwd);
	tmp_original_cwd = NULL;
	startup_info->original_cwd = strbuf_detach(&tmp, NULL);

	/*
	 * Get our worktree; we only protect the current working directory
	 * if it's in the worktree.
	 */
	worktree = repo_get_work_tree(repo);
	if (!worktree)
		goto no_prevention_needed;

	offset = dir_inside_of(startup_info->original_cwd, worktree);
	if (offset >= 0) {
		/*
		 * If startup_info->original_cwd == worktree, that is already
		 * protected and we don't need original_cwd as a secondary
		 * protection measure.
		 */
		if (!*(startup_info->original_cwd + offset))
			goto no_prevention_needed;

		/*
		 * original_cwd was inside worktree; precompose it just as
		 * we do prefix so that built up paths will match
		 */
		startup_info->original_cwd = \
			precompose_string_if_needed(startup_info->original_cwd
						    + offset);
		return;
	}

no_prevention_needed:
	free((char*)startup_info->original_cwd);
	startup_info->original_cwd = NULL;
}

static int read_worktree_config(const char *var, const char *value,
				const struct config_context *ctx UNUSED,
				void *vdata)
{
	struct repository_format *data = vdata;

	if (strcmp(var, "core.bare") == 0) {
		data->is_bare = git_config_bool(var, value);
	} else if (strcmp(var, "core.worktree") == 0) {
		if (!value)
			return config_error_nonbool(var);
		free(data->work_tree);
		data->work_tree = xstrdup(value);
	}
	return 0;
}

enum extension_result {
	EXTENSION_ERROR = -1, /* compatible with error(), etc */
	EXTENSION_UNKNOWN = 0,
	EXTENSION_OK = 1
};

/*
 * Do not add new extensions to this function. It handles extensions which are
 * respected even in v0-format repositories for historical compatibility.
 */
static enum extension_result handle_extension_v0(const char *var,
						 const char *value,
						 const char *ext,
						 struct repository_format *data)
{
		if (!strcmp(ext, "noop")) {
			return EXTENSION_OK;
		} else if (!strcmp(ext, "preciousobjects")) {
			data->precious_objects = git_config_bool(var, value);
			return EXTENSION_OK;
		} else if (!strcmp(ext, "partialclone")) {
			if (!value)
				return config_error_nonbool(var);
			data->partial_clone = xstrdup(value);
			return EXTENSION_OK;
		} else if (!strcmp(ext, "worktreeconfig")) {
			data->worktree_config = git_config_bool(var, value);
			return EXTENSION_OK;
		}

		return EXTENSION_UNKNOWN;
}

static void parse_reference_uri(const char *value, char **format,
				char **payload)
{
	const char *schema_end;

	schema_end = strstr(value, "://");
	if (!schema_end) {
		*format = xstrdup(value);
		*payload = NULL;
	} else {
		*format = xstrndup(value, schema_end - value);
		*payload = xstrdup_or_null(schema_end + 3);
	}
}

/*
 * Record any new extensions in this function.
 */
static enum extension_result handle_extension(const char *var,
					      const char *value,
					      const char *ext,
					      struct repository_format *data)
{
	if (!strcmp(ext, "noop-v1")) {
		return EXTENSION_OK;
	} else if (!strcmp(ext, "objectformat")) {
		int format;

		if (!value)
			return config_error_nonbool(var);
		format = hash_algo_by_name(value);
		if (format == GIT_HASH_UNKNOWN)
			return error(_("invalid value for '%s': '%s'"),
				     "extensions.objectformat", value);
		data->hash_algo = format;
		return EXTENSION_OK;
	} else if (!strcmp(ext, "compatobjectformat")) {
		struct string_list_item *item;
		int format;

		if (!value)
			return config_error_nonbool(var);
		format = hash_algo_by_name(value);
		if (format == GIT_HASH_UNKNOWN)
			return error(_("invalid value for '%s': '%s'"),
				     "extensions.compatobjectformat", value);
		/* For now only support compatObjectFormat being specified once. */
		for_each_string_list_item(item, &data->v1_only_extensions) {
			if (!strcmp(item->string, "compatobjectformat"))
				return error(_("'%s' already specified as '%s'"),
					"extensions.compatobjectformat",
					hash_algos[data->compat_hash_algo].name);
		}
		data->compat_hash_algo = format;
		return EXTENSION_OK;
	} else if (!strcmp(ext, "refstorage")) {
		unsigned int format;
		char *format_str;

		if (!value)
			return config_error_nonbool(var);

		parse_reference_uri(value, &format_str,
				    &data->ref_storage_payload);

		format = ref_storage_format_by_name(format_str);
		free(format_str);

		if (format == REF_STORAGE_FORMAT_UNKNOWN)
			return error(_("invalid value for '%s': '%s'"),
				     "extensions.refstorage", value);
		data->ref_storage_format = format;
		return EXTENSION_OK;
	} else if (!strcmp(ext, "relativeworktrees")) {
		data->relative_worktrees = git_config_bool(var, value);
		return EXTENSION_OK;
	} else if (!strcmp(ext, "submodulepathconfig")) {
		data->submodule_path_cfg = git_config_bool(var, value);
		return EXTENSION_OK;
	}
	return EXTENSION_UNKNOWN;
}

static int check_repo_format(const char *var, const char *value,
			     const struct config_context *ctx, void *vdata)
{
	struct repository_format *data = vdata;
	const char *ext;

	if (strcmp(var, "core.repositoryformatversion") == 0)
		data->version = git_config_int(var, value, ctx->kvi);
	else if (skip_prefix(var, "extensions.", &ext)) {
		switch (handle_extension_v0(var, value, ext, data)) {
		case EXTENSION_ERROR:
			return -1;
		case EXTENSION_OK:
			return 0;
		case EXTENSION_UNKNOWN:
			break;
		}

		switch (handle_extension(var, value, ext, data)) {
		case EXTENSION_ERROR:
			return -1;
		case EXTENSION_OK:
			string_list_append(&data->v1_only_extensions, ext);
			return 0;
		case EXTENSION_UNKNOWN:
			string_list_append(&data->unknown_extensions, ext);
			return 0;
		}
	}

	return read_worktree_config(var, value, ctx, vdata);
}

static int read_and_verify_repository_format(struct repository_format *format,
					     const char *gitdir,
					     int *nongit_ok)
{
	struct strbuf sb = STRBUF_INIT;
	struct strbuf err = STRBUF_INIT;
	int has_common;

	has_common = get_common_dir(&sb, gitdir);
	strbuf_addstr(&sb, "/config");
	read_repository_format(format, sb.buf);
	strbuf_release(&sb);

	/*
	 * For historical use of check_and_apply_repository_format() in git-init,
	 * we treat a missing config as a silent "ok", even when nongit_ok
	 * is unset.
	 */
	if (format->version < 0)
		return 0;

	if (verify_repository_format(format, &err) < 0) {
		if (nongit_ok) {
			warning("%s", err.buf);
			strbuf_release(&err);
			*nongit_ok = -1;
			return -1;
		}
		die("%s", err.buf);
	}

	string_list_clear(&format->unknown_extensions, 0);
	string_list_clear(&format->v1_only_extensions, 0);

	if (format->worktree_config) {
		/*
		 * pick up core.bare and core.worktree from per-worktree
		 * config if present
		 */
		strbuf_addf(&sb, "%s/config.worktree", gitdir);
		git_config_from_file(read_worktree_config, sb.buf, format);
		strbuf_release(&sb);
		has_common = 0;
	}

	if (startup_info->force_bare_repository) {
		format->is_bare = 1;
		FREE_AND_NULL(format->work_tree);
	} else if (has_common) {
		/*
		 * When sharing a common dir with another repository (e.g. a
		 * linked worktree), do not let this repository's config
		 * dictate bareness; it is inherited from the main worktree.
		 */
		format->is_bare = -1;

		/*
		 * Furthermore, "core.worktree" is supposed to be ignored when
		 * we have a commondir configured, unless it comes from the
		 * per-worktree configuration.
		 */
		FREE_AND_NULL(format->work_tree);
	}

	return 0;
}

int upgrade_repository_format(struct repository *repo, int target_version)
{
	struct strbuf sb = STRBUF_INIT;
	struct strbuf err = STRBUF_INIT;
	struct strbuf repo_version = STRBUF_INIT;
	struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
	int ret;

	repo_common_path_append(repo, &sb, "config");
	read_repository_format(&repo_fmt, sb.buf);
	strbuf_release(&sb);

	if (repo_fmt.version >= target_version) {
		ret = 0;
		goto out;
	}

	if (verify_repository_format(&repo_fmt, &err) < 0) {
		ret = error("cannot upgrade repository format from %d to %d: %s",
			    repo_fmt.version, target_version, err.buf);
		goto out;
	}
	if (!repo_fmt.version && repo_fmt.unknown_extensions.nr) {
		ret = error("cannot upgrade repository format: "
			    "unknown extension %s",
			    repo_fmt.unknown_extensions.items[0].string);
		goto out;
	}

	strbuf_addf(&repo_version, "%d", target_version);
	repo_config_set(repo, "core.repositoryformatversion", repo_version.buf);

	ret = 1;

out:
	clear_repository_format(&repo_fmt);
	strbuf_release(&repo_version);
	strbuf_release(&err);
	return ret;
}

static void init_repository_format(struct repository_format *format)
{
	const struct repository_format fresh = REPOSITORY_FORMAT_INIT;

	memcpy(format, &fresh, sizeof(fresh));
}

int read_repository_format(struct repository_format *format, const char *path)
{
	clear_repository_format(format);
	format->hash_algo = GIT_HASH_SHA1_LEGACY;
	git_config_from_file(check_repo_format, path, format);
	if (format->version == -1) {
		clear_repository_format(format);
		format->hash_algo = GIT_HASH_SHA1_LEGACY;
	}
	return format->version;
}

void clear_repository_format(struct repository_format *format)
{
	string_list_clear(&format->unknown_extensions, 0);
	string_list_clear(&format->v1_only_extensions, 0);
	free(format->work_tree);
	free(format->partial_clone);
	free(format->ref_storage_payload);
	init_repository_format(format);
}

int verify_repository_format(const struct repository_format *format,
			     struct strbuf *err)
{
	if (GIT_REPO_VERSION_READ < format->version) {
		strbuf_addf(err, _("Expected git repo version <= %d, found %d"),
			    GIT_REPO_VERSION_READ, format->version);
		return -1;
	}

	if (format->version >= 1 && format->unknown_extensions.nr) {
		int i;

		strbuf_addstr(err, Q_("unknown repository extension found:",
				      "unknown repository extensions found:",
				      format->unknown_extensions.nr));

		for (i = 0; i < format->unknown_extensions.nr; i++)
			strbuf_addf(err, "\n\t%s",
				    format->unknown_extensions.items[i].string);
		return -1;
	}

	if (format->version == 0 && format->v1_only_extensions.nr) {
		int i;

		strbuf_addstr(err,
			      Q_("repo version is 0, but v1-only extension found:",
				 "repo version is 0, but v1-only extensions found:",
				 format->v1_only_extensions.nr));

		for (i = 0; i < format->v1_only_extensions.nr; i++)
			strbuf_addf(err, "\n\t%s",
				    format->v1_only_extensions.items[i].string);
		return -1;
	}

	return 0;
}

void read_gitfile_error_die(int error_code, const char *path)
{
	switch (error_code) {
	case READ_GITFILE_ERR_NOT_A_FILE:
	case READ_GITFILE_ERR_STAT_FAILED:
	case READ_GITFILE_ERR_MISSING:
	case READ_GITFILE_ERR_IS_A_DIR:
		/* non-fatal; follow return path */
		break;
	case READ_GITFILE_ERR_OPEN_FAILED:
		die_errno(_("error opening '%s'"), path);
	case READ_GITFILE_ERR_TOO_LARGE:
		die(_("too large to be a .git file: '%s'"), path);
	case READ_GITFILE_ERR_READ_FAILED:
		die(_("error reading %s"), path);
	case READ_GITFILE_ERR_INVALID_FORMAT:
		die(_("invalid gitfile format: %s"), path);
	case READ_GITFILE_ERR_NO_PATH:
		die(_("no path in gitfile: %s"), path);
	case READ_GITFILE_ERR_NOT_A_REPO:
		die(_("gitfile does not point to a valid repository: %s"),
		    path);
	default:
		BUG("unknown error code");
	}
}

/*
 * Try to read the location of the git directory from the .git file,
 * return path to git directory if found. The return value comes from
 * a shared buffer.
 *
 * On failure, if return_error_code is not NULL, return_error_code
 * will be set to an error code and NULL will be returned. If
 * return_error_code is NULL the function will die instead (for most
 * cases).
 */
const char *read_gitfile_gently(const char *path, int *return_error_code)
{
	const int max_file_size = 1 << 20;  /* 1MB */
	int error_code = 0;
	char *buf = NULL;
	char *dir = NULL;
	const char *slash;
	struct stat st;
	int fd;
	ssize_t len;
	static struct strbuf realpath = STRBUF_INIT;

	if (stat(path, &st)) {
		if (errno == ENOENT || errno == ENOTDIR)
			error_code = READ_GITFILE_ERR_MISSING;
		else
			error_code = READ_GITFILE_ERR_STAT_FAILED;
		goto cleanup_return;
	}
	if (S_ISDIR(st.st_mode)) {
		error_code = READ_GITFILE_ERR_IS_A_DIR;
		goto cleanup_return;
	}
	if (!S_ISREG(st.st_mode)) {
		error_code = READ_GITFILE_ERR_NOT_A_FILE;
		goto cleanup_return;
	}
	if (st.st_size > max_file_size) {
		error_code = READ_GITFILE_ERR_TOO_LARGE;
		goto cleanup_return;
	}
	fd = open(path, O_RDONLY);
	if (fd < 0) {
		error_code = READ_GITFILE_ERR_OPEN_FAILED;
		goto cleanup_return;
	}
	buf = xmallocz(st.st_size);
	len = read_in_full(fd, buf, st.st_size);
	close(fd);
	if (len != st.st_size) {
		error_code = READ_GITFILE_ERR_READ_FAILED;
		goto cleanup_return;
	}
	if (!starts_with(buf, "gitdir: ")) {
		error_code = READ_GITFILE_ERR_INVALID_FORMAT;
		goto cleanup_return;
	}
	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
		len--;
	if (len < 9) {
		error_code = READ_GITFILE_ERR_NO_PATH;
		goto cleanup_return;
	}
	buf[len] = '\0';
	dir = buf + 8;

	if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) {
		size_t pathlen = slash+1 - path;
		dir = xstrfmt("%.*s%.*s", (int)pathlen, path,
			      (int)(len - 8), buf + 8);
		free(buf);
		buf = dir;
	}
	if (!is_git_directory(dir)) {
		error_code = READ_GITFILE_ERR_NOT_A_REPO;
		goto cleanup_return;
	}

	strbuf_realpath(&realpath, dir, 1);
	path = realpath.buf;

cleanup_return:
	if (return_error_code)
		*return_error_code = error_code;
	else if (error_code)
		read_gitfile_error_die(error_code, path);

	free(buf);
	return error_code ? NULL : path;
}

static void apply_gitdir_and_environment(struct repository *repo, const char *path)
{
	struct strvec to_free = STRVEC_INIT;
	struct set_gitdir_args args = {
		.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT),
		.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT),
		.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT),
		.disable_ref_updates = !!getenv(GIT_QUARANTINE_ENVIRONMENT),
	};

	repo_set_gitdir(repo, path, &args);

	strvec_clear(&to_free);
}

static void update_relative_gitdir(const char *name UNUSED,
				   const char *old_cwd,
				   const char *new_cwd,
				   void *data)
{
	struct repository *repo = data;
	char *path = reparent_relative_path(old_cwd, new_cwd,
					    repo_get_git_dir(repo));
	trace_printf_key(&trace_setup_key,
			 "setup: move $GIT_DIR to '%s'",
			 path);
	apply_gitdir_and_environment(repo, path);
	xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
	free(path);
}

static void apply_and_export_relative_gitdir(struct repository *repo, const char *path, int make_realpath)
{
	struct strbuf realpath = STRBUF_INIT;

	if (make_realpath) {
		strbuf_realpath(&realpath, path, 1);
		path = realpath.buf;
	}

	apply_gitdir_and_environment(repo, path);
	xsetenv(GIT_DIR_ENVIRONMENT, path, 1);

	if (!is_absolute_path(path))
		chdir_notify_register(NULL, update_relative_gitdir, repo);

	strbuf_release(&realpath);
}

struct repo_discovery {
	struct repository_format format;
	char *gitdir;
	char *worktree;
	char *prefix;
};

#define REPO_DISCOVERY_INIT { \
	.format = REPOSITORY_FORMAT_INIT, \
}

static void repo_discovery_release(struct repo_discovery *r)
{
	clear_repository_format(&r->format);
	free(r->gitdir);
	free(r->worktree);
	free(r->prefix);
}

static void repo_discovery_set_gitdir(struct repo_discovery *r,
				      const char *gitdir,
				      int make_realpath)
{
	free(r->gitdir);
	if (make_realpath) {
		struct strbuf realpath = STRBUF_INIT;
		strbuf_realpath(&realpath, gitdir, 1);
		r->gitdir = strbuf_detach(&realpath, NULL);
	} else {
		r->gitdir = xstrdup(gitdir);
	}
}

static void repo_discovery_set_worktree(struct repo_discovery *r,
					const char *worktree)
{
	free(r->worktree);
	r->worktree = real_pathdup(worktree, 1);
}

static void repo_discover_explicit_gitdir(struct repo_discovery *discovery,
					  const char *gitdirenv,
					  struct strbuf *cwd,
					  int *nongit_ok)
{
	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
	char *gitfile;
	int offset;

	if (PATH_MAX - 40 < strlen(gitdirenv))
		die(_("'$%s' too big"), GIT_DIR_ENVIRONMENT);

	gitfile = (char*)read_gitfile(gitdirenv);
	if (gitfile) {
		gitfile = xstrdup(gitfile);
		gitdirenv = gitfile;
	}

	if (!is_git_directory(gitdirenv)) {
		if (nongit_ok) {
			*nongit_ok = 1;
			goto out;
		}
		die(_("not a git repository: '%s'"), gitdirenv);
	}

	if (read_and_verify_repository_format(&discovery->format, gitdirenv, nongit_ok))
		goto out;

	/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
	if (work_tree_env) {
		/*
		 * The environment variable overrides "core.worktree". This
		 * also has the consequence that we don't want to flag cases as
		 * bogus where we have both "core.worktree" and "core.bare", so
		 * we have to explicitly unset the configuration.
		 */
		FREE_AND_NULL(discovery->format.work_tree);
		repo_discovery_set_worktree(discovery, work_tree_env);
	} else if (discovery->format.is_bare > 0) {
		/* #18, #26 */
		repo_discovery_set_gitdir(discovery, gitdirenv, 0);
		goto out;
	} else if (discovery->format.work_tree) { /* #6, #14 */
		if (is_absolute_path(discovery->format.work_tree)) {
			repo_discovery_set_worktree(discovery, discovery->format.work_tree);
		} else {
			char *core_worktree;
			if (chdir(gitdirenv))
				die_errno(_("cannot chdir to '%s'"), gitdirenv);
			if (chdir(discovery->format.work_tree))
				die_errno(_("cannot chdir to '%s'"), discovery->format.work_tree);
			core_worktree = xgetcwd();
			if (chdir(cwd->buf))
				die_errno(_("cannot come back to cwd"));
			repo_discovery_set_worktree(discovery, core_worktree);
			free(core_worktree);
		}
	} else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
		/* #16d */
		repo_discovery_set_gitdir(discovery, gitdirenv, 0);
		goto out;
	} else { /* #2, #10 */
		repo_discovery_set_worktree(discovery, ".");
	}

	/* both the worktree and cwd are already normalized */
	if (!strcmp(cwd->buf, discovery->worktree)) { /* cwd == worktree */
		repo_discovery_set_gitdir(discovery, gitdirenv, 0);
		goto out;
	}

	offset = dir_inside_of(cwd->buf, discovery->worktree);
	if (offset >= 0) {	/* cwd inside discovery->worktree? */
		repo_discovery_set_gitdir(discovery, gitdirenv, 1);
		if (chdir(discovery->worktree))
			die_errno(_("cannot chdir to '%s'"), discovery->worktree);
		discovery->prefix = xstrfmt("%s/", cwd->buf + offset);
		goto out;
	}

	/* cwd outside worktree */
	repo_discovery_set_gitdir(discovery, gitdirenv, 0);

out:
	free(gitfile);
}

static void repo_discover_implicit_gitdir(struct repo_discovery *discovery,
					  const char *gitdir,
					  struct strbuf *cwd, int offset,
					  int *nongit_ok)
{
	if (read_and_verify_repository_format(&discovery->format, gitdir, nongit_ok))
		return;

	/* --work-tree is set without --git-dir; use discovered one */
	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || discovery->format.work_tree) {
		char *to_free = NULL;

		if (offset != cwd->len && !is_absolute_path(gitdir))
			gitdir = to_free = real_pathdup(gitdir, 1);
		if (chdir(cwd->buf))
			die_errno(_("cannot come back to cwd"));
		repo_discover_explicit_gitdir(discovery, gitdir, cwd,
					      nongit_ok);
		free(to_free);
		return;
	}

	/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
	if (discovery->format.is_bare > 0) {
		repo_discovery_set_gitdir(discovery, gitdir, (offset != cwd->len));
		if (chdir(cwd->buf))
			die_errno(_("cannot come back to cwd"));
		return;
	}

	/* #0, #1, #5, #8, #9, #12, #13 */
	repo_discovery_set_worktree(discovery, ".");
	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
		repo_discovery_set_gitdir(discovery, gitdir, 0);
	if (offset >= cwd->len)
		return;

	/* Make "offset" point past the '/' (already the case for root dirs) */
	if (offset != offset_1st_component(cwd->buf))
		offset++;
	discovery->prefix = xstrfmt("%s/", cwd->buf + offset);
}

/* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
static void repo_discover_bare_gitdir(struct repo_discovery *discovery,
				      struct strbuf *cwd, int offset,
				      int *nongit_ok)
{
	int root_len;

	if (read_and_verify_repository_format(&discovery->format, ".", nongit_ok))
		return;

	setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);

	/* --work-tree is set without --git-dir; use discovered one */
	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || discovery->format.work_tree) {
		char *gitdir = offset == cwd->len ? xstrdup(".") : xmemdupz(cwd->buf, offset);
		if (chdir(cwd->buf))
			die_errno(_("cannot come back to cwd"));
		repo_discover_explicit_gitdir(discovery, gitdir, cwd, nongit_ok);
		free(gitdir);
		return;
	}

	if (offset != cwd->len) {
		if (chdir(cwd->buf))
			die_errno(_("cannot come back to cwd"));
		root_len = offset_1st_component(cwd->buf);
		strbuf_setlen(cwd, offset > root_len ? offset : root_len);
		repo_discovery_set_gitdir(discovery, cwd->buf, 0);
	} else {
		repo_discovery_set_gitdir(discovery, ".", 0);
	}
}

static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_len)
{
	struct stat buf;
	if (stat(path, &buf)) {
		die_errno(_("failed to stat '%*s%s%s'"),
				prefix_len,
				prefix ? prefix : "",
				prefix ? "/" : "", path);
	}
	return buf.st_dev;
}

/*
 * A "string_list_each_func_t" function that canonicalizes an entry
 * from GIT_CEILING_DIRECTORIES using real_pathdup(), or
 * discards it if unusable.  The presence of an empty entry in
 * GIT_CEILING_DIRECTORIES turns off canonicalization for all
 * subsequent entries.
 */
static int canonicalize_ceiling_entry(struct string_list_item *item,
				      void *cb_data)
{
	int *empty_entry_found = cb_data;
	char *ceil = item->string;

	if (!*ceil) {
		*empty_entry_found = 1;
		return 0;
	} else if (!is_absolute_path(ceil)) {
		return 0;
	} else if (*empty_entry_found) {
		/* Keep entry but do not canonicalize it */
		return 1;
	} else {
		char *real_path = real_pathdup(ceil, 0);
		if (!real_path) {
			return 0;
		}
		free(item->string);
		item->string = real_path;
		return 1;
	}
}

struct safe_directory_data {
	char *path;
	int is_safe;
};

static int safe_directory_cb(const char *key, const char *value,
			     const struct config_context *ctx UNUSED, void *d)
{
	struct safe_directory_data *data = d;

	if (strcmp(key, "safe.directory"))
		return 0;

	if (!value || !*value) {
		data->is_safe = 0;
	} else if (!strcmp(value, "*")) {
		data->is_safe = 1;
	} else {
		char *allowed = NULL;

		if (!git_config_pathname(&allowed, key, value) && allowed) {
			char *normalized = NULL;

			/*
			 * Setting safe.directory to a non-absolute path
			 * makes little sense---it won't be relative to
			 * the configuration file the item is defined in.
			 * Except for ".", which means "if we are at the top
			 * level of a repository, then it is OK", which is
			 * slightly tighter than "*" that allows discovery.
			 */
			if (!is_absolute_path(allowed) && strcmp(allowed, ".")) {
				warning(_("safe.directory '%s' not absolute"),
					allowed);
				goto next;
			}

			/*
			 * A .gitconfig in $HOME may be shared across
			 * different machines and safe.directory entries
			 * may or may not exist as paths on all of these
			 * machines.  In other words, it is not a warning
			 * worthy event when there is no such path on this
			 * machine---the entry may be useful elsewhere.
			 */
			normalized = real_pathdup(allowed, 0);
			if (!normalized)
				goto next;

			if (ends_with(normalized, "/*")) {
				size_t len = strlen(normalized);
				if (!fspathncmp(normalized, data->path, len - 1))
					data->is_safe = 1;
			} else if (!fspathcmp(data->path, normalized)) {
				data->is_safe = 1;
			}
		next:
			free(normalized);
			free(allowed);
		}
	}

	return 0;
}

/*
 * Check if a repository is safe, by verifying the ownership of the
 * worktree (if any), the git directory, and the gitfile (if any).
 *
 * Exemptions for known-safe repositories can be added via `safe.directory`
 * config settings; for non-bare repositories, their worktree needs to be
 * added, for bare ones their git directory.
 */
static int ensure_valid_ownership(const char *gitfile,
				  const char *worktree, const char *gitdir,
				  struct strbuf *report)
{
	struct safe_directory_data data = { 0 };

	if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) &&
	    (!gitfile || is_path_owned_by_current_user(gitfile, report)) &&
	    (!worktree || is_path_owned_by_current_user(worktree, report)) &&
	    (!gitdir || is_path_owned_by_current_user(gitdir, report)))
		return 1;

	/*
	 * normalize the data.path for comparison with normalized paths
	 * that come from the configuration file.  The path is unsafe
	 * if it cannot be normalized.
	 */
	data.path = real_pathdup(worktree ? worktree : gitdir, 0);
	if (!data.path)
		return 0;

	/*
	 * data.path is the "path" that identifies the repository and it is
	 * constant regardless of what failed above. data.is_safe should be
	 * initialized to false, and might be changed by the callback.
	 */
	git_protected_config(safe_directory_cb, &data);

	free(data.path);
	return data.is_safe;
}

void die_upon_dubious_ownership(const char *gitfile, const char *worktree,
				const char *gitdir)
{
	struct strbuf report = STRBUF_INIT, quoted = STRBUF_INIT;
	const char *path;

	if (ensure_valid_ownership(gitfile, worktree, gitdir, &report))
		return;

	strbuf_complete(&report, '\n');
	path = gitfile ? gitfile : gitdir;
	sq_quote_buf_pretty(&quoted, path);

	die(_("detected dubious ownership in repository at '%s'\n"
	      "%s"
	      "To add an exception for this directory, call:\n"
	      "\n"
	      "\tgit config --global --add safe.directory %s"),
	    path, report.buf, quoted.buf);
}

static int allowed_bare_repo_cb(const char *key, const char *value,
				const struct config_context *ctx UNUSED,
				void *d)
{
	enum allowed_bare_repo *allowed_bare_repo = d;

	if (strcasecmp(key, "safe.bareRepository"))
		return 0;

	if (!strcmp(value, "explicit")) {
		*allowed_bare_repo = ALLOWED_BARE_REPO_EXPLICIT;
		return 0;
	}
	if (!strcmp(value, "all")) {
		*allowed_bare_repo = ALLOWED_BARE_REPO_ALL;
		return 0;
	}
	return -1;
}

static enum allowed_bare_repo get_allowed_bare_repo(void)
{
#ifdef WITH_BREAKING_CHANGES
	enum allowed_bare_repo result = ALLOWED_BARE_REPO_EXPLICIT;
#else
	enum allowed_bare_repo result = ALLOWED_BARE_REPO_ALL;
#endif
	git_protected_config(allowed_bare_repo_cb, &result);
	return result;
}

static const char *allowed_bare_repo_to_string(
	enum allowed_bare_repo allowed_bare_repo)
{
	switch (allowed_bare_repo) {
	case ALLOWED_BARE_REPO_EXPLICIT:
		return "explicit";
	case ALLOWED_BARE_REPO_ALL:
		return "all";
	default:
		BUG("invalid allowed_bare_repo %d",
		    allowed_bare_repo);
	}
	return NULL;
}

static int is_implicit_bare_repo(const char *path)
{
	/*
	 * what we found is a ".git" directory at the root of
	 * the working tree.
	 */
	if (ends_with_path_components(path, ".git"))
		return 1;

	/*
	 * we are inside $GIT_DIR of a secondary worktree of a
	 * non-bare repository.
	 */
	if (strstr(path, "/.git/worktrees/"))
		return 1;

	/*
	 * we are inside $GIT_DIR of a worktree of a non-embedded
	 * submodule, whose superproject is not a bare repository.
	 */
	if (strstr(path, "/.git/modules/"))
		return 1;

	return 0;
}

/*
 * We cannot decide in this function whether we are in the work tree or
 * not, since the config can only be read _after_ this function was called.
 *
 * Also, we avoid changing any global state (such as the current working
 * directory) to allow early callers.
 *
 * The directory where the search should start needs to be passed in via the
 * `dir` parameter; upon return, the `dir` buffer will contain the path of
 * the directory where the search ended, and `gitdir` will contain the path of
 * the discovered .git/ directory, if any. If `gitdir` is not absolute, it
 * is relative to `dir` (i.e. *not* necessarily the cwd).
 */
static enum discovery_result repo_discovery_find_dir(struct strbuf *dir,
						     struct strbuf *gitdir,
						     struct strbuf *report,
						     int die_on_error)
{
	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
	struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
	const char *gitdirenv;
	int ceil_offset = -1, min_offset = offset_1st_component(dir->buf);
	dev_t current_device = 0;
	int one_filesystem = 1;

	/*
	 * If GIT_DIR is set explicitly, we're not going
	 * to do any discovery, but we still do repository
	 * validation.
	 */
	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
	if (gitdirenv) {
		strbuf_addstr(gitdir, gitdirenv);
		return GIT_DIR_EXPLICIT;
	}

	if (env_ceiling_dirs) {
		int empty_entry_found = 0;
		static const char path_sep[] = { PATH_SEP, '\0' };

		string_list_split(&ceiling_dirs, env_ceiling_dirs, path_sep, -1);
		filter_string_list(&ceiling_dirs, 0,
				   canonicalize_ceiling_entry, &empty_entry_found);
		ceil_offset = longest_ancestor_length(dir->buf, &ceiling_dirs);
		string_list_clear(&ceiling_dirs, 0);
	}

	if (ceil_offset < 0)
		ceil_offset = min_offset - 2;

	if (min_offset && min_offset == dir->len &&
	    !is_dir_sep(dir->buf[min_offset - 1])) {
		strbuf_addch(dir, '/');
		min_offset++;
	}

	/*
	 * Test in the following order (relative to the dir):
	 * - .git (file containing "gitdir: <path>")
	 * - .git/
	 * - ./ (bare)
	 * - ../.git
	 * - ../.git/
	 * - ../ (bare)
	 * - ../../.git
	 *   etc.
	 */
	one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
	if (one_filesystem)
		current_device = get_device_or_die(dir->buf, NULL, 0);
	for (;;) {
		int offset = dir->len, error_code = 0;
		char *gitdir_path = NULL;
		char *gitfile = NULL;

		if (offset > min_offset)
			strbuf_addch(dir, '/');
		strbuf_addstr(dir, DEFAULT_GIT_DIR_ENVIRONMENT);
		gitdirenv = read_gitfile_gently(dir->buf, &error_code);
		if (!gitdirenv) {
			switch (error_code) {
			case READ_GITFILE_ERR_MISSING:
				/* no .git in this directory, move on */
				break;
			case READ_GITFILE_ERR_IS_A_DIR:
				if (is_git_directory(dir->buf)) {
					gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
					gitdir_path = xstrdup(dir->buf);
				}
				break;
			case READ_GITFILE_ERR_STAT_FAILED:
				if (die_on_error)
					die(_("error reading '%s'"), dir->buf);
				else
					return GIT_DIR_INVALID_GITFILE;
			case READ_GITFILE_ERR_NOT_A_FILE:
				if (die_on_error)
					die(_("not a regular file: '%s'"), dir->buf);
				else
					return GIT_DIR_INVALID_GITFILE;
			default:
				if (die_on_error)
					read_gitfile_error_die(error_code, dir->buf);
				else
					return GIT_DIR_INVALID_GITFILE;
			}
		} else {
			gitfile = xstrdup(dir->buf);
		}
		/*
		 * Earlier, we tentatively added DEFAULT_GIT_DIR_ENVIRONMENT
		 * to check that directory for a repository.
		 * Now trim that tentative addition away, because we want to
		 * focus on the real directory we are in.
		 */
		strbuf_setlen(dir, offset);
		if (gitdirenv) {
			enum discovery_result ret;
			const char *gitdir_candidate =
				gitdir_path ? gitdir_path : gitdirenv;

			if (ensure_valid_ownership(gitfile, dir->buf,
						   gitdir_candidate, report)) {
				strbuf_addstr(gitdir, gitdirenv);
				ret = GIT_DIR_DISCOVERED;
			} else
				ret = GIT_DIR_INVALID_OWNERSHIP;

			/*
			 * Earlier, during discovery, we might have allocated
			 * string copies for gitdir_path or gitfile so make
			 * sure we don't leak by freeing them now, before
			 * leaving the loop and function.
			 *
			 * Note: gitdirenv will be non-NULL whenever these are
			 * allocated, therefore we need not take care of releasing
			 * them outside of this conditional block.
			 */
			free(gitdir_path);
			free(gitfile);

			return ret;
		}

		if (is_git_directory(dir->buf)) {
			trace2_data_string("setup", NULL, "implicit-bare-repository", dir->buf);
			if (get_allowed_bare_repo() == ALLOWED_BARE_REPO_EXPLICIT &&
			    !is_implicit_bare_repo(dir->buf))
				return GIT_DIR_DISALLOWED_BARE;
			if (!ensure_valid_ownership(NULL, NULL, dir->buf, report))
				return GIT_DIR_INVALID_OWNERSHIP;
			strbuf_addstr(gitdir, ".");
			return GIT_DIR_BARE;
		}

		if (offset <= min_offset)
			return GIT_DIR_HIT_CEILING;

		while (--offset > ceil_offset && !is_dir_sep(dir->buf[offset]))
			; /* continue */
		if (offset <= ceil_offset)
			return GIT_DIR_HIT_CEILING;

		strbuf_setlen(dir, offset > min_offset ?  offset : min_offset);
		if (one_filesystem &&
		    current_device != get_device_or_die(dir->buf, NULL, offset))
			return GIT_DIR_HIT_MOUNT_POINT;
	}
}

enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
						    struct strbuf *gitdir)
{
	struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
	size_t gitdir_offset = gitdir->len, cwd_len;
	size_t commondir_offset = commondir->len;
	struct repository_format candidate = REPOSITORY_FORMAT_INIT;
	enum discovery_result result;

	if (strbuf_getcwd(&dir))
		return GIT_DIR_CWD_FAILURE;

	cwd_len = dir.len;
	result = repo_discovery_find_dir(&dir, gitdir, NULL, 0);
	if (result <= 0) {
		strbuf_release(&dir);
		return result;
	}

	/*
	 * The returned gitdir is relative to dir, and if dir does not reflect
	 * the current working directory, we simply make the gitdir absolute.
	 */
	if (dir.len < cwd_len && !is_absolute_path(gitdir->buf + gitdir_offset)) {
		/* Avoid a trailing "/." */
		if (!strcmp(".", gitdir->buf + gitdir_offset))
			strbuf_setlen(gitdir, gitdir_offset);
		else
			strbuf_addch(&dir, '/');
		strbuf_insert(gitdir, gitdir_offset, dir.buf, dir.len);
	}

	get_common_dir(commondir, gitdir->buf + gitdir_offset);

	strbuf_reset(&dir);
	strbuf_addf(&dir, "%s/config", commondir->buf + commondir_offset);
	read_repository_format(&candidate, dir.buf);
	strbuf_release(&dir);

	if (verify_repository_format(&candidate, &err) < 0) {
		warning("ignoring git dir '%s': %s",
			gitdir->buf + gitdir_offset, err.buf);
		strbuf_release(&err);
		strbuf_setlen(commondir, commondir_offset);
		strbuf_setlen(gitdir, gitdir_offset);
		clear_repository_format(&candidate);
		return GIT_DIR_INVALID_FORMAT;
	}

	clear_repository_format(&candidate);
	return result;
}

int apply_repository_format(struct repository *repo,
			    const struct repository_format *format,
			    enum apply_repository_format_flags flags,
			    struct strbuf *err)
{
	char *object_directory = NULL, *alternate_object_directories = NULL;

	if (verify_repository_format(format, err) < 0)
		return -1;

	if (format->is_bare > 0 && format->work_tree) {
		/* #22.2, #30 */
		warning("core.bare and core.worktree do not make sense");
		repo->worktree_config_is_bogus = true;
	}

	if (flags & APPLY_REPOSITORY_FORMAT_HONOR_ENV) {
		const char *shallow_file;

		object_directory = xstrdup_or_null(getenv(DB_ENVIRONMENT));
		alternate_object_directories = xstrdup_or_null(getenv(ALTERNATE_DB_ENVIRONMENT));
		shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
		if (shallow_file)
			set_alternate_shallow_file(repo, shallow_file);
	}

	repo->bare_cfg = format->is_bare;
	repo_set_hash_algo(repo, format->hash_algo);
	repo->objects = odb_new(repo, object_directory,
				alternate_object_directories);
	repo_set_compat_hash_algo(repo, format->compat_hash_algo);
	repo_set_ref_storage_format(repo,
				    format->ref_storage_format,
				    format->ref_storage_payload);
	repo->repository_format_worktree_config =
		format->worktree_config;
	repo->repository_format_submodule_path_cfg =
		format->submodule_path_cfg;
	repo->repository_format_relative_worktrees =
		format->relative_worktrees;
	repo->repository_format_partial_clone =
		xstrdup_or_null(format->partial_clone);
	repo->repository_format_precious_objects =
		format->precious_objects;

	free(alternate_object_directories);
	free(object_directory);
	return 0;
}

const char *enter_repo(struct repository *repo, const char *path, unsigned flags)
{
	static struct strbuf validated_path = STRBUF_INIT;
	static struct strbuf used_path = STRBUF_INIT;

	if (!path)
		return NULL;

	if (!(flags & ENTER_REPO_STRICT)) {
		static const char *suffix[] = {
			"/.git", "", ".git/.git", ".git", NULL,
		};
		const char *gitfile;
		int len = strlen(path);
		int i;
		while ((1 < len) && (path[len-1] == '/'))
			len--;

		/*
		 * We can handle arbitrary-sized buffers, but this remains as a
		 * sanity check on untrusted input.
		 */
		if (PATH_MAX <= len)
			return NULL;

		strbuf_reset(&used_path);
		strbuf_reset(&validated_path);
		strbuf_add(&used_path, path, len);
		strbuf_add(&validated_path, path, len);

		if (used_path.buf[0] == '~') {
			char *newpath = interpolate_path(used_path.buf, 0);
			if (!newpath)
				return NULL;
			strbuf_attach(&used_path, newpath, strlen(newpath),
				      strlen(newpath));
		}
		for (i = 0; suffix[i]; i++) {
			struct stat st;
			size_t baselen = used_path.len;
			strbuf_addstr(&used_path, suffix[i]);
			if (!stat(used_path.buf, &st) &&
			    (S_ISREG(st.st_mode) ||
			    (S_ISDIR(st.st_mode) && is_git_directory(used_path.buf)))) {
				strbuf_addstr(&validated_path, suffix[i]);
				break;
			}
			strbuf_setlen(&used_path, baselen);
		}
		if (!suffix[i])
			return NULL;
		gitfile = read_gitfile(used_path.buf);
		if (!(flags & ENTER_REPO_ANY_OWNER_OK))
			die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
		if (gitfile) {
			strbuf_reset(&used_path);
			strbuf_addstr(&used_path, gitfile);
		}
		if (chdir(used_path.buf))
			return NULL;
		path = validated_path.buf;
	}
	else {
		const char *gitfile = read_gitfile(path);
		if (!(flags & ENTER_REPO_ANY_OWNER_OK))
			die_upon_dubious_ownership(gitfile, NULL, path);
		if (gitfile)
			path = gitfile;
		if (chdir(path))
			return NULL;
	}

	if (is_git_directory(".")) {
		struct repository_format fmt = REPOSITORY_FORMAT_INIT;
		struct strbuf err = STRBUF_INIT;

		apply_and_export_relative_gitdir(repo, ".", 0);
		read_and_verify_repository_format(&fmt, ".", NULL);
		if (apply_repository_format(repo, &fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
			die("%s", err.buf);
		startup_info->have_repository = 1;

		clear_repository_format(&fmt);
		strbuf_release(&err);
		return path;
	}

	return NULL;
}

/*
 * Note.  This works only before you used a work tree.  This was added
 * primarily to support git-clone to work in a new repository it just
 * created, and is not meant to flip between different work trees.
 */
static void set_git_work_tree(struct repository *repo, const char *new_work_tree)
{
	if (repo->worktree_initialized) {
		struct strbuf realpath = STRBUF_INIT;

		strbuf_realpath(&realpath, new_work_tree, 1);
		new_work_tree = realpath.buf;
		if (strcmp(new_work_tree, repo->worktree))
			die("internal error: work tree has already been set\n"
			    "Current worktree: %s\nNew worktree: %s",
			    repo->worktree, new_work_tree);
		strbuf_release(&realpath);
		return;
	}
	repo->worktree_initialized = true;
	repo_set_worktree(repo, new_work_tree);
}

static void repo_discover(struct repo_discovery *discovery, int *nongit_ok)
{
	struct strbuf cwd = STRBUF_INIT;
	struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;

	/*
	 * Let's assume that we are in a git repository.
	 * If it turns out later that we are somewhere else, the value will be
	 * updated accordingly.
	 */
	if (nongit_ok)
		*nongit_ok = 0;

	if (strbuf_getcwd(&cwd))
		die_errno(_("Unable to read current working directory"));
	strbuf_addbuf(&dir, &cwd);

	switch (repo_discovery_find_dir(&dir, &gitdir, &report, 1)) {
	case GIT_DIR_EXPLICIT:
		repo_discover_explicit_gitdir(discovery, gitdir.buf, &cwd,
					      nongit_ok);
		break;
	case GIT_DIR_DISCOVERED:
		if (dir.len < cwd.len && chdir(dir.buf))
			die(_("cannot change to '%s'"), dir.buf);
		repo_discover_implicit_gitdir(discovery, gitdir.buf, &cwd, dir.len,
					      nongit_ok);
		break;
	case GIT_DIR_BARE:
		if (dir.len < cwd.len && chdir(dir.buf))
			die(_("cannot change to '%s'"), dir.buf);
		repo_discover_bare_gitdir(discovery, &cwd, dir.len, nongit_ok);
		break;
	case GIT_DIR_HIT_CEILING:
		if (!nongit_ok)
			die(_("not a git repository (or any of the parent directories): %s"),
			    DEFAULT_GIT_DIR_ENVIRONMENT);
		*nongit_ok = 1;
		break;
	case GIT_DIR_HIT_MOUNT_POINT:
		if (!nongit_ok)
			die(_("not a git repository (or any parent up to mount point %s)\n"
			      "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."),
			    dir.buf);
		*nongit_ok = 1;
		break;
	case GIT_DIR_INVALID_OWNERSHIP:
		if (!nongit_ok) {
			struct strbuf quoted = STRBUF_INIT;

			strbuf_complete(&report, '\n');
			sq_quote_buf_pretty(&quoted, dir.buf);
			die(_("detected dubious ownership in repository at '%s'\n"
			      "%s"
			      "To add an exception for this directory, call:\n"
			      "\n"
			      "\tgit config --global --add safe.directory %s"),
			    dir.buf, report.buf, quoted.buf);
		}
		*nongit_ok = 1;
		break;
	case GIT_DIR_DISALLOWED_BARE:
		if (!nongit_ok) {
			die(_("cannot use bare repository '%s' (safe.bareRepository is '%s')"),
			    dir.buf,
			    allowed_bare_repo_to_string(get_allowed_bare_repo()));
		}
		*nongit_ok = 1;
		break;
	case GIT_DIR_CWD_FAILURE:
	case GIT_DIR_INVALID_FORMAT:
		/*
		 * As a safeguard against repo_discovery_find_dir returning
		 * these values, fallthrough to BUG. Otherwise it is possible to
		 * set startup_info->have_repository to 1 when we did nothing to
		 * find a repository.
		 */
	default:
		BUG("unhandled repo_discovery_find_dir() result");
	}

	strbuf_release(&dir);
	strbuf_release(&cwd);
	strbuf_release(&gitdir);
	strbuf_release(&report);
}

const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
{
	struct repo_discovery discovery = REPO_DISCOVERY_INIT;

	/*
	 * We may have read an incomplete configuration before
	 * setting-up the git directory. If so, clear the cache so
	 * that the next queries to the configuration reload complete
	 * configuration (including the per-repo config file that we
	 * ignored previously).
	 */
	repo_config_clear(repo);

	repo_discover(&discovery, nongit_ok);

	/*
	 * At this point, nongit_ok is stable. If it is non-NULL and points
	 * to a non-zero value, then this means that we haven't found a
	 * repository and that the caller expects startup_info to reflect
	 * this.
	 *
	 * Regardless of the state of nongit_ok, the_repository->prefix and
	 * the GIT_PREFIX environment variable must always match. For details
	 * see Documentation/config/alias.adoc.
	 */
	if (nongit_ok && *nongit_ok)
		startup_info->have_repository = 0;
	else
		startup_info->have_repository = 1;

	/*
	 * Not all paths through the setup code will have recorded a gitdir
	 * above, so in order to guarantee that the environment is in a
	 * consistent state after setup, explicitly set up the gitdir and
	 * environment if we have a repository.
	 *
	 * NEEDSWORK: currently we allow bogus GIT_DIR values to be set in some
	 * code paths so we also need to explicitly setup the environment if
	 * the user has set GIT_DIR.  It may be beneficial to disallow bogus
	 * GIT_DIR values at some point in the future.
	 */
	if (/* GIT_DIR_EXPLICIT, GIT_DIR_DISCOVERED, GIT_DIR_BARE */
	    startup_info->have_repository ||
	    /* GIT_DIR_EXPLICIT */
	    getenv(GIT_DIR_ENVIRONMENT)) {
		if (discovery.worktree)
			set_git_work_tree(repo, discovery.worktree);

		if (discovery.gitdir) {
			apply_and_export_relative_gitdir(repo, discovery.gitdir, 0);
		} else {
			const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
			if (!gitdir)
				gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
			apply_gitdir_and_environment(repo, gitdir);
		}

		if (startup_info->have_repository) {
			struct strbuf err = STRBUF_INIT;
			const char *ref_backend_uri;

			/*
			 * The env variable should override the repository config
			 * for 'extensions.refStorage'.
			 */
			ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
			if (ref_backend_uri) {
				char *format;

				free(discovery.format.ref_storage_payload);

				parse_reference_uri(ref_backend_uri, &format, &discovery.format.ref_storage_payload);
				discovery.format.ref_storage_format = ref_storage_format_by_name(format);
				if (discovery.format.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
					die(_("unknown ref storage format: '%s'"), format);

				free(format);
			}

			if (apply_repository_format(repo, &discovery.format,
						    APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
				die("%s", err.buf);

			clear_repository_format(&discovery.format);
			strbuf_release(&err);
		}
	}
	/*
	 * Since precompose_string_if_needed() needs to look at
	 * the core.precomposeunicode configuration, this
	 * has to happen after the above block that finds
	 * out where the repository is, i.e. a preparation
	 * for calling repo_config_get_bool().
	 */
	if (discovery.prefix) {
		const char *prefix = precompose_string_if_needed(discovery.prefix);
		repo->prefix = xstrdup(prefix);
		setenv(GIT_PREFIX_ENVIRONMENT, repo->prefix, 1);
	} else {
		FREE_AND_NULL(repo->prefix);
		setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
	}

	setup_original_cwd(repo);

	repo_discovery_release(&discovery);
	return repo->prefix;
}

int git_config_perm(const char *var, const char *value)
{
	int i;
	char *endptr;

	if (!value)
		return PERM_GROUP;

	if (!strcmp(value, "umask"))
		return PERM_UMASK;
	if (!strcmp(value, "group"))
		return PERM_GROUP;
	if (!strcmp(value, "all") ||
	    !strcmp(value, "world") ||
	    !strcmp(value, "everybody"))
		return PERM_EVERYBODY;

	/* Parse octal numbers */
	i = strtol(value, &endptr, 8);

	/* If not an octal number, maybe true/false? */
	if (*endptr != 0)
		return git_config_bool(var, value) ? PERM_GROUP : PERM_UMASK;

	/*
	 * Treat values 0, 1 and 2 as compatibility cases, otherwise it is
	 * a chmod value to restrict to.
	 */
	switch (i) {
	case PERM_UMASK:               /* 0 */
		return PERM_UMASK;
	case OLD_PERM_GROUP:           /* 1 */
		return PERM_GROUP;
	case OLD_PERM_EVERYBODY:       /* 2 */
		return PERM_EVERYBODY;
	}

	/* A filemode value was given: 0xxx */

	if ((i & 0600) != 0600)
		die(_("problem with core.sharedRepository filemode value "
		    "(0%.3o).\nThe owner of files must always have "
		    "read and write permissions."), i);

	/*
	 * Mask filemode value. Others can not get write permission.
	 * x flags for directories are handled separately.
	 */
	return -(i & 0666);
}

/*
 * Returns the "prefix", a path to the current working directory
 * relative to the work tree root, or NULL, if the current working
 * directory is not a strict subdirectory of the work tree root. The
 * prefix always ends with a '/' character.
 */
const char *setup_git_directory(struct repository *repo)
{
	return setup_git_directory_gently(repo, NULL);
}

const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)
{
	if (is_git_directory(suspect))
		return suspect;
	return read_gitfile_gently(suspect, return_error_code);
}

/* if any standard file descriptor is missing open it to /dev/null */
void sanitize_stdfds(void)
{
	int fd = xopen("/dev/null", O_RDWR);
	while (fd < 2)
		fd = xdup(fd);
	if (fd > 2)
		close(fd);
}

int daemonize(void)
{
#ifdef NO_POSIX_GOODIES
	errno = ENOSYS;
	return -1;
#else
	pid_t parent_pid = getpid();
	pid_t child_pid = fork();

	switch (child_pid) {
		case 0:
			/*
			 * We're in the child process, so we take ownership of
			 * all tempfiles.
			 */
			reassign_tempfile_ownership(parent_pid, getpid());
			break;
		case -1:
			die_errno(_("fork failed"));
		default:
			/*
			 * We're in the parent process, so we drop ownership of
			 * all tempfiles to prevent us from removing them upon
			 * exit.
			 */
			reassign_tempfile_ownership(parent_pid, child_pid);
			exit(0);
	}
	if (setsid() == -1)
		die_errno(_("setsid failed"));
	close(0);
	close(1);
	close(2);
	sanitize_stdfds();
	return 0;
#endif
}

struct template_dir_cb_data {
	char *path;
	int initialized;
};

static int template_dir_cb(const char *key, const char *value,
			   const struct config_context *ctx UNUSED, void *d)
{
	struct template_dir_cb_data *data = d;

	if (strcmp(key, "init.templatedir"))
		return 0;

	if (!value) {
		data->path = NULL;
	} else {
		char *path = NULL;

		FREE_AND_NULL(data->path);
		if (!git_config_pathname(&path, key, value))
			data->path = path ? path : xstrdup(value);
	}

	return 0;
}

const char *get_template_dir(const char *option_template)
{
	const char *template_dir = option_template;

	if (!template_dir)
		template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
	if (!template_dir) {
		static struct template_dir_cb_data data;

		if (!data.initialized) {
			git_protected_config(template_dir_cb, &data);
			data.initialized = 1;
		}
		template_dir = data.path;
	}
	if (!template_dir) {
		static char *dir;

		if (!dir)
			dir = system_path(DEFAULT_GIT_TEMPLATE_DIR);
		template_dir = dir;
	}
	return template_dir;
}

#ifdef NO_TRUSTABLE_FILEMODE
#define TEST_FILEMODE 0
#else
#define TEST_FILEMODE 1
#endif

#define GIT_DEFAULT_HASH_ENVIRONMENT "GIT_DEFAULT_HASH"

static void copy_templates_1(struct repository *repo,
			     struct strbuf *path,
			     struct strbuf *template_path,
			     DIR *dir)
{
	size_t path_baselen = path->len;
	size_t template_baselen = template_path->len;
	struct dirent *de;

	/* Note: if ".git/hooks" file exists in the repository being
	 * re-initialized, /etc/core-git/templates/hooks/update would
	 * cause "git init" to fail here.  I think this is sane but
	 * it means that the set of templates we ship by default, along
	 * with the way the namespace under .git/ is organized, should
	 * be really carefully chosen.
	 */
	safe_create_dir(repo, path->buf, 1);
	while ((de = readdir(dir)) != NULL) {
		struct stat st_git, st_template;
		int exists = 0;

		strbuf_setlen(path, path_baselen);
		strbuf_setlen(template_path, template_baselen);

		if (de->d_name[0] == '.')
			continue;
		strbuf_addstr(path, de->d_name);
		strbuf_addstr(template_path, de->d_name);
		if (lstat(path->buf, &st_git)) {
			if (errno != ENOENT)
				die_errno(_("cannot stat '%s'"), path->buf);
		}
		else
			exists = 1;

		if (lstat(template_path->buf, &st_template))
			die_errno(_("cannot stat template '%s'"), template_path->buf);

		if (S_ISDIR(st_template.st_mode)) {
			DIR *subdir = opendir(template_path->buf);
			if (!subdir)
				die_errno(_("cannot opendir '%s'"), template_path->buf);
			strbuf_addch(path, '/');
			strbuf_addch(template_path, '/');
			copy_templates_1(repo, path, template_path, subdir);
			closedir(subdir);
		}
		else if (exists)
			continue;
		else if (S_ISLNK(st_template.st_mode)) {
			struct strbuf lnk = STRBUF_INIT;
			if (strbuf_readlink(&lnk, template_path->buf,
					    st_template.st_size) < 0)
				die_errno(_("cannot readlink '%s'"), template_path->buf);
			if (symlink(lnk.buf, path->buf))
				die_errno(_("cannot symlink '%s' '%s'"),
					  lnk.buf, path->buf);
			strbuf_release(&lnk);
		}
		else if (S_ISREG(st_template.st_mode)) {
			if (copy_file(path->buf, template_path->buf, st_template.st_mode))
				die_errno(_("cannot copy '%s' to '%s'"),
					  template_path->buf, path->buf);
		}
		else
			error(_("ignoring template %s"), template_path->buf);
	}
}

static void copy_templates(struct repository *repo, const char *option_template)
{
	const char *template_dir = get_template_dir(option_template);
	struct strbuf path = STRBUF_INIT;
	struct strbuf template_path = STRBUF_INIT;
	size_t template_len;
	struct repository_format template_format = REPOSITORY_FORMAT_INIT;
	struct strbuf err = STRBUF_INIT;
	DIR *dir;
	char *to_free = NULL;

	if (!template_dir || !*template_dir)
		return;

	strbuf_addstr(&template_path, template_dir);
	strbuf_complete(&template_path, '/');
	template_len = template_path.len;

	dir = opendir(template_path.buf);
	if (!dir) {
		warning(_("templates not found in %s"), template_dir);
		goto free_return;
	}

	/* Make sure that template is from the correct vintage */
	strbuf_addstr(&template_path, "config");
	read_repository_format(&template_format, template_path.buf);
	strbuf_setlen(&template_path, template_len);

	/*
	 * No mention of version at all is OK, but anything else should be
	 * verified.
	 */
	if (template_format.version >= 0 &&
	    verify_repository_format(&template_format, &err) < 0) {
		warning(_("not copying templates from '%s': %s"),
			  template_dir, err.buf);
		strbuf_release(&err);
		goto close_free_return;
	}

	strbuf_addstr(&path, repo_get_common_dir(repo));
	strbuf_complete(&path, '/');
	copy_templates_1(repo, &path, &template_path, dir);
close_free_return:
	closedir(dir);
free_return:
	free(to_free);
	strbuf_release(&path);
	strbuf_release(&template_path);
	clear_repository_format(&template_format);
}

/*
 * If the git_dir is not directly inside the working tree, then git will not
 * find it by default, and we need to set the worktree explicitly.
 */
static int needs_work_tree_config(const char *git_dir, const char *work_tree)
{
	if (!strcmp(work_tree, "/") && !strcmp(git_dir, "/.git"))
		return 0;
	if (skip_prefix(git_dir, work_tree, &git_dir) &&
	    !strcmp(git_dir, "/.git"))
		return 0;
	return 1;
}

void initialize_repository_version(struct repository *repo,
				   int hash_algo,
				   enum ref_storage_format ref_storage_format,
				   int reinit)
{
	struct strbuf repo_version = STRBUF_INIT;
	int target_version = GIT_REPO_VERSION;
	int default_submodule_path_config = 0;

	/*
	 * Note that we initialize the repository version to 1 when the ref
	 * storage format is unknown. This is on purpose so that we can add the
	 * correct object format to the config during git-clone(1). The format
	 * version will get adjusted by git-clone(1) once it has learned about
	 * the remote repository's format.
	 */
	if (hash_algo != GIT_HASH_SHA1_LEGACY ||
	    ref_storage_format != REF_STORAGE_FORMAT_FILES ||
	    repo->ref_storage_payload)
		target_version = GIT_REPO_VERSION_READ;

	if (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN)
		repo_config_set(repo, "extensions.objectformat",
				hash_algos[hash_algo].name);
	else if (reinit)
		repo_config_set_gently(repo, "extensions.objectformat", NULL);

	if (repo->ref_storage_payload) {
		struct strbuf ref_uri = STRBUF_INIT;

		strbuf_addf(&ref_uri, "%s://%s",
			    ref_storage_format_to_name(ref_storage_format),
			    repo->ref_storage_payload);
		repo_config_set(repo, "extensions.refstorage", ref_uri.buf);
		strbuf_release(&ref_uri);
	} else if (ref_storage_format != REF_STORAGE_FORMAT_FILES) {
		repo_config_set(repo, "extensions.refstorage",
				ref_storage_format_to_name(ref_storage_format));
	} else if (reinit) {
		repo_config_set_gently(repo, "extensions.refstorage", NULL);
	}

	if (reinit) {
		struct strbuf config = STRBUF_INIT;
		struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;

		repo_common_path_append(repo, &config, "config");
		read_repository_format(&repo_fmt, config.buf);

		if (repo_fmt.v1_only_extensions.nr)
			target_version = GIT_REPO_VERSION_READ;

		strbuf_release(&config);
		clear_repository_format(&repo_fmt);
	}

	repo_config_get_bool(repo, "init.defaultSubmodulePathConfig",
			     &default_submodule_path_config);
	if (default_submodule_path_config) {
		/* extensions.submodulepathconfig requires at least version 1 */
		if (target_version == 0)
			target_version = 1;
		repo_config_set(repo, "extensions.submodulepathconfig", "true");
	}

	strbuf_addf(&repo_version, "%d", target_version);
	repo_config_set(repo, "core.repositoryformatversion", repo_version.buf);

	strbuf_release(&repo_version);
}

static int is_reinit(struct repository *repo)
{
	struct strbuf buf = STRBUF_INIT;
	char junk[2];
	int ret;

	repo_git_path_replace(repo, &buf, "HEAD");
	ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;
	strbuf_release(&buf);
	return ret;
}

void create_reference_database(struct repository *repo,
			       const char *initial_branch, int quiet)
{
	struct strbuf err = STRBUF_INIT;
	char *to_free = NULL;
	int reinit = is_reinit(repo);

	if (ref_store_create_on_disk(get_main_ref_store(repo), 0, &err))
		die("failed to set up refs db: %s", err.buf);

	/*
	 * Point the HEAD symref to the initial branch with if HEAD does
	 * not yet exist.
	 */
	if (!reinit) {
		char *ref;

		if (!initial_branch)
			initial_branch = to_free =
				repo_default_branch_name(repo, quiet);

		ref = xstrfmt("refs/heads/%s", initial_branch);
		if (check_refname_format(ref, 0) < 0)
			die(_("invalid initial branch name: '%s'"),
			    initial_branch);

		if (refs_update_symref(get_main_ref_store(repo), "HEAD", ref, NULL) < 0)
			exit(1);
		free(ref);
	}

	if (reinit && initial_branch)
		warning(_("re-init: ignored --initial-branch=%s"),
			initial_branch);

	strbuf_release(&err);
	free(to_free);
}

static int create_default_files(struct repository *repo,
				const char *template_path,
				const char *original_git_dir,
				const struct repository_format *fmt,
				int init_shared_repository)
{
	struct stat st1;
	struct strbuf path = STRBUF_INIT;
	int reinit;
	int filemode;
	const char *work_tree = repo_get_work_tree(repo);

	/*
	 * First copy the templates -- we might have the default
	 * config file there, in which case we would want to read
	 * from it after installing.
	 *
	 * Before reading that config, we also need to clear out any cached
	 * values (since we've just potentially changed what's available on
	 * disk).
	 */
	copy_templates(repo, template_path);
	repo_config_clear(repo);
	repo_settings_reset_shared_repository(repo);
	repo_config(repo, git_default_config, NULL);

	reinit = is_reinit(repo);

	/*
	 * We must make sure command-line options continue to override any
	 * values we might have just re-read from the config.
	 */
	if (init_shared_repository != -1)
		repo_settings_set_shared_repository(repo,
						    init_shared_repository);

	repo->bare_cfg = !work_tree;

	/*
	 * We would have created the above under user's umask -- under
	 * shared-repository settings, we would need to fix them up.
	 */
	if (repo_settings_get_shared_repository(repo)) {
		adjust_shared_perm(repo, repo_get_git_dir(repo));
	}

	initialize_repository_version(repo, fmt->hash_algo, fmt->ref_storage_format, reinit);

	/* Check filemode trustability */
	repo_git_path_replace(repo, &path, "config");
	filemode = TEST_FILEMODE;
	if (TEST_FILEMODE && !lstat(path.buf, &st1)) {
		struct stat st2;
		filemode = (!chmod(path.buf, st1.st_mode ^ S_IXUSR) &&
				!lstat(path.buf, &st2) &&
				st1.st_mode != st2.st_mode &&
				!chmod(path.buf, st1.st_mode));
		if (filemode && !reinit && (st1.st_mode & S_IXUSR))
			filemode = 0;
	}
	repo_config_set(repo, "core.filemode", filemode ? "true" : "false");

	if (is_bare_repository(repo))
		repo_config_set(repo, "core.bare", "true");
	else {
		const char *value;

		repo_config_set(repo, "core.bare", "false");

		/* allow template config file to override the default */
		if (repo_config_get_string_tmp(repo, "core.logallrefupdates", &value))
			repo_config_set(repo, "core.logallrefupdates", "true");

		if (needs_work_tree_config(original_git_dir, work_tree))
			repo_config_set(repo, "core.worktree", work_tree);
	}

	if (!reinit) {
		/* Check if symlink is supported in the work tree */
		repo_git_path_replace(repo, &path, "tXXXXXX");
		if (!close(xmkstemp(path.buf)) &&
		    !unlink(path.buf) &&
		    !symlink("testing", path.buf) &&
		    !lstat(path.buf, &st1) &&
		    S_ISLNK(st1.st_mode))
			unlink(path.buf); /* good */
		else
			repo_config_set(repo, "core.symlinks", "false");

		/* Check if the filesystem is case-insensitive */
		repo_git_path_replace(repo, &path, "CoNfIg");
		if (!access(path.buf, F_OK))
			repo_config_set(repo, "core.ignorecase", "true");
		probe_utf8_pathname_composition();
	}

	strbuf_release(&path);
	return reinit;
}

static void create_object_directory(struct repository *repo)
{
	struct strbuf path = STRBUF_INIT;
	size_t baselen;

	strbuf_addstr(&path, repo_get_object_directory(repo));
	baselen = path.len;

	safe_create_dir(repo, path.buf, 1);

	strbuf_setlen(&path, baselen);
	strbuf_addstr(&path, "/pack");
	safe_create_dir(repo, path.buf, 1);

	strbuf_setlen(&path, baselen);
	strbuf_addstr(&path, "/info");
	safe_create_dir(repo, path.buf, 1);

	strbuf_release(&path);
}

static void separate_git_dir(const char *git_dir, const char *git_link)
{
	struct stat st;

	if (!stat(git_link, &st)) {
		const char *src;

		if (S_ISREG(st.st_mode))
			src = read_gitfile(git_link);
		else if (S_ISDIR(st.st_mode))
			src = git_link;
		else
			die(_("unable to handle file type %d"), (int)st.st_mode);

		if (rename(src, git_dir))
			die_errno(_("unable to move %s to %s"), src, git_dir);
		repair_worktrees_after_gitdir_move(src);
	}

	write_file(git_link, "gitdir: %s", git_dir);
}

struct default_format_config {
	int hash;
	enum ref_storage_format ref_format;
};

static int read_default_format_config(const char *key, const char *value,
				      const struct config_context *ctx UNUSED,
				      void *payload)
{
	struct default_format_config *cfg = payload;
	char *str = NULL;
	int ret;

	if (!strcmp(key, "init.defaultobjectformat")) {
		ret = git_config_string(&str, key, value);
		if (ret)
			goto out;
		cfg->hash = hash_algo_by_name(str);
		if (cfg->hash == GIT_HASH_UNKNOWN)
			warning(_("unknown hash algorithm '%s'"), str);
		goto out;
	}

	if (!strcmp(key, "init.defaultrefformat")) {
		ret = git_config_string(&str, key, value);
		if (ret)
			goto out;
		cfg->ref_format = ref_storage_format_by_name(str);
		if (cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN)
			warning(_("unknown ref storage format '%s'"), str);
		goto out;
	}

	/*
	 * Enable the reftable format when "features.experimental" is enabled.
	 * "init.defaultRefFormat" takes precedence over this setting.
	 */
	if (!strcmp(key, "feature.experimental") &&
	    cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN &&
	    git_config_bool(key, value)) {
		cfg->ref_format = REF_STORAGE_FORMAT_REFTABLE;
		ret = 0;
		goto out;
	}

	ret = 0;
out:
	free(str);
	return ret;
}

static void repository_format_configure(struct repository_format *repo_fmt,
					int hash, enum ref_storage_format ref_format)
{
	struct default_format_config cfg = {
		.hash = GIT_HASH_UNKNOWN,
		.ref_format = REF_STORAGE_FORMAT_UNKNOWN,
	};
	struct config_options opts = {
		.respect_includes = 1,
		.ignore_repo = 1,
		.ignore_worktree = 1,
	};
	const char *ref_backend_uri;
	const char *env;

	config_with_options(read_default_format_config, &cfg, NULL, NULL, &opts);

	/*
	 * If we already have an initialized repo, don't allow the user to
	 * specify a different algorithm, as that could cause corruption.
	 * Otherwise, if the user has specified one on the command line, use it.
	 */
	env = getenv(GIT_DEFAULT_HASH_ENVIRONMENT);
	if (repo_fmt->version >= 0 && hash != GIT_HASH_UNKNOWN && hash != repo_fmt->hash_algo)
		die(_("attempt to reinitialize repository with different hash"));
	else if (hash != GIT_HASH_UNKNOWN)
		repo_fmt->hash_algo = hash;
	else if (env) {
		int env_algo = hash_algo_by_name(env);
		if (env_algo == GIT_HASH_UNKNOWN)
			die(_("unknown hash algorithm '%s'"), env);
		if (repo_fmt->version < 0 ||
		    repo_fmt->hash_algo == GIT_HASH_UNKNOWN)
			repo_fmt->hash_algo = env_algo;
	} else if (cfg.hash != GIT_HASH_UNKNOWN) {
		repo_fmt->hash_algo = cfg.hash;
	}

	env = getenv("GIT_DEFAULT_REF_FORMAT");
	if (repo_fmt->version >= 0 &&
	    ref_format != REF_STORAGE_FORMAT_UNKNOWN &&
	    ref_format != repo_fmt->ref_storage_format) {
		die(_("attempt to reinitialize repository with different reference storage format"));
	} else if (ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
		repo_fmt->ref_storage_format = ref_format;
	} else if (env) {
		ref_format = ref_storage_format_by_name(env);
		if (ref_format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format '%s'"), env);
		if (repo_fmt->version < 0 ||
		    repo_fmt->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			repo_fmt->ref_storage_format = ref_format;
	} else if (cfg.ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
		repo_fmt->ref_storage_format = cfg.ref_format;
	} else {
		repo_fmt->ref_storage_format = REF_STORAGE_FORMAT_DEFAULT;
	}


	ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
	if (ref_backend_uri) {
		char *backend, *payload;
		enum ref_storage_format format;

		parse_reference_uri(ref_backend_uri, &backend, &payload);
		format = ref_storage_format_by_name(backend);
		if (format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format: '%s'"), backend);

		repo_fmt->ref_storage_format = format;
		repo_fmt->ref_storage_payload = payload;

		free(backend);
	}
}

int init_db(struct repository *repo,
	    const char *git_dir,
	    const char *real_git_dir,
	    const char *worktree,
	    const char *template_dir, int hash,
	    enum ref_storage_format ref_storage_format,
	    const char *initial_branch,
	    int init_shared_repository, unsigned int flags)
{
	int reinit;
	int exist_ok = flags & INIT_DB_EXIST_OK;
	char *original_git_dir = real_pathdup(git_dir, 1);
	struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
	struct strbuf err = STRBUF_INIT;

	if (real_git_dir) {
		struct stat st;

		if (!exist_ok && !stat(git_dir, &st))
			die(_("%s already exists"), git_dir);

		if (!exist_ok && !stat(real_git_dir, &st))
			die(_("%s already exists"), real_git_dir);

		apply_and_export_relative_gitdir(repo, real_git_dir, 1);
		git_dir = repo_get_git_dir(repo);
		separate_git_dir(git_dir, original_git_dir);
	} else {
		apply_and_export_relative_gitdir(repo, git_dir, 1);
		git_dir = repo_get_git_dir(repo);
	}

	if (worktree)
		set_git_work_tree(repo, worktree);

	/*
	 * Check to see if the repository version is right.
	 * Note that a newly created repository does not have
	 * config file, so this will not fail.  What we are catching
	 * is an attempt to reinitialize new repository with an old tool.
	 */
	read_and_verify_repository_format(&repo_fmt, repo_get_git_dir(repo), NULL);
	repository_format_configure(&repo_fmt, hash, ref_storage_format);
	if (apply_repository_format(repo, &repo_fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
		die("%s", err.buf);
	startup_info->have_repository = 1;

	/*
	 * Ensure `core.hidedotfiles` is processed. This must happen after we
	 * have set up the repository format such that we can evaluate
	 * includeIf conditions correctly in the case of re-initialization.
	 */
	repo_config(repo, git_default_core_config, NULL);

	safe_create_dir(repo, git_dir, 0);

	reinit = create_default_files(repo, template_dir, original_git_dir,
				      &repo_fmt, init_shared_repository);

	if (!(flags & INIT_DB_SKIP_REFDB))
		create_reference_database(repo, initial_branch, flags & INIT_DB_QUIET);
	create_object_directory(repo);

	if (repo_settings_get_shared_repository(repo)) {
		char buf[10];
		/* We do not spell "group" and such, so that
		 * the configuration can be read by older version
		 * of git. Note, we use octal numbers for new share modes,
		 * and compatibility values for PERM_GROUP and
		 * PERM_EVERYBODY.
		 */
		if (repo_settings_get_shared_repository(repo) < 0)
			/* force to the mode value */
			xsnprintf(buf, sizeof(buf), "0%o", -repo_settings_get_shared_repository(repo));
		else if (repo_settings_get_shared_repository(repo) == PERM_GROUP)
			xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP);
		else if (repo_settings_get_shared_repository(repo) == PERM_EVERYBODY)
			xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY);
		else
			BUG("invalid value for shared_repository");
		repo_config_set(repo, "core.sharedrepository", buf);
		repo_config_set(repo, "receive.denyNonFastforwards", "true");
	}

	if (!(flags & INIT_DB_QUIET)) {
		int len = strlen(git_dir);

		if (reinit)
			printf(repo_settings_get_shared_repository(repo)
			       ? _("Reinitialized existing shared Git repository in %s%s\n")
			       : _("Reinitialized existing Git repository in %s%s\n"),
			       git_dir, len && git_dir[len-1] != '/' ? "/" : "");
		else
			printf(repo_settings_get_shared_repository(repo)
			       ? _("Initialized empty shared Git repository in %s%s\n")
			       : _("Initialized empty Git repository in %s%s\n"),
			       git_dir, len && git_dir[len-1] != '/' ? "/" : "");
	}

	clear_repository_format(&repo_fmt);
	strbuf_release(&err);
	free(original_git_dir);
	return 0;
}
