#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;
}

/*
 * 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;

		if (!value)
			return config_error_nonbool(var);

		FREE_AND_NULL(data->ref_storage_payload);
		format = ref_storage_format_by_uri(value,
						   &data->ref_storage_payload);

		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)
{
	int error_code = 0;
	const char *slash;
	struct strbuf contents = STRBUF_INIT;
	static struct strbuf realpath = STRBUF_INIT;

	error_code = read_gitfile_raw(&contents, path);
	if (error_code)
		goto cleanup_return;

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

	strbuf_realpath(&realpath, contents.buf, 1);

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

	strbuf_release(&contents);
	return error_code ? NULL : realpath.buf;
}

/*
 * Read the path following "gitdir: " from the .git file into strbuf.
 *
 * Unlike read_gitfile_gently(), this function does not resolve a
 * relative path or validate it using is_git_directory().
 */
int read_gitfile_raw(struct strbuf *contents, const char *path)
{
	const int max_file_size = 1 << 20;  /* 1MB */
	int error_code = 0;
	char *buf = NULL;
	struct stat st;
	int fd;
	ssize_t len;

	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;
	}
	strbuf_add(contents, buf+8, len-8);

cleanup_return:
	free(buf);
	return error_code;
}

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 *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(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;
	}
}

void path_allowlist_apply(const char *allowed, const char *target_path,
			  bool *matches,
			  bool (*allow_path)(const char *path, void *cbdata),
			  void *allow_path_cbdata)
{
	char *normalized = NULL;

	if (!allowed || !*allowed) {
		*matches = false;
		return;
	}

	if (!strcmp(allowed, "*")) {
		*matches = true;
		return;
	}

	if (!allow_path(allowed, allow_path_cbdata))
		return;

	/*
	 * A .gitconfig in $HOME may be shared across different
	 * machines and the config variable 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.
	 *
	 * NEEDSWORK: this also silently ignores misspelled paths. We
	 * may want to warn about a missing path unless it is marked
	 * as allowed to be missing, e.g., with an ":(optional)"
	 * prefix like pathname-typed configuration values, and hint
	 * about that prefix in the warning.
	 */
	normalized = real_pathdup(allowed, 0);
	if (!normalized)
		return;

	if (ends_with(normalized, "/*")) {
		size_t len = strlen(normalized);
		if (!fspathncmp(normalized, target_path, len - 1))
			*matches = true;
	} else if (!fspathcmp(target_path, normalized)) {
		*matches = true;
	}

	free(normalized);
}

void path_allowlist_config_apply(const char *key, const char *value,
				 const char *target_path, bool *matches,
				 bool (*allow_path)(const char *path, void *cbdata),
				 void *allow_path_cbdata)
{
	char *allowed = NULL;

	if (!value || !*value || !strcmp(value, "*")) {
		path_allowlist_apply(value, target_path, matches,
				     allow_path, allow_path_cbdata);
		return;
	}

	if (git_config_pathname(&allowed, key, value) || !allowed)
		return;

	path_allowlist_apply(allowed, target_path, matches,
			     allow_path, allow_path_cbdata);

	free(allowed);
}

/*
 * Setting the config variable 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.
 */
static bool allow_safe_dir(const char *path, void *cbdata_)
{
	struct path_allowlist_cb_data *cbdata = cbdata_;

	if (is_absolute_path(path) || !strcmp(path, "."))
		return true;

	warning(_("%s '%s' not absolute"), cbdata->key, path);
	return false;
}

struct safe_directory_data {
	char *path;
	bool 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;
	struct path_allowlist_cb_data cbdata = { .key = key };

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

	path_allowlist_config_apply(key, value, data->path, &data->is_safe,
				    allow_safe_dir, &cbdata);

	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)
{
	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;

		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_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;

	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);
		repo->objects = odb_new(repo, ODB_NEW_HONOR_ENV);
		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_REF_STORAGE_FORMAT_ENVIRONMENT);
			if (!ref_backend_uri)
				ref_backend_uri = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT);
			if (ref_backend_uri) {
				FREE_AND_NULL(discovery.format.ref_storage_payload);
				discovery.format.ref_storage_format =
					ref_storage_format_by_uri(ref_backend_uri,
								  &discovery.format.ref_storage_payload);
				if (discovery.format.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
					die(_("unknown ref storage format: '%s'"), ref_backend_uri);
			}

			if (apply_repository_format(repo, &discovery.format,
						    APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
				die("%s", err.buf);
			repo->objects = odb_new(repo, ODB_NEW_HONOR_ENV);

			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(repo, 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;
}

void create_object_database(struct repository *repo,
			    const struct strvec *alternates)
{
	struct odb_create_on_disk_options opts = {
		.alternates = alternates,
	};

	/*
	 * Create the "objects" directory in the common directory. This is done
	 * so that the repository can be discovered regardless of the backend
	 * used.
	 *
	 * Note that we only do this in case the object directory wasn't
	 * overwritten via an environment variable. If it _is_ being overridden
	 * then we skip this step, as the repository won't be discoverable
	 * anyway without the environment variable.
	 */
	if (!getenv(DB_ENVIRONMENT)) {
		struct strbuf objects_dir = STRBUF_INIT;
		repo_common_path_append(repo, &objects_dir, "objects");
		safe_create_dir(repo, objects_dir.buf, 1);
		strbuf_release(&objects_dir);
	}

	repo->objects = odb_new(repo, ODB_NEW_HONOR_ENV);

	if (odb_source_create_on_disk(repo->objects->source, &opts) < 0)
		die(_("failed creating object database"));
}

static void separate_git_dir(struct repository *repo,
			     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(repo, src);
	}

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

struct default_format_config {
	int hash;
	enum ref_storage_format ref_storage_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.defaultrefstorageformat") ||
	    !strcmp(key, "init.defaultrefformat")) {
		ret = git_config_string(&str, key, value);
		if (ret)
			goto out;
		cfg->ref_storage_format = ref_storage_format_by_name(str);
		if (cfg->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			warning(_("unknown ref storage format '%s'"), str);
		goto out;
	}

	/*
	 * Enable the reftable format when "features.experimental" is enabled.
	 * "init.defaultRefStorageFormat" takes precedence over this setting.
	 */
	if (!strcmp(key, "feature.experimental") &&
	    cfg->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN &&
	    git_config_bool(key, value)) {
		cfg->ref_storage_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,
					const char *ref_storage_format_uri)
{
	struct default_format_config cfg = {
		.hash = GIT_HASH_UNKNOWN,
		.ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN,
	};
	struct config_options opts = {
		.respect_includes = 1,
		.ignore_repo = 1,
		.ignore_worktree = 1,
	};
	enum ref_storage_format ref_storage_format;
	char *ref_storage_payload = NULL;
	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;
	}

	/*
	 * We have the following order of preference when configuring the ref
	 * storage format:
	 *
	 *   1. Explicit override via the command line, like in `git init
	 *      --ref-storage-format=`.
	 *
	 *   2. Explicit override via the environment with
	 *      "GIT_REF_STORAGE_FORMAT".
	 *
	 *   3. Its deprecated equivalent "GIT_REFERENCE_BACKEND".
	 *
	 *   4. Existing repository format. All the subsequent sources only
	 *      kick in when there is no repository yet.
	 *
	 *   4. The default ref storage format for new repositories as
	 *      configured via "GIT_DEFAULT_REF_STORAGE_FORMAT".
	 *
	 *   5. Its deprecated equivalent "GIT_DEFAULT_REF_FORMAT".
	 *
	 *   6. The default ref storage format for new repositories as
	 *      configured via "init.defaultRefStorageFormat" or its deprecated
	 *      equivalent "init.defaultRefFormat".
	 *
	 *   7. Otherwise, we fall back to the default ref storage format
	 *      compiled into Git.
	 */
	if (ref_storage_format_uri) {
		ref_storage_format = ref_storage_format_by_uri(ref_storage_format_uri,
							       &ref_storage_payload);
		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format specified via command line: '%s'"),
			    ref_storage_format_uri);
	} else if ((env = getenv(GIT_REF_STORAGE_FORMAT_ENVIRONMENT))) {
		ref_storage_format = ref_storage_format_by_uri(env, &ref_storage_payload);
		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format specified via %s: '%s'"),
			    GIT_REF_STORAGE_FORMAT_ENVIRONMENT, env);
	} else if ((env = getenv(GIT_REFERENCE_BACKEND_ENVIRONMENT))) {
		ref_storage_format = ref_storage_format_by_uri(env, &ref_storage_payload);
		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format specified via %s: '%s'"),
			    GIT_REFERENCE_BACKEND_ENVIRONMENT, env);
	} else if (repo_fmt->version >= 0) {
		ref_storage_format = repo_fmt->ref_storage_format;
		ref_storage_payload = xstrdup_or_null(repo_fmt->ref_storage_payload);
	} else if ((env = getenv("GIT_DEFAULT_REF_STORAGE_FORMAT"))) {
		ref_storage_format = ref_storage_format_by_name(env);
		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format specified via %s: '%s'"),
			    "GIT_DEFAULT_REF_STORAGE_FORMAT", env);
	} else if ((env = getenv("GIT_DEFAULT_REF_FORMAT"))) {
		ref_storage_format = ref_storage_format_by_name(env);
		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
			die(_("unknown ref storage format specified via %s: '%s'"),
			    "GIT_DEFAULT_REF_FORMAT", env);
	} else if (cfg.ref_storage_format != REF_STORAGE_FORMAT_UNKNOWN) {
		ref_storage_format = cfg.ref_storage_format;
	} else {
		ref_storage_format = REF_STORAGE_FORMAT_DEFAULT;
	}

	/*
	 * If we have a preexisting repository we need to verify that its
	 * current ref storage format does not change.
	 */
	if (repo_fmt->version >= 0) {
		if (ref_storage_format != repo_fmt->ref_storage_format)
			die(_("attempt to reinitialize repository with different reference storage format"));
		if ((ref_storage_payload || repo_fmt->ref_storage_payload) &&
		    strcmp(ref_storage_payload ? ref_storage_payload : "",
			   repo_fmt->ref_storage_payload ? repo_fmt->ref_storage_payload : ""))
			die(_("attempt to reinitialize repository with different reference storage payload"));
	}

	free(repo_fmt->ref_storage_payload);
	repo_fmt->ref_storage_format = ref_storage_format;
	repo_fmt->ref_storage_payload = ref_storage_payload;
}

void create_repository(struct repository *repo,
		       const char *git_dir,
		       const char *real_git_dir,
		       const char *worktree,
		       const char *template_dir,
		       int hash,
		       const char *ref_storage_format_uri,
		       int init_shared_repository,
		       int *reinit_ok)
{
	int reinit_ignored;
	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 (!reinit_ok && !stat(git_dir, &st))
			die(_("%s already exists"), git_dir);

		if (!reinit_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(repo, 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_uri);
	if (apply_repository_format(repo, &repo_fmt, APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
		die("%s", err.buf);

	/*
	 * 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);

	if (!reinit_ok)
		reinit_ok = &reinit_ignored;
	*reinit_ok = create_default_files(repo, template_dir, original_git_dir,
					  &repo_fmt, init_shared_repository);

	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");
	}

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