Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'worktree.c')
-rw-r--r--worktree.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/worktree.c b/worktree.c
index 62217b4a6b..3ad93cc4aa 100644
--- a/worktree.c
+++ b/worktree.c
@@ -571,3 +571,64 @@ int other_head_refs(each_ref_fn fn, void *cb_data)
free_worktrees(worktrees);
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)
+{
+ struct strbuf dotgit = STRBUF_INIT;
+ struct strbuf repo = STRBUF_INIT;
+ char *backlink;
+ const char *repair = NULL;
+ int err;
+
+ /* missing worktree can't be repaired */
+ if (!file_exists(wt->path))
+ return;
+
+ if (!is_directory(wt->path)) {
+ fn(1, wt->path, _("not a directory"), cb_data);
+ return;
+ }
+
+ strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1);
+ strbuf_addf(&dotgit, "%s/.git", wt->path);
+ backlink = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
+
+ if (err == READ_GITFILE_ERR_NOT_A_FILE)
+ fn(1, wt->path, _(".git is not a file"), cb_data);
+ else if (err)
+ repair = _(".git file broken");
+ else if (fspathcmp(backlink, repo.buf))
+ repair = _(".git file incorrect");
+
+ if (repair) {
+ fn(0, wt->path, repair, cb_data);
+ write_file(dotgit.buf, "gitdir: %s", repo.buf);
+ }
+
+ free(backlink);
+ strbuf_release(&repo);
+ strbuf_release(&dotgit);
+}
+
+static void repair_noop(int iserr, const char *path, const char *msg,
+ void *cb_data)
+{
+ /* nothing */
+}
+
+void repair_worktrees(worktree_repair_fn fn, void *cb_data)
+{
+ struct worktree **worktrees = get_worktrees();
+ struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
+
+ if (!fn)
+ fn = repair_noop;
+ for (; *wt; wt++)
+ repair_gitfile(*wt, fn, cb_data);
+ free_worktrees(worktrees);
+}