mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-16 00:56:23 +00:00
store: reduce duplication in Workspace
and Repo
init code
There is a bit of duplicated across the three functions for creating a `Workspace` and `Repo`. This patch reduces that duplication by passing in a closure. In addition to reducing duplication, this is a step towards making it easier to add new backends.
This commit is contained in:
parent
07c8126053
commit
25b922cd0b
4 changed files with 46 additions and 67 deletions
|
@ -23,12 +23,14 @@ use std::sync::{Arc, Mutex};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::backend::{BackendError, ChangeId, CommitId};
|
use crate::backend::{Backend, BackendError, ChangeId, CommitId};
|
||||||
use crate::commit::Commit;
|
use crate::commit::Commit;
|
||||||
use crate::commit_builder::CommitBuilder;
|
use crate::commit_builder::CommitBuilder;
|
||||||
use crate::dag_walk::topo_order_reverse;
|
use crate::dag_walk::topo_order_reverse;
|
||||||
|
use crate::git_backend::GitBackend;
|
||||||
use crate::index::{IndexRef, MutableIndex, ReadonlyIndex};
|
use crate::index::{IndexRef, MutableIndex, ReadonlyIndex};
|
||||||
use crate::index_store::IndexStore;
|
use crate::index_store::IndexStore;
|
||||||
|
use crate::local_backend::LocalBackend;
|
||||||
use crate::op_heads_store::{LockedOpHeads, OpHeads, OpHeadsStore};
|
use crate::op_heads_store::{LockedOpHeads, OpHeads, OpHeadsStore};
|
||||||
use crate::op_store::{BranchTarget, OpStore, OperationId, RefTarget, WorkspaceId};
|
use crate::op_store::{BranchTarget, OpStore, OperationId, RefTarget, WorkspaceId};
|
||||||
use crate::operation::Operation;
|
use crate::operation::Operation;
|
||||||
|
@ -127,18 +129,16 @@ impl Debug for ReadonlyRepo {
|
||||||
|
|
||||||
impl ReadonlyRepo {
|
impl ReadonlyRepo {
|
||||||
pub fn init_local(settings: &UserSettings, repo_path: PathBuf) -> Arc<ReadonlyRepo> {
|
pub fn init_local(settings: &UserSettings, repo_path: PathBuf) -> Arc<ReadonlyRepo> {
|
||||||
let repo_path = repo_path.canonicalize().unwrap();
|
Self::init(settings, repo_path, |store_path| {
|
||||||
ReadonlyRepo::init_repo_dir(&repo_path);
|
Box::new(LocalBackend::init(store_path))
|
||||||
let store = Store::init_local(repo_path.join("store"));
|
})
|
||||||
ReadonlyRepo::init(settings, repo_path, store)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes a repo with a new Git backend in .jj/git/ (bare Git repo)
|
/// Initializes a repo with a new Git backend in .jj/git/ (bare Git repo)
|
||||||
pub fn init_internal_git(settings: &UserSettings, repo_path: PathBuf) -> Arc<ReadonlyRepo> {
|
pub fn init_internal_git(settings: &UserSettings, repo_path: PathBuf) -> Arc<ReadonlyRepo> {
|
||||||
let repo_path = repo_path.canonicalize().unwrap();
|
Self::init(settings, repo_path, |store_path| {
|
||||||
ReadonlyRepo::init_repo_dir(&repo_path);
|
Box::new(GitBackend::init_internal(store_path))
|
||||||
let store = Store::init_internal_git(repo_path.join("store"));
|
})
|
||||||
ReadonlyRepo::init(settings, repo_path, store)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes a repo with an existing Git backend at the specified path
|
/// Initializes a repo with an existing Git backend at the specified path
|
||||||
|
@ -147,10 +147,9 @@ impl ReadonlyRepo {
|
||||||
repo_path: PathBuf,
|
repo_path: PathBuf,
|
||||||
git_repo_path: PathBuf,
|
git_repo_path: PathBuf,
|
||||||
) -> Arc<ReadonlyRepo> {
|
) -> Arc<ReadonlyRepo> {
|
||||||
let repo_path = repo_path.canonicalize().unwrap();
|
Self::init(settings, repo_path, |store_path| {
|
||||||
ReadonlyRepo::init_repo_dir(&repo_path);
|
Box::new(GitBackend::init_external(store_path, git_repo_path.clone()))
|
||||||
let store = Store::init_external_git(repo_path.join("store"), git_repo_path);
|
})
|
||||||
ReadonlyRepo::init(settings, repo_path, store)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_repo_dir(repo_path: &Path) {
|
fn init_repo_dir(repo_path: &Path) {
|
||||||
|
@ -160,15 +159,16 @@ impl ReadonlyRepo {
|
||||||
fs::create_dir(repo_path.join("index")).unwrap();
|
fs::create_dir(repo_path.join("index")).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
pub fn init(
|
||||||
user_settings: &UserSettings,
|
user_settings: &UserSettings,
|
||||||
repo_path: PathBuf,
|
repo_path: PathBuf,
|
||||||
store: Arc<Store>,
|
backend_factory: impl FnOnce(PathBuf) -> Box<dyn Backend>,
|
||||||
) -> Arc<ReadonlyRepo> {
|
) -> Arc<ReadonlyRepo> {
|
||||||
|
let repo_path = repo_path.canonicalize().unwrap();
|
||||||
|
ReadonlyRepo::init_repo_dir(&repo_path);
|
||||||
|
let store = Store::new(backend_factory(repo_path.join("store")));
|
||||||
let repo_settings = user_settings.with_repo(&repo_path).unwrap();
|
let repo_settings = user_settings.with_repo(&repo_path).unwrap();
|
||||||
|
|
||||||
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.head_ids.insert(store.root_commit_id().clone());
|
root_view.head_ids.insert(store.root_commit_id().clone());
|
||||||
root_view
|
root_view
|
||||||
|
@ -177,11 +177,8 @@ impl ReadonlyRepo {
|
||||||
let (op_heads_store, init_op) =
|
let (op_heads_store, init_op) =
|
||||||
OpHeadsStore::init(repo_path.join("op_heads"), &op_store, &root_view);
|
OpHeadsStore::init(repo_path.join("op_heads"), &op_store, &root_view);
|
||||||
let op_heads_store = Arc::new(op_heads_store);
|
let op_heads_store = Arc::new(op_heads_store);
|
||||||
|
|
||||||
let index_store = Arc::new(IndexStore::init(repo_path.join("index")));
|
let index_store = Arc::new(IndexStore::init(repo_path.join("index")));
|
||||||
|
|
||||||
let view = View::new(root_view);
|
let view = View::new(root_view);
|
||||||
|
|
||||||
Arc::new(ReadonlyRepo {
|
Arc::new(ReadonlyRepo {
|
||||||
repo_path,
|
repo_path,
|
||||||
store,
|
store,
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub struct Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
fn new(backend: Box<dyn Backend>) -> Arc<Self> {
|
pub fn new(backend: Box<dyn Backend>) -> Arc<Self> {
|
||||||
let root_commit_id = CommitId::new(vec![0; backend.hash_length()]);
|
let root_commit_id = CommitId::new(vec![0; backend.hash_length()]);
|
||||||
Arc::new(Store {
|
Arc::new(Store {
|
||||||
backend,
|
backend,
|
||||||
|
@ -50,21 +50,6 @@ impl Store {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_local(store_path: PathBuf) -> Arc<Self> {
|
|
||||||
Store::new(Box::new(LocalBackend::init(store_path)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_internal_git(store_path: PathBuf) -> Arc<Self> {
|
|
||||||
Store::new(Box::new(GitBackend::init_internal(store_path)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_external_git(store_path: PathBuf, git_repo_path: PathBuf) -> Arc<Self> {
|
|
||||||
Store::new(Box::new(GitBackend::init_external(
|
|
||||||
store_path,
|
|
||||||
git_repo_path,
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_store(store_path: PathBuf) -> Arc<Store> {
|
pub fn load_store(store_path: PathBuf) -> Arc<Store> {
|
||||||
let git_target_path = store_path.join("git_target");
|
let git_target_path = store_path.join("git_target");
|
||||||
let backend: Box<dyn Backend> = if git_target_path.is_file() {
|
let backend: Box<dyn Backend> = if git_target_path.is_file() {
|
||||||
|
|
|
@ -24,6 +24,8 @@ use tempfile::TempDir;
|
||||||
use crate::backend::{FileId, TreeId, TreeValue};
|
use crate::backend::{FileId, TreeId, TreeValue};
|
||||||
use crate::commit::Commit;
|
use crate::commit::Commit;
|
||||||
use crate::commit_builder::CommitBuilder;
|
use crate::commit_builder::CommitBuilder;
|
||||||
|
use crate::git_backend::GitBackend;
|
||||||
|
use crate::local_backend::LocalBackend;
|
||||||
use crate::repo::{MutableRepo, ReadonlyRepo};
|
use crate::repo::{MutableRepo, ReadonlyRepo};
|
||||||
use crate::repo_path::RepoPath;
|
use crate::repo_path::RepoPath;
|
||||||
use crate::rewrite::RebasedDescendant;
|
use crate::rewrite::RebasedDescendant;
|
||||||
|
@ -68,9 +70,13 @@ impl TestRepo {
|
||||||
let repo = if use_git {
|
let repo = if use_git {
|
||||||
let git_path = temp_dir.path().join("git-repo");
|
let git_path = temp_dir.path().join("git-repo");
|
||||||
git2::Repository::init(&git_path).unwrap();
|
git2::Repository::init(&git_path).unwrap();
|
||||||
ReadonlyRepo::init_external_git(&settings, repo_dir, git_path)
|
ReadonlyRepo::init(&settings, repo_dir, |store_path| {
|
||||||
|
Box::new(GitBackend::init_external(store_path, git_path.clone()))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
ReadonlyRepo::init_local(&settings, repo_dir)
|
ReadonlyRepo::init(&settings, repo_dir, |store_path| {
|
||||||
|
Box::new(LocalBackend::init(store_path))
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -19,6 +19,9 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use crate::backend::Backend;
|
||||||
|
use crate::git_backend::GitBackend;
|
||||||
|
use crate::local_backend::LocalBackend;
|
||||||
use crate::op_store::WorkspaceId;
|
use crate::op_store::WorkspaceId;
|
||||||
use crate::repo::{ReadonlyRepo, RepoLoader};
|
use crate::repo::{ReadonlyRepo, RepoLoader};
|
||||||
use crate::settings::UserSettings;
|
use crate::settings::UserSettings;
|
||||||
|
@ -104,51 +107,39 @@ impl Workspace {
|
||||||
user_settings: &UserSettings,
|
user_settings: &UserSettings,
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
||||||
let jj_dir = create_jj_dir(&workspace_root)?;
|
Self::init_with_backend(user_settings, workspace_root, |store_path| {
|
||||||
let repo_dir = jj_dir.join("repo");
|
Box::new(LocalBackend::init(store_path))
|
||||||
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,
|
|
||||||
WorkspaceId::default(),
|
|
||||||
);
|
|
||||||
let repo_loader = repo.loader();
|
|
||||||
let workspace = Self::new(workspace_root, working_copy, repo_loader);
|
|
||||||
Ok((workspace, repo))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_internal_git(
|
pub fn init_internal_git(
|
||||||
user_settings: &UserSettings,
|
user_settings: &UserSettings,
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
||||||
let jj_dir = create_jj_dir(&workspace_root)?;
|
Self::init_with_backend(user_settings, workspace_root, |store_path| {
|
||||||
let repo_dir = jj_dir.join("repo");
|
Box::new(GitBackend::init_internal(store_path))
|
||||||
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,
|
|
||||||
WorkspaceId::default(),
|
|
||||||
);
|
|
||||||
let repo_loader = repo.loader();
|
|
||||||
let workspace = Workspace::new(workspace_root, working_copy, repo_loader);
|
|
||||||
Ok((workspace, repo))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_external_git(
|
pub fn init_external_git(
|
||||||
user_settings: &UserSettings,
|
user_settings: &UserSettings,
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
git_repo_path: PathBuf,
|
git_repo_path: PathBuf,
|
||||||
|
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
||||||
|
Self::init_with_backend(user_settings, workspace_root, |store_path| {
|
||||||
|
Box::new(GitBackend::init_external(store_path, git_repo_path.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_with_backend(
|
||||||
|
user_settings: &UserSettings,
|
||||||
|
workspace_root: PathBuf,
|
||||||
|
backend_factory: impl FnOnce(PathBuf) -> Box<dyn Backend>,
|
||||||
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
|
||||||
let jj_dir = create_jj_dir(&workspace_root)?;
|
let jj_dir = create_jj_dir(&workspace_root)?;
|
||||||
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(user_settings, repo_dir, backend_factory);
|
||||||
let (working_copy, repo) = init_working_copy(
|
let (working_copy, repo) = init_working_copy(
|
||||||
user_settings,
|
user_settings,
|
||||||
&repo,
|
&repo,
|
||||||
|
|
Loading…
Reference in a new issue