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`.
This commit is contained in:
Cormac Relf 2024-10-18 18:31:49 +11:00
parent 64adf64bc2
commit 3e4b0c192a

View file

@ -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();
}