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

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:
Martin von Zweigbergk 2022-01-30 12:27:18 -08:00
parent f2e7086172
commit a6ef792ba6
4 changed files with 29 additions and 33 deletions

View file

@ -26,7 +26,7 @@ use thiserror::Error;
use crate::backend::{BackendError, CommitId};
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::index::{IndexRef, MutableIndex, ReadonlyIndex};
use crate::index_store::IndexStore;
@ -165,27 +165,10 @@ impl ReadonlyRepo {
) -> Arc<ReadonlyRepo> {
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 mut root_view = op_store::View::default();
root_view
.checkouts
.insert(workspace_id, checkout_commit.id().clone());
root_view.head_ids.insert(checkout_commit.id().clone());
root_view.head_ids.insert(store.root_commit_id().clone());
root_view
.public_head_ids
.insert(store.root_commit_id().clone());

View file

@ -55,21 +55,32 @@ fn create_jj_dir(workspace_root: &Path) -> Result<PathBuf, WorkspaceInitError> {
}
fn init_working_copy(
user_settings: &UserSettings,
repo: &Arc<ReadonlyRepo>,
workspace_root: &Path,
jj_dir: &Path,
) -> WorkingCopy {
) -> (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();
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(),
workspace_root.to_path_buf(),
working_copy_state_path,
repo.op_id().clone(),
workspace_id,
repo.view().checkout().clone(),
)
checkout_commit.id().clone(),
);
(working_copy, repo)
}
impl Workspace {
@ -81,7 +92,8 @@ 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 = 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 workspace = Workspace {
workspace_root,
@ -99,7 +111,8 @@ 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 = 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 workspace = Workspace {
workspace_root,
@ -118,7 +131,8 @@ 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 = 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 workspace = Workspace {
workspace_root,

View file

@ -66,9 +66,9 @@ fn test_commit_parallel(use_git: bool) {
// root commit
assert_eq!(repo.view().heads().len(), num_threads + 1);
// One operation for initializing the repo (containing the root id and the
// initial working copy commit).
assert_eq!(count_non_merge_operations(&repo), num_threads + 1);
// One addition operation for initializing the repo, one for checking out the
// initial commit.
assert_eq!(count_non_merge_operations(&repo), num_threads + 2);
}
#[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());
assert_eq!(repo.view().heads().len(), num_threads + 1);
// One operation for initializing the repo (containing the root id and the
// initial working copy commit).
assert_eq!(count_non_merge_operations(&repo), num_threads + 1);
// One addition operation for initializing the repo, one for checking out the
// initial commit.
assert_eq!(count_non_merge_operations(&repo), num_threads + 2);
}

View file

@ -328,7 +328,6 @@ fn test_import_refs_detached_head() {
let repo = tx.commit();
let expected_heads = hashset! {
repo.view().checkout().clone(),
commit_id(&commit1),
};
assert_eq!(*repo.view().heads(), expected_heads);