From 3e4b0c192a5bfb7a1eb2d9ad4e2c472296c556a0 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Fri, 18 Oct 2024 18:31:49 +1100 Subject: [PATCH] workspace: add stopgap test helper to create a colocated workspace A colocated workspace is one that also happens to have a valid .git file or directory. Currently, only the default workspace can be colocated, but we also want secondary workspaces to have this ability. To create a *secondary* colocated workspace in an existing JJ repo, we need to add a corresponding git _worktree_. JJ doesn't have the ability to create git worktrees yet. We want to test a bunch of code around colocating worktrees with a workspace, assuming we will build the functionality to actually create one in JJ itself later. So here's a helper function to do it the really hacky way with the `git` CLI, moving a .git file into place, and running `git worktree repair`. --- cli/tests/test_git_colocated.rs | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/cli/tests/test_git_colocated.rs b/cli/tests/test_git_colocated.rs index acac054a4..e3b607c49 100644 --- a/cli/tests/test_git_colocated.rs +++ b/cli/tests/test_git_colocated.rs @@ -13,7 +13,9 @@ // limitations under the License. use std::path::Path; +use std::process::Command; +use assert_cmd::assert::OutputAssertExt; use git2::Oid; use crate::common::TestEnvironment; @@ -921,3 +923,55 @@ fn test_git_colocated_create_workspace_moving_wc() { ◆ 0000000000000000000000000000000000000000 "); } + +/// Substitute for `jj workspace add --colocate` or similar using git CLI, +/// please replace with the real thing when it lands. +fn stopgap_workspace_colocate( + test_env: &TestEnvironment, + repo_path: &Path, + original_colocated: bool, + dst: &str, + initial_head: &str, +) { + // Can't use gix/git2, as neither can repair the broken worktree we're about to + // create. + let repo_relative_path = if original_colocated { + dst.to_owned() + } else { + format!("../../../../{dst}") + }; + Command::new("git") + .args(["worktree", "add", &repo_relative_path]) + .arg(initial_head) + .current_dir(if original_colocated { + repo_path.to_path_buf() + } else { + repo_path.join(".jj/repo/store/git") + }) + .assert() + .success() + .stderr(format!( + "Preparing worktree (detached HEAD {})\n", + &initial_head[..7] + )); + let dst_path = repo_path.join(dst); + let tmp_path = test_env.env_root().join("__tmp_worktree__"); + if tmp_path.exists() { + std::fs::remove_dir_all(&tmp_path).unwrap(); + } + std::fs::rename(&dst_path, &tmp_path).unwrap(); + test_env.jj_cmd_ok(repo_path, &["workspace", "add", dst]); + std::fs::rename(tmp_path.join(".git"), dst_path.join(".git")).unwrap(); + std::fs::write(dst_path.join(".jj/.gitignore"), "*\n").unwrap(); + Command::new("git") + .args(["worktree", "repair"]) + .current_dir(&dst_path) + .assert() + .success(); + Command::new("git") + .arg("checkout") + .arg(initial_head) + .current_dir(&dst_path) + .assert() + .success(); +}