mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-18 18:27:38 +00:00
repo: initialize without checkouts, let Workspace add it (#13)
As part of creating a new repository, we create an open commit on top of the root and set that as the current checkout. Now that we have support for multiple checkouts in the model, we also have support for zero checkouts, which means we don't need to create that commit on top of the root when creating the repo. We can therefore move out of `ReadonlyRepo`'s initialization code and let `Workspace` instead take care of it. A user-visible effect of this change is that we now create one operation for initilizing the repo and another one for checking out the root commit. That seems fine, and will be consistent with the additional operation we will create when adding further workspaces.
This commit is contained in:
parent
f2e7086172
commit
a6ef792ba6
4 changed files with 29 additions and 33 deletions
|
@ -26,7 +26,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::backend::{BackendError, CommitId};
|
use crate::backend::{BackendError, CommitId};
|
||||||
use crate::commit::Commit;
|
use crate::commit::Commit;
|
||||||
use crate::commit_builder::{new_change_id, signature, CommitBuilder};
|
use crate::commit_builder::CommitBuilder;
|
||||||
use crate::dag_walk::topo_order_reverse;
|
use crate::dag_walk::topo_order_reverse;
|
||||||
use crate::index::{IndexRef, MutableIndex, ReadonlyIndex};
|
use crate::index::{IndexRef, MutableIndex, ReadonlyIndex};
|
||||||
use crate::index_store::IndexStore;
|
use crate::index_store::IndexStore;
|
||||||
|
@ -165,27 +165,10 @@ impl ReadonlyRepo {
|
||||||
) -> Arc<ReadonlyRepo> {
|
) -> Arc<ReadonlyRepo> {
|
||||||
let repo_settings = user_settings.with_repo(&repo_path).unwrap();
|
let repo_settings = user_settings.with_repo(&repo_path).unwrap();
|
||||||
|
|
||||||
let signature = signature(user_settings);
|
|
||||||
let checkout_commit = backend::Commit {
|
|
||||||
parents: vec![],
|
|
||||||
predecessors: vec![],
|
|
||||||
root_tree: store.empty_tree_id().clone(),
|
|
||||||
change_id: new_change_id(),
|
|
||||||
description: "".to_string(),
|
|
||||||
author: signature.clone(),
|
|
||||||
committer: signature,
|
|
||||||
is_open: true,
|
|
||||||
};
|
|
||||||
let checkout_commit = store.write_commit(checkout_commit);
|
|
||||||
let workspace_id = WorkspaceId::default();
|
|
||||||
|
|
||||||
let op_store: Arc<dyn OpStore> = Arc::new(SimpleOpStore::init(repo_path.join("op_store")));
|
let op_store: Arc<dyn OpStore> = Arc::new(SimpleOpStore::init(repo_path.join("op_store")));
|
||||||
|
|
||||||
let mut root_view = op_store::View::default();
|
let mut root_view = op_store::View::default();
|
||||||
root_view
|
root_view.head_ids.insert(store.root_commit_id().clone());
|
||||||
.checkouts
|
|
||||||
.insert(workspace_id, checkout_commit.id().clone());
|
|
||||||
root_view.head_ids.insert(checkout_commit.id().clone());
|
|
||||||
root_view
|
root_view
|
||||||
.public_head_ids
|
.public_head_ids
|
||||||
.insert(store.root_commit_id().clone());
|
.insert(store.root_commit_id().clone());
|
||||||
|
|
|
@ -55,21 +55,32 @@ fn create_jj_dir(workspace_root: &Path) -> Result<PathBuf, WorkspaceInitError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_working_copy(
|
fn init_working_copy(
|
||||||
|
user_settings: &UserSettings,
|
||||||
repo: &Arc<ReadonlyRepo>,
|
repo: &Arc<ReadonlyRepo>,
|
||||||
workspace_root: &Path,
|
workspace_root: &Path,
|
||||||
jj_dir: &Path,
|
jj_dir: &Path,
|
||||||
) -> WorkingCopy {
|
) -> (WorkingCopy, Arc<ReadonlyRepo>) {
|
||||||
let working_copy_state_path = jj_dir.join("working_copy");
|
let working_copy_state_path = jj_dir.join("working_copy");
|
||||||
std::fs::create_dir(&working_copy_state_path).unwrap();
|
std::fs::create_dir(&working_copy_state_path).unwrap();
|
||||||
|
|
||||||
let workspace_id = WorkspaceId::default();
|
let workspace_id = WorkspaceId::default();
|
||||||
WorkingCopy::init(
|
let mut tx = repo.start_transaction(&format!("add workspace '{}'", workspace_id.as_str()));
|
||||||
|
let checkout_commit = tx.mut_repo().check_out(
|
||||||
|
workspace_id.clone(),
|
||||||
|
user_settings,
|
||||||
|
&repo.store().root_commit(),
|
||||||
|
);
|
||||||
|
let repo = tx.commit();
|
||||||
|
|
||||||
|
let working_copy = WorkingCopy::init(
|
||||||
repo.store().clone(),
|
repo.store().clone(),
|
||||||
workspace_root.to_path_buf(),
|
workspace_root.to_path_buf(),
|
||||||
working_copy_state_path,
|
working_copy_state_path,
|
||||||
repo.op_id().clone(),
|
repo.op_id().clone(),
|
||||||
workspace_id,
|
workspace_id,
|
||||||
repo.view().checkout().clone(),
|
checkout_commit.id().clone(),
|
||||||
)
|
);
|
||||||
|
(working_copy, repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Workspace {
|
impl Workspace {
|
||||||
|
@ -81,7 +92,8 @@ impl Workspace {
|
||||||
let repo_dir = jj_dir.join("repo");
|
let repo_dir = jj_dir.join("repo");
|
||||||
std::fs::create_dir(&repo_dir).unwrap();
|
std::fs::create_dir(&repo_dir).unwrap();
|
||||||
let repo = ReadonlyRepo::init_local(user_settings, repo_dir);
|
let repo = ReadonlyRepo::init_local(user_settings, repo_dir);
|
||||||
let working_copy = init_working_copy(&repo, &workspace_root, &jj_dir);
|
let (working_copy, repo) =
|
||||||
|
init_working_copy(user_settings, &repo, &workspace_root, &jj_dir);
|
||||||
let repo_loader = repo.loader();
|
let repo_loader = repo.loader();
|
||||||
let workspace = Workspace {
|
let workspace = Workspace {
|
||||||
workspace_root,
|
workspace_root,
|
||||||
|
@ -99,7 +111,8 @@ impl Workspace {
|
||||||
let repo_dir = jj_dir.join("repo");
|
let repo_dir = jj_dir.join("repo");
|
||||||
std::fs::create_dir(&repo_dir).unwrap();
|
std::fs::create_dir(&repo_dir).unwrap();
|
||||||
let repo = ReadonlyRepo::init_internal_git(user_settings, repo_dir);
|
let repo = ReadonlyRepo::init_internal_git(user_settings, repo_dir);
|
||||||
let working_copy = init_working_copy(&repo, &workspace_root, &jj_dir);
|
let (working_copy, repo) =
|
||||||
|
init_working_copy(user_settings, &repo, &workspace_root, &jj_dir);
|
||||||
let repo_loader = repo.loader();
|
let repo_loader = repo.loader();
|
||||||
let workspace = Workspace {
|
let workspace = Workspace {
|
||||||
workspace_root,
|
workspace_root,
|
||||||
|
@ -118,7 +131,8 @@ impl Workspace {
|
||||||
let repo_dir = jj_dir.join("repo");
|
let repo_dir = jj_dir.join("repo");
|
||||||
std::fs::create_dir(&repo_dir).unwrap();
|
std::fs::create_dir(&repo_dir).unwrap();
|
||||||
let repo = ReadonlyRepo::init_external_git(user_settings, repo_dir, git_repo_path);
|
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 (working_copy, repo) =
|
||||||
|
init_working_copy(user_settings, &repo, &workspace_root, &jj_dir);
|
||||||
let repo_loader = repo.loader();
|
let repo_loader = repo.loader();
|
||||||
let workspace = Workspace {
|
let workspace = Workspace {
|
||||||
workspace_root,
|
workspace_root,
|
||||||
|
|
|
@ -66,9 +66,9 @@ fn test_commit_parallel(use_git: bool) {
|
||||||
// root commit
|
// root commit
|
||||||
assert_eq!(repo.view().heads().len(), num_threads + 1);
|
assert_eq!(repo.view().heads().len(), num_threads + 1);
|
||||||
|
|
||||||
// One operation for initializing the repo (containing the root id and the
|
// One addition operation for initializing the repo, one for checking out the
|
||||||
// initial working copy commit).
|
// initial commit.
|
||||||
assert_eq!(count_non_merge_operations(&repo), num_threads + 1);
|
assert_eq!(count_non_merge_operations(&repo), num_threads + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case(false ; "local backend")]
|
#[test_case(false ; "local backend")]
|
||||||
|
@ -100,7 +100,7 @@ fn test_commit_parallel_instances(use_git: bool) {
|
||||||
let repo = ReadonlyRepo::load(&settings, repo.repo_path().clone());
|
let repo = ReadonlyRepo::load(&settings, repo.repo_path().clone());
|
||||||
assert_eq!(repo.view().heads().len(), num_threads + 1);
|
assert_eq!(repo.view().heads().len(), num_threads + 1);
|
||||||
|
|
||||||
// One operation for initializing the repo (containing the root id and the
|
// One addition operation for initializing the repo, one for checking out the
|
||||||
// initial working copy commit).
|
// initial commit.
|
||||||
assert_eq!(count_non_merge_operations(&repo), num_threads + 1);
|
assert_eq!(count_non_merge_operations(&repo), num_threads + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,7 +328,6 @@ fn test_import_refs_detached_head() {
|
||||||
let repo = tx.commit();
|
let repo = tx.commit();
|
||||||
|
|
||||||
let expected_heads = hashset! {
|
let expected_heads = hashset! {
|
||||||
repo.view().checkout().clone(),
|
|
||||||
commit_id(&commit1),
|
commit_id(&commit1),
|
||||||
};
|
};
|
||||||
assert_eq!(*repo.view().heads(), expected_heads);
|
assert_eq!(*repo.view().heads(), expected_heads);
|
||||||
|
|
Loading…
Reference in a new issue