workspace: add functions for initializing a repo

`ReadonlyRepo::init_*()` currently calls `WorkingCopy::init()`. In
order to remove that dependency, this patch wraps the
`ReadonlyRepo::init_*()` functions in new `Workspace` functions. A
later patch will have those functions call `WorkspaceCopy::init()`.`
This commit is contained in:
Martin von Zweigbergk 2021-11-21 22:55:31 -08:00
parent c08adba424
commit 466d35d4bc
4 changed files with 57 additions and 22 deletions

View File

@ -60,14 +60,13 @@ pub fn init_repo(settings: &UserSettings, use_git: bool) -> TestWorkspace {
let workspace_root = temp_dir.path().join("repo");
fs::create_dir(&workspace_root).unwrap();
let repo = if use_git {
let (workspace, repo) = if use_git {
let git_path = temp_dir.path().join("git-repo");
git2::Repository::init(&git_path).unwrap();
ReadonlyRepo::init_external_git(settings, workspace_root.clone(), git_path).unwrap()
Workspace::init_external_git(settings, workspace_root, git_path).unwrap()
} else {
ReadonlyRepo::init_local(settings, workspace_root.clone()).unwrap()
Workspace::init_local(settings, workspace_root).unwrap()
};
let workspace = Workspace::load(settings, workspace_root).unwrap();
TestWorkspace {
temp_dir,

View File

@ -13,8 +13,9 @@
// limitations under the License.
use std::path::PathBuf;
use std::sync::Arc;
use crate::repo::{RepoLoadError, RepoLoader};
use crate::repo::{ReadonlyRepo, RepoInitError, RepoLoadError, RepoLoader};
use crate::settings::UserSettings;
use crate::working_copy::WorkingCopy;
@ -29,6 +30,38 @@ pub struct Workspace {
}
impl Workspace {
pub fn init_local(
user_settings: &UserSettings,
workspace_root: PathBuf,
) -> Result<(Self, Arc<ReadonlyRepo>), RepoInitError> {
let repo = ReadonlyRepo::init_local(user_settings, workspace_root.clone())?;
let repo_loader = repo.loader();
let workspace = Self::from_repo_loader(workspace_root, repo_loader);
Ok((workspace, repo))
}
pub fn init_internal_git(
user_settings: &UserSettings,
workspace_root: PathBuf,
) -> Result<(Self, Arc<ReadonlyRepo>), RepoInitError> {
let repo = ReadonlyRepo::init_internal_git(user_settings, workspace_root.clone())?;
let repo_loader = repo.loader();
let workspace = Self::from_repo_loader(workspace_root, repo_loader);
Ok((workspace, repo))
}
pub fn init_external_git(
user_settings: &UserSettings,
workspace_root: PathBuf,
git_repo_path: PathBuf,
) -> Result<(Self, Arc<ReadonlyRepo>), RepoInitError> {
let repo =
ReadonlyRepo::init_external_git(user_settings, workspace_root.clone(), git_repo_path)?;
let repo_loader = repo.loader();
let workspace = Self::from_repo_loader(workspace_root, repo_loader);
Ok((workspace, repo))
}
pub fn load(
user_settings: &UserSettings,
workspace_root: PathBuf,
@ -36,17 +69,21 @@ impl Workspace {
// TODO: Move the find_repo_dir() call from RepoLoader::init() to here
let repo_loader = RepoLoader::init(user_settings, workspace_root)?;
let workspace_root = repo_loader.working_copy_path().clone();
let working_copy_state_path = repo_path.join("working_copy");
Ok(Self::from_repo_loader(workspace_root, repo_loader))
}
fn from_repo_loader(workspace_root: PathBuf, repo_loader: RepoLoader) -> Self {
let working_copy_state_path = repo_loader.repo_path().join("working_copy");
let working_copy = WorkingCopy::load(
repo_loader.store().clone(),
workspace_root.clone(),
working_copy_state_path,
);
Ok(Self {
Self {
workspace_root,
repo_loader,
working_copy,
})
}
}
pub fn workspace_root(&self) -> &PathBuf {

View File

@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use jujutsu_lib::repo::ReadonlyRepo;
use jujutsu_lib::settings::UserSettings;
use jujutsu_lib::testutils;
use jujutsu_lib::workspace::Workspace;
use test_case::test_case;
#[test]
@ -22,10 +22,10 @@ fn test_init_local() {
let settings = testutils::user_settings();
let temp_dir = tempfile::tempdir().unwrap();
let wc_path = temp_dir.path().to_owned();
let repo = ReadonlyRepo::init_local(&settings, wc_path.clone()).unwrap();
let (workspace, repo) = Workspace::init_local(&settings, wc_path.clone()).unwrap();
assert!(repo.store().git_repo().is_none());
assert_eq!(repo.working_copy_path(), &wc_path);
assert_eq!(repo.repo_path(), &wc_path.join(".jj"));
assert_eq!(workspace.workspace_root(), &wc_path);
// Just test that we can write a commit to the store
let mut tx = repo.start_transaction("test");
@ -38,10 +38,10 @@ fn test_init_internal_git() {
let settings = testutils::user_settings();
let temp_dir = tempfile::tempdir().unwrap();
let wc_path = temp_dir.path().to_owned();
let repo = ReadonlyRepo::init_internal_git(&settings, wc_path.clone()).unwrap();
let (workspace, repo) = Workspace::init_internal_git(&settings, wc_path.clone()).unwrap();
assert!(repo.store().git_repo().is_some());
assert_eq!(repo.working_copy_path(), &wc_path);
assert_eq!(repo.repo_path(), &wc_path.join(".jj"));
assert_eq!(workspace.workspace_root(), &wc_path);
// Just test that we ca write a commit to the store
let mut tx = repo.start_transaction("test");
@ -57,10 +57,11 @@ fn test_init_external_git() {
git2::Repository::init(&git_repo_path).unwrap();
let wc_path = temp_dir.path().join("jj");
std::fs::create_dir(&wc_path).unwrap();
let repo = ReadonlyRepo::init_external_git(&settings, wc_path.clone(), git_repo_path).unwrap();
let (workspace, repo) =
Workspace::init_external_git(&settings, wc_path.clone(), git_repo_path).unwrap();
assert!(repo.store().git_repo().is_some());
assert_eq!(repo.working_copy_path(), &wc_path);
assert_eq!(repo.repo_path(), &wc_path.join(".jj"));
assert_eq!(workspace.workspace_root(), &wc_path);
// Just test that we can write a commit to the store
let mut tx = repo.start_transaction("test");

View File

@ -1384,20 +1384,19 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &ArgMatches) -> Result<(
if let Some(git_store_str) = args.value_of("git-store") {
let git_store_path = ui.cwd().join(git_store_str);
let repo = ReadonlyRepo::init_external_git(ui.settings(), wc_path.clone(), git_store_path)?;
let (workspace, repo) =
Workspace::init_external_git(ui.settings(), wc_path.clone(), git_store_path)?;
let git_repo = repo.store().git_repo().unwrap();
let workspace = Workspace::load(ui.settings(), wc_path.clone()).unwrap();
let mut workspace_command = command.for_loaded_repo(ui, workspace, repo);
let mut tx = workspace_command.start_transaction("import git refs");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
// TODO: Check out a recent commit. Maybe one with the highest generation
// number.
workspace_command.finish_transaction(ui, tx)?;
workspace_command.repo
} else if args.is_present("git") {
ReadonlyRepo::init_internal_git(ui.settings(), wc_path.clone())?
Workspace::init_internal_git(ui.settings(), wc_path.clone())?;
} else {
ReadonlyRepo::init_local(ui.settings(), wc_path.clone())?
Workspace::init_local(ui.settings(), wc_path.clone())?;
};
writeln!(ui, "Initialized repo in \"{}\"", wc_path.display())?;
Ok(())
@ -3526,10 +3525,9 @@ fn cmd_git_clone(
fs::create_dir(&wc_path).unwrap();
}
let repo = ReadonlyRepo::init_internal_git(ui.settings(), wc_path.clone())?;
let (workspace, repo) = Workspace::init_internal_git(ui.settings(), wc_path.clone())?;
let git_repo = get_git_repo(repo.store())?;
writeln!(ui, "Fetching into new repo in {:?}", wc_path)?;
let workspace = Workspace::load(ui.settings(), wc_path).unwrap();
let mut workspace_command = command.for_loaded_repo(ui, workspace, repo);
let remote_name = "origin";
git_repo.remote(remote_name, source).unwrap();