workspace: store repo in .jj/repo/ (#13)

The `.jj/` directory contains information about two distinct parts:
the repo and the working copy. Most subdirectories are related to the
repo; only `.jj/working_copy/` is about the working copy. Let's move
the repo-related bits into a new `.jj/repo/` subdirectory. That makes
it clearer that they're related to the repo. It will probably also be
easier to manage when we have support for multiple workspaces backed
by a single repo.
This commit is contained in:
Martin von Zweigbergk 2022-01-28 20:26:16 -08:00
parent 51c351f272
commit ca055d91d9
3 changed files with 65 additions and 36 deletions

View file

@ -75,7 +75,9 @@ impl Workspace {
workspace_root: PathBuf,
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
let jj_dir = create_jj_dir(&workspace_root)?;
let repo = ReadonlyRepo::init_local(user_settings, jj_dir.clone());
let repo_dir = jj_dir.join("repo");
std::fs::create_dir(&repo_dir).unwrap();
let repo = ReadonlyRepo::init_local(user_settings, repo_dir);
let working_copy = init_working_copy(&repo, &workspace_root, &jj_dir);
let repo_loader = repo.loader();
let workspace = Workspace {
@ -91,7 +93,9 @@ impl Workspace {
workspace_root: PathBuf,
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
let jj_dir = create_jj_dir(&workspace_root)?;
let repo = ReadonlyRepo::init_internal_git(user_settings, jj_dir.clone());
let repo_dir = jj_dir.join("repo");
std::fs::create_dir(&repo_dir).unwrap();
let repo = ReadonlyRepo::init_internal_git(user_settings, repo_dir);
let working_copy = init_working_copy(&repo, &workspace_root, &jj_dir);
let repo_loader = repo.loader();
let workspace = Workspace {
@ -108,7 +112,9 @@ impl Workspace {
git_repo_path: PathBuf,
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
let jj_dir = create_jj_dir(&workspace_root)?;
let repo = ReadonlyRepo::init_external_git(user_settings, jj_dir.clone(), git_repo_path);
let repo_dir = jj_dir.join("repo");
std::fs::create_dir(&repo_dir).unwrap();
let repo = ReadonlyRepo::init_external_git(user_settings, repo_dir, git_repo_path);
let working_copy = init_working_copy(&repo, &workspace_root, &jj_dir);
let repo_loader = repo.loader();
let workspace = Workspace {
@ -126,8 +132,17 @@ impl Workspace {
let jj_dir = find_jj_dir(&workspace_path)
.ok_or(WorkspaceLoadError::NoWorkspaceHere(workspace_path))?;
let workspace_root = jj_dir.parent().unwrap().to_owned();
let repo_loader = RepoLoader::init(user_settings, jj_dir);
let working_copy_state_path = repo_loader.repo_path().join("working_copy");
let repo_dir = jj_dir.join("repo");
if !repo_dir.exists() {
// TODO: Delete this in mid 2022 or so
println!("The repo format has changed. Moving repo into .jj/repo/");
std::fs::create_dir(&repo_dir).unwrap();
for dir in ["store", "op_store", "op_heads", "index"] {
std::fs::rename(jj_dir.join(dir), repo_dir.join(dir)).unwrap();
}
}
let repo_loader = RepoLoader::init(user_settings, repo_dir);
let working_copy_state_path = jj_dir.join("working_copy");
let working_copy = WorkingCopy::load(
repo_loader.store().clone(),
workspace_root.clone(),

View file

@ -24,7 +24,7 @@ fn test_init_local() {
let wc_path = temp_dir.path().to_owned();
let (workspace, repo) = Workspace::init_local(&settings, wc_path.clone()).unwrap();
assert!(repo.store().git_repo().is_none());
assert_eq!(repo.repo_path(), &wc_path.join(".jj"));
assert_eq!(repo.repo_path(), &wc_path.join(".jj").join("repo"));
assert_eq!(workspace.workspace_root(), &wc_path);
// Just test that we can write a commit to the store
@ -39,7 +39,7 @@ fn test_init_internal_git() {
let wc_path = temp_dir.path().to_owned();
let (workspace, repo) = Workspace::init_internal_git(&settings, wc_path.clone()).unwrap();
assert!(repo.store().git_repo().is_some());
assert_eq!(repo.repo_path(), &wc_path.join(".jj"));
assert_eq!(repo.repo_path(), &wc_path.join(".jj").join("repo"));
assert_eq!(workspace.workspace_root(), &wc_path);
// Just test that we ca write a commit to the store
@ -58,7 +58,7 @@ fn test_init_external_git() {
let (workspace, repo) =
Workspace::init_external_git(&settings, wc_path.clone(), git_repo_path).unwrap();
assert!(repo.store().git_repo().is_some());
assert_eq!(repo.repo_path(), &wc_path.join(".jj"));
assert_eq!(repo.repo_path(), &wc_path.join(".jj").join("repo"));
assert_eq!(workspace.workspace_root(), &wc_path);
// Just test that we can write a commit to the store

View file

@ -20,22 +20,25 @@ fn test_init_git_internal() {
let output = testutils::CommandRunner::new(temp_dir.path()).run(vec!["init", "repo", "--git"]);
assert_eq!(output.status, 0);
let repo_path = temp_dir.path().join("repo");
let workspace_root = temp_dir.path().join("repo");
let jj_path = workspace_root.join(".jj");
let repo_path = jj_path.join("repo");
let store_path = repo_path.join("store");
assert!(workspace_root.is_dir());
assert!(jj_path.is_dir());
assert!(jj_path.join("working_copy").is_dir());
assert!(repo_path.is_dir());
assert!(repo_path.join(".jj").is_dir());
assert!(repo_path.join(".jj").join("store").is_dir());
assert!(repo_path.join(".jj").join("store").join("git").is_dir());
assert!(repo_path
.join(".jj")
.join("store")
.join("git_target")
.is_file());
let git_target_file_contents =
std::fs::read_to_string(repo_path.join(".jj").join("store").join("git_target")).unwrap();
assert!(store_path.is_dir());
assert!(store_path.join("git").is_dir());
assert!(store_path.join("git_target").is_file());
let git_target_file_contents = std::fs::read_to_string(store_path.join("git_target")).unwrap();
assert_eq!(git_target_file_contents, "git");
assert_eq!(
output.stdout_string(),
format!("Initialized repo in \"{}\"\n", repo_path.to_str().unwrap())
format!(
"Initialized repo in \"{}\"\n",
workspace_root.to_str().unwrap()
)
);
}
@ -53,18 +56,22 @@ fn test_init_git_external() {
]);
assert_eq!(output.status, 0);
let repo_path = temp_dir.path().join("repo");
let workspace_root = temp_dir.path().join("repo");
let jj_path = workspace_root.join(".jj");
let repo_path = jj_path.join("repo");
let store_path = repo_path.join("store");
assert!(workspace_root.is_dir());
assert!(jj_path.is_dir());
assert!(jj_path.join("working_copy").is_dir());
assert!(repo_path.is_dir());
assert!(repo_path.join(".jj").is_dir());
assert!(repo_path.join(".jj").join("store").is_dir());
let git_target_file_contents =
std::fs::read_to_string(repo_path.join(".jj").join("store").join("git_target")).unwrap();
assert!(store_path.is_dir());
let git_target_file_contents = std::fs::read_to_string(store_path.join("git_target")).unwrap();
assert!(git_target_file_contents
.replace('\\', "/")
.ends_with("/git-repo"));
assert_eq!(
output.stdout_string(),
format!("Initialized repo in \"{}\"\n", repo_path.display())
format!("Initialized repo in \"{}\"\n", workspace_root.display())
);
}
@ -75,18 +82,25 @@ fn test_init_local() {
let output = testutils::CommandRunner::new(temp_dir.path()).run(vec!["init", "repo"]);
assert_eq!(output.status, 0);
let repo_path = temp_dir.path().join("repo");
let workspace_root = temp_dir.path().join("repo");
let jj_path = workspace_root.join(".jj");
let repo_path = jj_path.join("repo");
let store_path = repo_path.join("store");
assert!(workspace_root.is_dir());
assert!(jj_path.is_dir());
assert!(jj_path.join("working_copy").is_dir());
assert!(repo_path.is_dir());
assert!(repo_path.join(".jj").is_dir());
let store_dir = repo_path.join(".jj").join("store");
assert!(store_dir.is_dir());
assert!(store_dir.join("commits").is_dir());
assert!(store_dir.join("trees").is_dir());
assert!(store_dir.join("files").is_dir());
assert!(store_dir.join("symlinks").is_dir());
assert!(store_dir.join("conflicts").is_dir());
assert!(store_path.is_dir());
assert!(store_path.join("commits").is_dir());
assert!(store_path.join("trees").is_dir());
assert!(store_path.join("files").is_dir());
assert!(store_path.join("symlinks").is_dir());
assert!(store_path.join("conflicts").is_dir());
assert_eq!(
output.stdout_string(),
format!("Initialized repo in \"{}\"\n", repo_path.to_str().unwrap())
format!(
"Initialized repo in \"{}\"\n",
workspace_root.to_str().unwrap()
)
);
}