#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 = (is_bare_repository_cfg == 1) ||
		is_bare_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);
}
