From c09a4e15c5018946af8fd4568ea31c72c625f84e Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Sun, 30 Jan 2022 11:58:05 -0800 Subject: [PATCH] workspace: add a function for initializing additional workspace (#13) --- lib/src/working_copy.rs | 2 ++ lib/src/workspace.rs | 56 +++++++++++++++++++++++++++++++------ lib/tests/test_workspace.rs | 37 ++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/lib/src/working_copy.rs b/lib/src/working_copy.rs index 4734446f7..b9e17d3c2 100644 --- a/lib/src/working_copy.rs +++ b/lib/src/working_copy.rs @@ -739,6 +739,8 @@ impl WorkingCopy { commit_id: CommitId, ) -> WorkingCopy { let mut proto = crate::protos::working_copy::Checkout::new(); + proto.operation_id = operation_id.to_bytes(); + proto.workspace_id = workspace_id.as_str().to_string(); proto.commit_id = commit_id.to_bytes(); let mut file = OpenOptions::new() .create_new(true) diff --git a/lib/src/workspace.rs b/lib/src/workspace.rs index 7b275550a..cefe2904d 100644 --- a/lib/src/workspace.rs +++ b/lib/src/workspace.rs @@ -13,7 +13,7 @@ // limitations under the License. use std::fs::File; -use std::io::Read; +use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::sync::Arc; @@ -63,11 +63,11 @@ fn init_working_copy( repo: &Arc, workspace_root: &Path, jj_dir: &Path, + workspace_id: WorkspaceId, ) -> (WorkingCopy, Arc) { let working_copy_state_path = jj_dir.join("working_copy"); std::fs::create_dir(&working_copy_state_path).unwrap(); - let workspace_id = WorkspaceId::default(); let mut tx = repo.start_transaction(&format!("add workspace '{}'", workspace_id.as_str())); let checkout_commit = tx.mut_repo().check_out( workspace_id.clone(), @@ -96,8 +96,13 @@ impl Workspace { 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, repo) = - init_working_copy(user_settings, &repo, &workspace_root, &jj_dir); + let (working_copy, repo) = init_working_copy( + user_settings, + &repo, + &workspace_root, + &jj_dir, + WorkspaceId::default(), + ); let repo_loader = repo.loader(); let workspace = Workspace { workspace_root, @@ -115,8 +120,13 @@ impl Workspace { 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, repo) = - init_working_copy(user_settings, &repo, &workspace_root, &jj_dir); + let (working_copy, repo) = init_working_copy( + user_settings, + &repo, + &workspace_root, + &jj_dir, + WorkspaceId::default(), + ); let repo_loader = repo.loader(); let workspace = Workspace { workspace_root, @@ -135,8 +145,13 @@ impl Workspace { 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, repo) = - init_working_copy(user_settings, &repo, &workspace_root, &jj_dir); + let (working_copy, repo) = init_working_copy( + user_settings, + &repo, + &workspace_root, + &jj_dir, + WorkspaceId::default(), + ); let repo_loader = repo.loader(); let workspace = Workspace { workspace_root, @@ -146,6 +161,31 @@ impl Workspace { Ok((workspace, repo)) } + pub fn init_workspace_with_existing_repo( + user_settings: &UserSettings, + workspace_root: PathBuf, + repo: &Arc, + workspace_id: WorkspaceId, + ) -> Result<(Self, Arc), WorkspaceInitError> { + let jj_dir = create_jj_dir(&workspace_root)?; + + let repo_dir = std::fs::canonicalize(repo.repo_path()).unwrap(); + let mut repo_file = File::create(jj_dir.join("repo")).unwrap(); + repo_file + .write_all(repo_dir.to_str().unwrap().as_bytes()) + .unwrap(); + + let repo_loader = RepoLoader::init(user_settings, repo_dir); + let (working_copy, repo) = + init_working_copy(user_settings, repo, &workspace_root, &jj_dir, workspace_id); + let workspace = Workspace { + workspace_root, + repo_loader, + working_copy, + }; + Ok((workspace, repo)) + } + pub fn load( user_settings: &UserSettings, workspace_path: PathBuf, diff --git a/lib/tests/test_workspace.rs b/lib/tests/test_workspace.rs index cf5392dcb..b3c489467 100644 --- a/lib/tests/test_workspace.rs +++ b/lib/tests/test_workspace.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use jujutsu_lib::op_store::WorkspaceId; use jujutsu_lib::testutils; use jujutsu_lib::workspace::{Workspace, WorkspaceLoadError}; use test_case::test_case; @@ -44,3 +45,39 @@ fn test_load_from_subdir(use_git: bool) { assert_eq!(same_workspace.repo_path(), workspace.repo_path()); assert_eq!(same_workspace.workspace_root(), workspace.workspace_root()); } + +#[test_case(false ; "local backend")] +// #[test_case(true ; "git backend")] +fn test_init_additional_workspace(use_git: bool) { + let settings = testutils::user_settings(); + let test_workspace = testutils::init_repo(&settings, use_git); + let workspace = &test_workspace.workspace; + + let ws2_id = WorkspaceId::new("ws2".to_string()); + let ws2_root = test_workspace.temp_dir.path().join("ws2_root"); + std::fs::create_dir(&ws2_root).unwrap(); + let (ws2, repo) = Workspace::init_workspace_with_existing_repo( + &settings, + ws2_root.clone(), + &test_workspace.repo, + ws2_id.clone(), + ) + .unwrap(); + let checkout_id = repo.view().get_checkout(&ws2_id); + assert_ne!(checkout_id, None); + let checkout_id = checkout_id.unwrap(); + let checkout_commit = repo.store().get_commit(checkout_id).unwrap(); + assert_eq!( + checkout_commit.parent_ids(), + vec![repo.store().root_commit_id().clone()] + ); + assert_eq!(ws2.workspace_id(), ws2_id); + assert_eq!(ws2.repo_path(), workspace.repo_path()); + assert_eq!(*ws2.workspace_root(), ws2_root); + let same_workspace = Workspace::load(&settings, ws2_root); + assert!(same_workspace.is_ok()); + let same_workspace = same_workspace.unwrap(); + assert_eq!(same_workspace.workspace_id(), ws2_id); + assert_eq!(same_workspace.repo_path(), workspace.repo_path()); + assert_eq!(same_workspace.workspace_root(), ws2.workspace_root()); +}