]> git.ipfire.org Git - thirdparty/git.git/commitdiff
worktree: add `write_worktree_linking_files()` function
authorCaleb White <cdwhite3@pm.me>
Fri, 29 Nov 2024 22:22:47 +0000 (22:22 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 2 Dec 2024 00:36:17 +0000 (09:36 +0900)
A new helper function, `write_worktree_linking_files()`, centralizes
the logic for computing and writing either relative or absolute
paths, based on the provided configuration. This function accepts
`strbuf` pointers to both the worktree’s `.git` link and the
repository’s `gitdir`, and then writes the appropriate path to each.
The `relativeWorktrees` extension is automatically set when a worktree
is linked with relative paths.

Signed-off-by: Caleb White <cdwhite3@pm.me>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
worktree.c
worktree.h

index afde5394c8760c328f12aa321be3ac5c199cc0f1..cf05045cc973f121a0a76b5ccfa731acf25d1a73 100644 (file)
@@ -1032,3 +1032,38 @@ cleanup:
        free(main_worktree_file);
        return res;
 }
+
+void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir,
+                                 int use_relative_paths)
+{
+       struct strbuf path = STRBUF_INIT;
+       struct strbuf repo = STRBUF_INIT;
+       struct strbuf tmp = STRBUF_INIT;
+
+       strbuf_addbuf(&path, &dotgit);
+       strbuf_strip_suffix(&path, "/.git");
+       strbuf_realpath(&path, path.buf, 1);
+       strbuf_addbuf(&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(1) < 0)
+                       die(_("unable to upgrade repository format to support relative worktrees"));
+               if (git_config_set_gently("extensions.relativeWorktrees", "true"))
+                       die(_("unable to set extensions.relativeWorktrees setting"));
+               the_repository->repository_format_relative_worktrees = 1;
+       }
+
+       if (use_relative_paths) {
+               write_file(gitdir.buf, "%s/.git", relative_path(path.buf, repo.buf, &tmp));
+               write_file(dotgit.buf, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
+       } else {
+               write_file(gitdir.buf, "%s/.git", path.buf);
+               write_file(dotgit.buf, "gitdir: %s", repo.buf);
+       }
+
+       strbuf_release(&path);
+       strbuf_release(&repo);
+       strbuf_release(&tmp);
+}
index e96118621638667d87c5d7e0452ed10bd1ddf606..fd040f5d999697b603df929679bdddd2ff7f6eea 100644 (file)
@@ -215,4 +215,17 @@ void strbuf_worktree_ref(const struct worktree *wt,
  */
 int init_worktree_config(struct repository *r);
 
+/**
+ * Write the .git file and gitdir file that links the worktree to the repository.
+ *
+ * The `dotgit` parameter is the path to the worktree's .git file, and `gitdir`
+ * is the path to the repository's `gitdir` file.
+ *
+ * Example
+ *  dotgit: "/path/to/foo/.git"
+ *  gitdir: "/path/to/repo/worktrees/foo/gitdir"
+ */
+void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir,
+                                 int use_relative_paths);
+
 #endif