ok/jj
1
0
Fork 0
forked from mirrors/jj

workspace: add a function for initializing additional workspace (#13)

This commit is contained in:
Martin von Zweigbergk 2022-01-30 11:58:05 -08:00
parent 5fd060ca18
commit c09a4e15c5
3 changed files with 87 additions and 8 deletions

View file

@ -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)

View file

@ -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<ReadonlyRepo>,
workspace_root: &Path,
jj_dir: &Path,
workspace_id: WorkspaceId,
) -> (WorkingCopy, Arc<ReadonlyRepo>) {
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<ReadonlyRepo>,
workspace_id: WorkspaceId,
) -> Result<(Self, Arc<ReadonlyRepo>), 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,

View file

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