From 820fd706a24be7a58554a27e411e120cfa28d9a6 Mon Sep 17 00:00:00 2001 From: m0wer Date: Sun, 29 Mar 2026 16:45:52 +0200 Subject: feat: git worktree support Git worktrees don't have a .git directory with a parent, so we need to look for the git dir via git2's Repository::discover() and then look for the cache database there. This allows the client to work correctly when run from a worktree, and also allows the cache database to be shared between the main repo and its worktrees (since they share the same git dir and thus the same cache path). --- test_utils/src/git.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'test_utils/src/git.rs') diff --git a/test_utils/src/git.rs b/test_utils/src/git.rs index a18f81c..2668b3f 100644 --- a/test_utils/src/git.rs +++ b/test_utils/src/git.rs @@ -276,6 +276,49 @@ impl GitTestRepo { Ok(()) } + /// Creates a git worktree linked to this repository. + /// Returns a `GitTestRepo` whose `dir` points to the worktree working + /// directory. + pub fn create_worktree(&self, branch_name: &str) -> Result { + let worktree_path = self + .dir + .parent() + .unwrap() + .join(format!("tmpgit-worktree-{}", rand::random::())); + + // Create the branch at the current HEAD + let head_commit = self.git_repo.head()?.peel_to_commit()?; + self.git_repo + .branch(branch_name, &head_commit, false) + .context("failed to create branch for worktree")?; + + // Add worktree via git2 + let worktree = self + .git_repo + .worktree( + branch_name, + &worktree_path, + Some( + git2::WorktreeAddOptions::new().reference(Some( + &self + .git_repo + .find_branch(branch_name, git2::BranchType::Local)? + .into_reference(), + )), + ), + ) + .context("failed to create worktree")?; + + let worktree_repo = git2::Repository::open_from_worktree(&worktree) + .context("failed to open repo from worktree")?; + + Ok(GitTestRepo { + dir: worktree_path, + git_repo: worktree_repo, + delete_dir_on_drop: true, + }) + } + pub fn checkout_remote_branch(&self, branch_name: &str) -> Result { self.checkout(&format!("remotes/origin/{branch_name}"))?; let mut branch = self.create_branch(branch_name)?; -- cgit v1.2.3