#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "abspath.h"
#include "environment.h"
#include "gettext.h"
#include "path.h"
#include "repository.h"
#include "refs.h"
#include "setup.h"
#include "strbuf.h"
#include "worktree.h"
#include "dir.h"
#include "wt-status.h"
#include "config.h"

void free_worktree(struct worktree *worktree)
{
	if (!worktree)
		return;
	free(worktree->path);
	free(worktree->id);
	free(worktree->head_ref);
	free(worktree->lock_reason);
	free(worktree->prune_reason);
	free(worktree);
}

void free_worktrees(struct worktree **worktrees)
{
	int i = 0;
	for (i = 0; worktrees[i]; i++)
		free_worktree(worktrees[i]);
	free (worktrees);
}

/**
 * Update head_oid, head_ref and is_detached of the given worktree
 */
static void add_head_info(struct worktree *wt)
{
	int flags;
	const char *target;

	target = refs_resolve_ref_unsafe(get_worktree_ref_store(wt),
					 "HEAD",
					 0,
					 &wt->head_oid, &flags);
	if (!target)
		return;

	if (flags & REF_ISSYMREF)
		wt->head_ref = xstrdup(target);
	else
		wt->is_detached = 1;
}

static int is_current_worktree(struct worktree *wt)
{
	char *git_dir = absolute_pathdup(repo_get_git_dir(wt->repo));
	char *wt_git_dir = get_worktree_git_dir(wt);
	int is_current = !fspathcmp(git_dir, absolute_path(wt_git_dir));
	free(wt_git_dir);
	free(git_dir);
	return is_current;
}

struct worktree *get_current_worktree(struct repository *repo)
{
	struct worktree *wt = xcalloc(1, sizeof(*wt));
	char *gitdir = absolute_pathdup(repo->gitdir);
	char *commondir = absolute_pathdup(repo->commondir);

	wt->repo = repo;
	wt->path = absolute_pathdup(repo->worktree ? repo->worktree
						   : repo->gitdir);
	wt->is_bare = !repo->worktree;
	if (fspathcmp(gitdir, commondir))
		wt->id = xstrdup(find_last_dir_sep(gitdir) + 1);
	wt->is_current = true;
	add_head_info(wt);

	free(gitdir);
	free(commondir);
	return wt;
}

/*
* When in a secondary worktree, and when extensions.worktreeConfig
* is true, only $commondir/config and $commondir/worktrees/<id>/
* config.worktree are consulted, hence any core.bare=true setting in
* $commondir/config.worktree gets overlooked. Thus, check it manually
* to determine if the repository is bare.
*/
static int is_main_worktree_bare(struct repository *repo)
{
	int bare = 0;
	struct config_set cs = {0};
	char *worktree_config = xstrfmt("%s/config.worktree", repo_get_common_dir(repo));

	git_configset_init(&cs);
	git_configset_add_file(&cs, worktree_config);
	git_configset_get_bool(&cs, "core.bare", &bare);

	git_configset_clear(&cs);
	free(worktree_config);
	return bare;
}

/**
 * get the main worktree
 */
static struct worktree *get_main_worktree(int skip_reading_head)
{
	struct worktree *worktree = NULL;
	struct strbuf worktree_path = STRBUF_INIT;

	strbuf_add_real_path(&worktree_path, repo_get_common_dir(the_repository));
	strbuf_strip_suffix(&worktree_path, "/.git");

	CALLOC_ARRAY(worktree, 1);
	worktree->repo = the_repository;
	worktree->path = strbuf_detach(&worktree_path, NULL);
	worktree->is_current = is_current_worktree(worktree);
	worktree->is_bare = (the_repository->bare_cfg == 1) ||
		is_bare_repository(the_repository) ||
		/*
		 * When in a secondary worktree we have to also verify if the main
		 * worktree is bare in $commondir/config.worktree.
		 * This check is unnecessary if we're currently in the main worktree,
		 * as prior checks already consulted all configs of the current worktree.
		 */
		(!worktree->is_current && is_main_worktree_bare(the_repository));

	if (!skip_reading_head)
		add_head_info(worktree);
	return worktree;
}

struct worktree *get_linked_worktree(const char *id,
				     int skip_reading_head)
{
	struct worktree *worktree = NULL;
	struct strbuf path = STRBUF_INIT;
	struct strbuf worktree_path = STRBUF_INIT;

	if (!id)
		die("Missing linked worktree name");

	repo_common_path_append(the_repository, &path, "worktrees/%s/gitdir", id);
	if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0)
		/* invalid gitdir file */
		goto done;
	strbuf_rtrim(&worktree_path);
	strbuf_strip_suffix(&worktree_path, "/.git");

	if (!is_absolute_path(worktree_path.buf)) {
		strbuf_strip_suffix(&path, "gitdir");
		strbuf_addbuf(&path, &worktree_path);
		strbuf_realpath_forgiving(&worktree_path, path.buf, 0);
	}

	CALLOC_ARRAY(worktree, 1);
	worktree->repo = the_repository;
	worktree->path = strbuf_detach(&worktree_path, NULL);
	worktree->id = xstrdup(id);
	worktree->is_current = is_current_worktree(worktree);
	if (!skip_reading_head)
		add_head_info(worktree);

done:
	strbuf_release(&path);
	strbuf_release(&worktree_path);
	return worktree;
}

/*
 * NEEDSWORK: This function exists so that we can look up metadata of a
 * worktree without trying to access any of its internals like the refdb. It
 * would be preferable to instead have a corruption-tolerant function for
 * retrieving worktree metadata that could be used when the worktree is known
 * to not be in a healthy state, e.g. when creating or repairing it.
 */
static struct worktree **get_worktrees_internal(int skip_reading_head)
{
	struct worktree **list = NULL;
	struct strbuf path = STRBUF_INIT;
	DIR *dir;
	struct dirent *d;
	int counter = 0, alloc = 2;

	ALLOC_ARRAY(list, alloc);

	list[counter++] = get_main_worktree(skip_reading_head);

	strbuf_addf(&path, "%s/worktrees", repo_get_common_dir(the_repository));
	dir = opendir(path.buf);
	strbuf_release(&path);
	if (dir) {
		while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
			struct worktree *linked = NULL;

			if ((linked = get_linked_worktree(d->d_name, skip_reading_head))) {
				ALLOC_GROW(list, counter + 1, alloc);
				list[counter++] = linked;
			}
		}
		closedir(dir);
	}
	ALLOC_GROW(list, counter + 1, alloc);
	list[counter] = NULL;

	return list;
}

struct worktree **get_worktrees(void)
{
	return get_worktrees_internal(0);
}

struct worktree **get_worktrees_without_reading_head(void)
{
	return get_worktrees_internal(1);
}

char *get_worktree_git_dir(const struct worktree *wt)
{
	if (!wt)
		BUG("%s() called with NULL worktree", __func__);
	else if (!wt->id)
		return xstrdup(repo_get_common_dir(wt->repo));
	else
		return repo_common_path(wt->repo, "worktrees/%s", wt->id);
}

static struct worktree *find_worktree_by_suffix(struct worktree **list,
						const char *suffix)
{
	struct worktree *found = NULL;
	int nr_found = 0, suffixlen;

	suffixlen = strlen(suffix);
	if (!suffixlen)
		return NULL;

	for (; *list && nr_found < 2; list++) {
		const char	*path	 = (*list)->path;
		int		 pathlen = strlen(path);
		int		 start	 = pathlen - suffixlen;

		/* suffix must start at directory boundary */
		if ((!start || (start > 0 && is_dir_sep(path[start - 1]))) &&
		    !fspathcmp(suffix, path + start)) {
			found = *list;
			nr_found++;
		}
	}
	return nr_found == 1 ? found : NULL;
}

struct worktree *find_worktree(struct worktree **list,
			       const char *prefix,
			       const char *arg)
{
	struct worktree *wt;
	char *to_free = NULL;

	if ((wt = find_worktree_by_suffix(list, arg)))
		return wt;

	if (prefix)
		arg = to_free = prefix_filename(prefix, arg);
	wt = find_worktree_by_path(list, arg);
	free(to_free);
	return wt;
}

struct worktree *find_worktree_by_path(struct worktree **list, const char *p)
{
	struct strbuf wt_path = STRBUF_INIT;
	char *path = real_pathdup(p, 0);

	if (!path)
		return NULL;
	for (; *list; list++) {
		if (!strbuf_realpath(&wt_path, (*list)->path, 0))
			continue;

		if (!fspathcmp(path, wt_path.buf))
			break;
	}
	free(path);
	strbuf_release(&wt_path);
	return *list;
}

int is_main_worktree(const struct worktree *wt)
{
	return !wt->id;
}

const char *worktree_lock_reason(struct worktree *wt)
{
	if (is_main_worktree(wt))
		return NULL;

	if (!wt->lock_reason_valid) {
		struct strbuf path = STRBUF_INIT;

		strbuf_addstr(&path, worktree_git_path(wt, "locked"));
		if (file_exists(path.buf)) {
			struct strbuf lock_reason = STRBUF_INIT;
			if (strbuf_read_file(&lock_reason, path.buf, 0) < 0)
				die_errno(_("failed to read '%s'"), path.buf);
			strbuf_trim(&lock_reason);
			wt->lock_reason = strbuf_detach(&lock_reason, NULL);
		} else
			wt->lock_reason = NULL;
		wt->lock_reason_valid = 1;
		strbuf_release(&path);
	}

	return wt->lock_reason;
}

const char *worktree_prune_reason(struct worktree *wt, timestamp_t expire)
{
	struct strbuf reason = STRBUF_INIT;
	char *path = NULL;

	if (is_main_worktree(wt))
		return NULL;
	if (wt->prune_reason_valid)
		return wt->prune_reason;

	if (should_prune_worktree(wt->id, &reason, &path, expire))
		wt->prune_reason = strbuf_detach(&reason, NULL);
	wt->prune_reason_valid = 1;

	strbuf_release(&reason);
	free(path);
	return wt->prune_reason;
}

/* convenient wrapper to deal with NULL strbuf */
__attribute__((format (printf, 2, 3)))
static void strbuf_addf_gently(struct strbuf *buf, const char *fmt, ...)
{
	va_list params;

	if (!buf)
		return;

	va_start(params, fmt);
	strbuf_vaddf(buf, fmt, params);
	va_end(params);
}

int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
		      unsigned flags)
{
	struct strbuf wt_path = STRBUF_INIT;
	struct strbuf realpath = STRBUF_INIT;
	struct strbuf buf = STRBUF_INIT;
	char *path = NULL;
	int err, ret = -1;

	strbuf_addf(&wt_path, "%s/.git", wt->path);

	if (is_main_worktree(wt)) {
		if (is_directory(wt_path.buf)) {
			ret = 0;
			goto done;
		}
		/*
		 * Main worktree using .git file to point to the
		 * repository would make it impossible to know where
		 * the actual worktree is if this function is executed
		 * from another worktree. No .git file support for now.
		 */
		strbuf_addf_gently(errmsg,
				   _("'%s' at main working tree is not the repository directory"),
				   wt_path.buf);
		goto done;
	}

	/*
	 * Make sure "gitdir" file points to a real .git file and that
	 * file points back here.
	 */
	if (!is_absolute_path(wt->path)) {
		strbuf_addf_gently(errmsg,
				   _("'%s' file does not contain absolute path to the working tree location"),
				   repo_common_path_replace(the_repository, &buf, "worktrees/%s/gitdir", wt->id));
		goto done;
	}

	if (flags & WT_VALIDATE_WORKTREE_MISSING_OK &&
	    !file_exists(wt->path)) {
		ret = 0;
		goto done;
	}

	if (!file_exists(wt_path.buf)) {
		strbuf_addf_gently(errmsg, _("'%s' does not exist"), wt_path.buf);
		goto done;
	}

	path = xstrdup_or_null(read_gitfile_gently(wt_path.buf, &err));
	if (!path) {
		strbuf_addf_gently(errmsg, _("'%s' is not a .git file, error code %d"),
				   wt_path.buf, err);
		goto done;
	}

	strbuf_realpath(&realpath, repo_common_path_replace(the_repository, &buf, "worktrees/%s", wt->id), 1);
	ret = fspathcmp(path, realpath.buf);

	if (ret)
		strbuf_addf_gently(errmsg, _("'%s' does not point back to '%s'"),
				   wt->path, repo_common_path_replace(the_repository, &buf,
								      "worktrees/%s", wt->id));
done:
	free(path);
	strbuf_release(&buf);
	strbuf_release(&wt_path);
	strbuf_release(&realpath);
	return ret;
}

void update_worktree_location(struct worktree *wt, const char *path_,
			      int use_relative_paths)
{
	struct strbuf path = STRBUF_INIT;
	struct strbuf dotgit = STRBUF_INIT;
	struct strbuf gitdir = STRBUF_INIT;
	char *wt_gitdir;

	if (is_main_worktree(wt))
		BUG("can't relocate main worktree");

	wt_gitdir = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id);
	strbuf_realpath(&gitdir, wt_gitdir, 1);
	strbuf_realpath(&path, path_, 1);
	strbuf_addf(&dotgit, "%s/.git", path.buf);
	if (fspathcmp(wt->path, path.buf)) {
		write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);

		free(wt->path);
		wt->path = strbuf_detach(&path, NULL);
	}
	strbuf_release(&path);
	strbuf_release(&dotgit);
	strbuf_release(&gitdir);
	free(wt_gitdir);
}

int is_worktree_being_rebased(const struct worktree *wt,
			      const char *target)
{
	struct wt_status_state state;
	int found_rebase;

	memset(&state, 0, sizeof(state));
	found_rebase = wt_status_check_rebase(wt, &state) &&
		       (state.rebase_in_progress ||
			state.rebase_interactive_in_progress) &&
		       state.branch &&
		       skip_prefix(target, "refs/heads/", &target) &&
		       !strcmp(state.branch, target);
	wt_status_state_free_buffers(&state);
	return found_rebase;
}

int is_worktree_being_bisected(const struct worktree *wt,
			       const char *target)
{
	struct wt_status_state state;
	int found_bisect;

	memset(&state, 0, sizeof(state));
	found_bisect = wt_status_check_bisect(wt, &state) &&
		       state.bisecting_from &&
		       skip_prefix(target, "refs/heads/", &target) &&
		       !strcmp(state.bisecting_from, target);
	wt_status_state_free_buffers(&state);
	return found_bisect;
}

/*
 * note: this function should be able to detect shared symref even if
 * HEAD is temporarily detached (e.g. in the middle of rebase or
 * bisect). New commands that do similar things should update this
 * function as well.
 */
int is_shared_symref(const struct worktree *wt, const char *symref,
		     const char *target)
{
	const char *symref_target;
	struct ref_store *refs;
	int flags;

	if (wt->is_bare)
		return 0;

	if (wt->is_detached && !strcmp(symref, "HEAD")) {
		if (is_worktree_being_rebased(wt, target))
			return 1;
		if (is_worktree_being_bisected(wt, target))
			return 1;
	}

	refs = get_worktree_ref_store(wt);
	symref_target = refs_resolve_ref_unsafe(refs, symref, 0,
						NULL, &flags);
	if ((flags & REF_ISSYMREF) &&
	    symref_target && !strcmp(symref_target, target))
		return 1;

	return 0;
}

const struct worktree *find_shared_symref(struct worktree **worktrees,
					  const char *symref,
					  const char *target)
{

	for (int i = 0; worktrees[i]; i++)
		if (is_shared_symref(worktrees[i], symref, target))
			return worktrees[i];

	return NULL;
}

int submodule_uses_worktrees(const char *path)
{
	char *submodule_gitdir;
	struct strbuf sb = STRBUF_INIT, err = STRBUF_INIT;
	DIR *dir;
	struct dirent *d;
	int ret = 0;
	struct repository_format format = REPOSITORY_FORMAT_INIT;

	submodule_gitdir = repo_submodule_path(the_repository,
					       path, "%s", "");
	if (!submodule_gitdir)
		return 0;

	/* The env would be set for the superproject. */
	get_common_dir_noenv(&sb, submodule_gitdir);
	free(submodule_gitdir);

	strbuf_addstr(&sb, "/config");
	read_repository_format(&format, sb.buf);
	if (verify_repository_format(&format, &err)) {
		strbuf_release(&err);
		strbuf_release(&sb);
		clear_repository_format(&format);
		return 1;
	}
	clear_repository_format(&format);
	strbuf_release(&err);

	/* Replace config by worktrees. */
	strbuf_setlen(&sb, sb.len - strlen("config"));
	strbuf_addstr(&sb, "worktrees");

	/* See if there is any file inside the worktrees directory. */
	dir = opendir(sb.buf);
	strbuf_release(&sb);

	if (!dir)
		return 0;

	d = readdir_skip_dot_and_dotdot(dir);
	if (d)
		ret = 1;
	closedir(dir);
	return ret;
}

void strbuf_worktree_ref(const struct worktree *wt,
			 struct strbuf *sb,
			 const char *refname)
{
	if (parse_worktree_ref(refname, NULL, NULL, NULL) ==
		    REF_WORKTREE_CURRENT &&
	    wt && !wt->is_current) {
		if (is_main_worktree(wt))
			strbuf_addstr(sb, "main-worktree/");
		else
			strbuf_addf(sb, "worktrees/%s/", wt->id);
	}
	strbuf_addstr(sb, refname);
}

int other_head_refs(refs_for_each_cb fn, void *cb_data)
{
	struct worktree **worktrees, **p;
	struct strbuf refname = STRBUF_INIT;
	int ret = 0;

	worktrees = get_worktrees();
	for (p = worktrees; *p; p++) {
		struct worktree *wt = *p;
		struct object_id oid;
		int flag;

		if (wt->is_current)
			continue;

		strbuf_reset(&refname);
		strbuf_worktree_ref(wt, &refname, "HEAD");
		if (refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
					    refname.buf,
					    RESOLVE_REF_READING,
					    &oid, &flag)) {
			struct reference ref = {
				.name = refname.buf,
				.oid = &oid,
				.flags = flag,
			};

			ret = fn(&ref, cb_data);
		}
		if (ret)
			break;
	}
	free_worktrees(worktrees);
	strbuf_release(&refname);
	return ret;
}

/*
 * Repair worktree's /path/to/worktree/.git file if missing, corrupt, or not
 * pointing at <repo>/worktrees/<id>.
 */
static void repair_gitfile(struct worktree *wt,
			   worktree_repair_fn fn, void *cb_data,
			   int use_relative_paths)
{
	struct strbuf dotgit = STRBUF_INIT;
	struct strbuf gitdir = STRBUF_INIT;
	struct strbuf repo = STRBUF_INIT;
	struct strbuf backlink = STRBUF_INIT;
	char *dotgit_contents = NULL;
	const char *repair = NULL;
	char *path = NULL;
	int err;

	/* missing worktree can't be repaired */
	if (!file_exists(wt->path))
		goto done;

	if (!is_directory(wt->path)) {
		fn(1, wt->path, _("not a directory"), cb_data);
		goto done;
	}

	path = repo_common_path(the_repository, "worktrees/%s", wt->id);
	strbuf_realpath(&repo, path, 1);
	strbuf_addf(&dotgit, "%s/.git", wt->path);
	strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
	dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));

	if (dotgit_contents) {
		if (is_absolute_path(dotgit_contents)) {
			strbuf_addstr(&backlink, dotgit_contents);
		} else {
			strbuf_addf(&backlink, "%s/%s", wt->path, dotgit_contents);
			strbuf_realpath_forgiving(&backlink, backlink.buf, 0);
		}
	}

	if (err == READ_GITFILE_ERR_NOT_A_FILE ||
		err == READ_GITFILE_ERR_IS_A_DIR)
		fn(1, wt->path, _(".git is not a file"), cb_data);
	else if (err)
		repair = _(".git file broken");
	else if (fspathcmp(backlink.buf, repo.buf))
		repair = _(".git file incorrect");
	else if (use_relative_paths == is_absolute_path(dotgit_contents))
		repair = _(".git file absolute/relative path mismatch");

	if (repair) {
		fn(0, wt->path, repair, cb_data);
		write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
	}

done:
	free(dotgit_contents);
	free(path);
	strbuf_release(&repo);
	strbuf_release(&dotgit);
	strbuf_release(&gitdir);
	strbuf_release(&backlink);
}

static void repair_noop(int iserr UNUSED,
			const char *path UNUSED,
			const char *msg UNUSED,
			void *cb_data UNUSED)
{
	/* nothing */
}

void repair_worktrees(worktree_repair_fn fn, void *cb_data, int use_relative_paths)
{
	struct worktree **worktrees = get_worktrees_internal(1);
	struct worktree **wt = worktrees + 1; /* +1 skips main worktree */

	if (!fn)
		fn = repair_noop;
	for (; *wt; wt++)
		repair_gitfile(*wt, fn, cb_data, use_relative_paths);
	free_worktrees(worktrees);
}

void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path)
{
	struct strbuf gitdir = STRBUF_INIT;
	struct strbuf dotgit = STRBUF_INIT;
	int is_relative_path;
	char *path = NULL;

	if (is_main_worktree(wt))
		goto done;

	path = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id);
	strbuf_realpath(&gitdir, path, 1);

	if (strbuf_read_file(&dotgit, gitdir.buf, 0) < 0)
		goto done;

	strbuf_rtrim(&dotgit);
	is_relative_path = ! is_absolute_path(dotgit.buf);
	if (is_relative_path) {
		strbuf_insertf(&dotgit, 0, "%s/worktrees/%s/", old_path, wt->id);
		strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0);
	}

	if (!file_exists(dotgit.buf))
		goto done;

	write_worktree_linking_files(dotgit.buf, gitdir.buf, is_relative_path);
done:
	strbuf_release(&gitdir);
	strbuf_release(&dotgit);
	free(path);
}

void repair_worktrees_after_gitdir_move(const char *old_path)
{
	struct worktree **worktrees = get_worktrees_internal(1);
	struct worktree **wt = worktrees + 1; /* +1 skips main worktree */

	for (; *wt; wt++)
		repair_worktree_after_gitdir_move(*wt, old_path);
	free_worktrees(worktrees);
}

static int is_main_worktree_path(const char *path)
{
	struct strbuf target = STRBUF_INIT;
	struct strbuf maindir = STRBUF_INIT;
	int cmp;

	strbuf_add_real_path(&target, path);
	strbuf_strip_suffix(&target, "/.git");
	strbuf_add_real_path(&maindir, repo_get_common_dir(the_repository));
	strbuf_strip_suffix(&maindir, "/.git");
	cmp = fspathcmp(maindir.buf, target.buf);

	strbuf_release(&maindir);
	strbuf_release(&target);
	return !cmp;
}

/*
 * If both the main worktree and linked worktree have been moved, then the
 * gitfile /path/to/worktree/.git won't point into the repository, thus we
 * won't know which <repo>/worktrees/<id>/gitdir to repair. However, we may
 * be able to infer the gitdir by manually reading /path/to/worktree/.git,
 * extracting the <id>, and checking if <repo>/worktrees/<id> exists.
 *
 * Returns -1 on failure and strbuf.len on success.
 */
static ssize_t infer_backlink(const char *gitfile, struct strbuf *inferred)
{
	struct strbuf actual = STRBUF_INIT;
	const char *id;

	if (strbuf_read_file(&actual, gitfile, 0) < 0)
		goto error;
	if (!starts_with(actual.buf, "gitdir:"))
		goto error;
	if (!(id = find_last_dir_sep(actual.buf)))
		goto error;
	strbuf_trim(&actual);
	id++; /* advance past '/' to point at <id> */
	if (!*id)
		goto error;
	repo_common_path_replace(the_repository, inferred, "worktrees/%s", id);
	if (!is_directory(inferred->buf))
		goto error;

	strbuf_release(&actual);
	return inferred->len;
error:
	strbuf_release(&actual);
	strbuf_reset(inferred); /* clear invalid path */
	return -1;
}

/*
 * Repair <repo>/worktrees/<id>/gitdir if missing, corrupt, or not pointing at
 * the worktree's path.
 */
void repair_worktree_at_path(const char *path,
			     worktree_repair_fn fn, void *cb_data,
			     int use_relative_paths)
{
	struct strbuf dotgit = STRBUF_INIT;
	struct strbuf backlink = STRBUF_INIT;
	struct strbuf inferred_backlink = STRBUF_INIT;
	struct strbuf gitdir = STRBUF_INIT;
	struct strbuf olddotgit = STRBUF_INIT;
	char *dotgit_contents = NULL;
	const char *repair = NULL;
	int err;

	if (!fn)
		fn = repair_noop;

	if (is_main_worktree_path(path))
		goto done;

	strbuf_addf(&dotgit, "%s/.git", path);
	if (!strbuf_realpath(&dotgit, dotgit.buf, 0)) {
		fn(1, path, _("not a valid path"), cb_data);
		goto done;
	}

	infer_backlink(dotgit.buf, &inferred_backlink);
	strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0);
	dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
	if (dotgit_contents) {
		if (is_absolute_path(dotgit_contents)) {
			strbuf_addstr(&backlink, dotgit_contents);
		} else {
			strbuf_addbuf(&backlink, &dotgit);
			strbuf_strip_suffix(&backlink, ".git");
			strbuf_addstr(&backlink, dotgit_contents);
			strbuf_realpath_forgiving(&backlink, backlink.buf, 0);
		}
	} else if (err == READ_GITFILE_ERR_NOT_A_FILE ||
			err == READ_GITFILE_ERR_IS_A_DIR) {
		fn(1, dotgit.buf, _("unable to locate repository; .git is not a file"), cb_data);
		goto done;
	} else if (err == READ_GITFILE_ERR_NOT_A_REPO) {
		if (inferred_backlink.len) {
			/*
			 * Worktree's .git file does not point at a repository
			 * but we found a .git/worktrees/<id> in this
			 * repository with the same <id> as recorded in the
			 * worktree's .git file so make the worktree point at
			 * the discovered .git/worktrees/<id>.
			 */
			strbuf_swap(&backlink, &inferred_backlink);
		} else {
			fn(1, dotgit.buf, _("unable to locate repository; .git file does not reference a repository"), cb_data);
			goto done;
		}
	} else {
		fn(1, dotgit.buf, _("unable to locate repository; .git file broken"), cb_data);
		goto done;
	}

	/*
	 * If we got this far, either the worktree's .git file pointed at a
	 * valid repository (i.e. read_gitfile_gently() returned success) or
	 * the .git file did not point at a repository but we were able to
	 * infer a suitable new value for the .git file by locating a
	 * .git/worktrees/<id> in *this* repository corresponding to the <id>
	 * recorded in the worktree's .git file.
	 *
	 * However, if, at this point, inferred_backlink is non-NULL (i.e. we
	 * found a suitable .git/worktrees/<id> in *this* repository) *and* the
	 * worktree's .git file points at a valid repository *and* those two
	 * paths differ, then that indicates that the user probably *copied*
	 * the main and linked worktrees to a new location as a unit rather
	 * than *moving* them. Thus, the copied worktree's .git file actually
	 * points at the .git/worktrees/<id> in the *original* repository, not
	 * in the "copy" repository. In this case, point the "copy" worktree's
	 * .git file at the "copy" repository.
	 */
	if (inferred_backlink.len && fspathcmp(backlink.buf, inferred_backlink.buf))
		strbuf_swap(&backlink, &inferred_backlink);

	strbuf_addf(&gitdir, "%s/gitdir", backlink.buf);
	if (strbuf_read_file(&olddotgit, gitdir.buf, 0) < 0)
		repair = _("gitdir unreadable");
	else if (use_relative_paths == is_absolute_path(olddotgit.buf))
		repair = _("gitdir absolute/relative path mismatch");
	else {
		strbuf_rtrim(&olddotgit);
		if (!is_absolute_path(olddotgit.buf)) {
			strbuf_insertf(&olddotgit, 0, "%s/", backlink.buf);
			strbuf_realpath_forgiving(&olddotgit, olddotgit.buf, 0);
		}
		if (fspathcmp(olddotgit.buf, dotgit.buf))
			repair = _("gitdir incorrect");
	}

	if (repair) {
		fn(0, gitdir.buf, repair, cb_data);
		write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths);
	}
done:
	free(dotgit_contents);
	strbuf_release(&olddotgit);
	strbuf_release(&backlink);
	strbuf_release(&inferred_backlink);
	strbuf_release(&gitdir);
	strbuf_release(&dotgit);
}

int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire)
{
	struct stat st;
	struct strbuf dotgit = STRBUF_INIT;
	struct strbuf gitdir = STRBUF_INIT;
	struct strbuf repo = STRBUF_INIT;
	struct strbuf file = STRBUF_INIT;
	char *path = NULL;
	int rc = 0;
	int fd;
	size_t len;
	ssize_t read_result;

	*wtpath = NULL;

	path = repo_common_path(the_repository, "worktrees/%s", id);
	strbuf_realpath(&repo, path, 1);
	FREE_AND_NULL(path);

	strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
	if (!is_directory(repo.buf)) {
		strbuf_addstr(reason, _("not a valid directory"));
		rc = 1;
		goto done;
	}
	strbuf_addf(&file, "%s/locked", repo.buf);
	if (file_exists(file.buf)) {
		goto done;
	}
	if (stat(gitdir.buf, &st)) {
		strbuf_addstr(reason, _("gitdir file does not exist"));
		rc = 1;
		goto done;
	}
	fd = open(gitdir.buf, O_RDONLY);
	if (fd < 0) {
		strbuf_addf(reason, _("unable to read gitdir file (%s)"),
			    strerror(errno));
		rc = 1;
		goto done;
	}
	len = xsize_t(st.st_size);
	path = xmallocz(len);

	read_result = read_in_full(fd, path, len);
	close(fd);
	if (read_result < 0) {
		strbuf_addf(reason, _("unable to read gitdir file (%s)"),
			    strerror(errno));
		rc = 1;
		goto done;
	} else if (read_result != len) {
		strbuf_addf(reason,
			    _("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
			    (uintmax_t)len, (uintmax_t)read_result);
		rc = 1;
		goto done;
	}
	while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
		len--;
	if (!len) {
		strbuf_addstr(reason, _("invalid gitdir file"));
		rc = 1;
		goto done;
	}
	path[len] = '\0';
	if (is_absolute_path(path)) {
		strbuf_addstr(&dotgit, path);
	} else {
		strbuf_addf(&dotgit, "%s/%s", repo.buf, path);
		strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0);
	}
	if (!file_exists(dotgit.buf)) {
		strbuf_reset(&file);
		strbuf_addf(&file, "%s/index", repo.buf);
		if (stat(file.buf, &st) || st.st_mtime <= expire) {
			strbuf_addstr(reason, _("gitdir file points to non-existent location"));
			rc = 1;
			goto done;
		}
	}
	*wtpath = strbuf_detach(&dotgit, NULL);
done:
	free(path);
	strbuf_release(&dotgit);
	strbuf_release(&gitdir);
	strbuf_release(&repo);
	strbuf_release(&file);
	return rc;
}

static int move_config_setting(const char *key, const char *value,
			       const char *from_file, const char *to_file)
{
	if (repo_config_set_in_file_gently(the_repository, to_file, key, NULL, value))
		return error(_("unable to set %s in '%s'"), key, to_file);
	if (repo_config_set_in_file_gently(the_repository, from_file, key, NULL, NULL))
		return error(_("unable to unset %s in '%s'"), key, from_file);
	return 0;
}

int init_worktree_config(struct repository *r)
{
	int res = 0;
	int bare = 0;
	struct config_set cs = { { 0 } };
	const char *core_worktree;
	char *common_config_file;
	char *main_worktree_file;

	/*
	 * If the extension is already enabled, then we can skip the
	 * upgrade process.
	 */
	if (r->repository_format_worktree_config)
		return 0;
	if ((res = repo_config_set_gently(the_repository, "extensions.worktreeConfig", "true")))
		return error(_("failed to set extensions.worktreeConfig setting"));

	common_config_file = xstrfmt("%s/config", r->commondir);
	main_worktree_file = xstrfmt("%s/config.worktree", r->commondir);

	git_configset_init(&cs);
	git_configset_add_file(&cs, common_config_file);

	/*
	 * If core.bare is true in the common config file, then we need to
	 * move it to the main worktree's config file or it will break all
	 * worktrees. If it is false, then leave it in place because it
	 * _could_ be negating a global core.bare=true.
	 */
	if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare) {
		if ((res = move_config_setting("core.bare", "true",
					       common_config_file,
					       main_worktree_file)))
			goto cleanup;
	}
	/*
	 * If core.worktree is set, then the main worktree is located
	 * somewhere different than the parent of the common Git dir.
	 * Relocate that value to avoid breaking all worktrees with this
	 * upgrade to worktree config.
	 */
	if (!git_configset_get_value(&cs, "core.worktree", &core_worktree, NULL)) {
		if ((res = move_config_setting("core.worktree", core_worktree,
					       common_config_file,
					       main_worktree_file)))
			goto cleanup;
	}

	/*
	 * Ensure that we use worktree config for the remaining lifetime
	 * of the current process.
	 */
	r->repository_format_worktree_config = 1;

cleanup:
	git_configset_clear(&cs);
	free(common_config_file);
	free(main_worktree_file);
	return res;
}

void write_worktree_linking_files(const char *dotgit, const char *gitdir,
				  int use_relative_paths)
{
	struct strbuf path = STRBUF_INIT;
	struct strbuf repo = STRBUF_INIT;
	struct strbuf tmp = STRBUF_INIT;

	strbuf_addstr(&path, dotgit);
	strbuf_strip_suffix(&path, "/.git");
	strbuf_realpath(&path, path.buf, 1);
	strbuf_addstr(&repo, gitdir);
	strbuf_strip_suffix(&repo, "/gitdir");
	strbuf_realpath(&repo, repo.buf, 1);

	if (use_relative_paths && !the_repository->repository_format_relative_worktrees) {
		if (upgrade_repository_format(the_repository, 1) < 0)
			die(_("unable to upgrade repository format to support relative worktrees"));
		if (repo_config_set_gently(the_repository, "extensions.relativeWorktrees", "true"))
			die(_("unable to set extensions.relativeWorktrees setting"));
		the_repository->repository_format_relative_worktrees = 1;
	}

	if (use_relative_paths) {
		write_file(gitdir, "%s/.git", relative_path(path.buf, repo.buf, &tmp));
		write_file(dotgit, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
	} else {
		write_file(gitdir, "%s/.git", path.buf);
		write_file(dotgit, "gitdir: %s", repo.buf);
	}

	strbuf_release(&path);
	strbuf_release(&repo);
	strbuf_release(&tmp);
}
