repo/workspace: drop support for old repo formats

It's been more than 6 months since we added support for dynamically
selecting the working copy implementation. This patch drops support
for selecting the default implementation of that and other stores.
This commit is contained in:
Martin von Zweigbergk 2024-06-08 13:59:42 -07:00 committed by Martin von Zweigbergk
parent 556c7291c1
commit bfa0573cab
4 changed files with 15 additions and 66 deletions

View file

@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
modifier. Surround with parentheses if it should be parsed as string/file modifier. Surround with parentheses if it should be parsed as string/file
pattern. pattern.
* Dropped support for automatic upgrade of repo formats used by versions before
0.12.0.
### Deprecations ### Deprecations
### New features ### New features

View file

@ -17,7 +17,6 @@
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::io::ErrorKind;
use std::ops::Deref; use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
@ -478,19 +477,7 @@ impl StoreFactories {
settings: &UserSettings, settings: &UserSettings,
store_path: &Path, store_path: &Path,
) -> Result<Box<dyn Backend>, StoreLoadError> { ) -> Result<Box<dyn Backend>, StoreLoadError> {
// For compatibility with existing repos. TODO: Delete in 0.8+. let backend_type = read_store_type("commit", store_path.join("type"))?;
if store_path.join("backend").is_file() {
fs::rename(store_path.join("backend"), store_path.join("type"))
.expect("Failed to rename 'backend' file to 'type'");
}
// For compatibility with existing repos. TODO: Delete default in 0.8+.
let backend_type = read_store_type_compat("commit", store_path.join("type"), || {
if store_path.join("git_target").is_file() {
GitBackend::name()
} else {
LocalBackend::name()
}
})?;
let backend_factory = self.backend_factories.get(&backend_type).ok_or_else(|| { let backend_factory = self.backend_factories.get(&backend_type).ok_or_else(|| {
StoreLoadError::UnsupportedType { StoreLoadError::UnsupportedType {
store: "commit", store: "commit",
@ -509,9 +496,7 @@ impl StoreFactories {
settings: &UserSettings, settings: &UserSettings,
store_path: &Path, store_path: &Path,
) -> Result<Box<dyn OpStore>, StoreLoadError> { ) -> Result<Box<dyn OpStore>, StoreLoadError> {
// For compatibility with existing repos. TODO: Delete default in 0.8+. let op_store_type = read_store_type("operation", store_path.join("type"))?;
let op_store_type =
read_store_type_compat("operation", store_path.join("type"), SimpleOpStore::name)?;
let op_store_factory = self.op_store_factories.get(&op_store_type).ok_or_else(|| { let op_store_factory = self.op_store_factories.get(&op_store_type).ok_or_else(|| {
StoreLoadError::UnsupportedType { StoreLoadError::UnsupportedType {
store: "operation", store: "operation",
@ -531,12 +516,7 @@ impl StoreFactories {
settings: &UserSettings, settings: &UserSettings,
store_path: &Path, store_path: &Path,
) -> Result<Box<dyn OpHeadsStore>, StoreLoadError> { ) -> Result<Box<dyn OpHeadsStore>, StoreLoadError> {
// For compatibility with existing repos. TODO: Delete default in 0.8+. let op_heads_store_type = read_store_type("operation heads", store_path.join("type"))?;
let op_heads_store_type = read_store_type_compat(
"operation heads",
store_path.join("type"),
SimpleOpHeadsStore::name,
)?;
let op_heads_store_factory = self let op_heads_store_factory = self
.op_heads_store_factories .op_heads_store_factories
.get(&op_heads_store_type) .get(&op_heads_store_type)
@ -556,9 +536,7 @@ impl StoreFactories {
settings: &UserSettings, settings: &UserSettings,
store_path: &Path, store_path: &Path,
) -> Result<Box<dyn IndexStore>, StoreLoadError> { ) -> Result<Box<dyn IndexStore>, StoreLoadError> {
// For compatibility with existing repos. TODO: Delete default in 0.9+ let index_store_type = read_store_type("index", store_path.join("type"))?;
let index_store_type =
read_store_type_compat("index", store_path.join("type"), DefaultIndexStore::name)?;
let index_store_factory = self let index_store_factory = self
.index_store_factories .index_store_factories
.get(&index_store_type) .get(&index_store_type)
@ -579,13 +557,7 @@ impl StoreFactories {
settings: &UserSettings, settings: &UserSettings,
store_path: &Path, store_path: &Path,
) -> Result<Box<dyn SubmoduleStore>, StoreLoadError> { ) -> Result<Box<dyn SubmoduleStore>, StoreLoadError> {
// For compatibility with repos without repo/submodule_store. let submodule_store_type = read_store_type("submodule_store", store_path.join("type"))?;
// TODO Delete default in TBD version
let submodule_store_type = read_store_type_compat(
"submodule_store",
store_path.join("type"),
DefaultSubmoduleStore::name,
)?;
let submodule_store_factory = self let submodule_store_factory = self
.submodule_store_factories .submodule_store_factories
.get(&submodule_store_type) .get(&submodule_store_type)
@ -598,23 +570,12 @@ impl StoreFactories {
} }
} }
pub fn read_store_type_compat( pub fn read_store_type(
store: &'static str, store: &'static str,
path: impl AsRef<Path>, path: impl AsRef<Path>,
default: impl FnOnce() -> &'static str,
) -> Result<String, StoreLoadError> { ) -> Result<String, StoreLoadError> {
let path = path.as_ref(); let path = path.as_ref();
let read_or_write_default = || match fs::read_to_string(path) { fs::read_to_string(path)
Ok(content) => Ok(content),
Err(err) if err.kind() == ErrorKind::NotFound => {
let default_type = default();
fs::create_dir(path.parent().unwrap()).ok();
fs::write(path, default_type)?;
Ok(default_type.to_owned())
}
Err(err) => Err(err),
};
read_or_write_default()
.context(path) .context(path)
.map_err(|source| StoreLoadError::ReadError { store, source }) .map_err(|source| StoreLoadError::ReadError { store, source })
} }

View file

@ -31,7 +31,7 @@ use crate::local_backend::LocalBackend;
use crate::local_working_copy::{LocalWorkingCopy, LocalWorkingCopyFactory}; use crate::local_working_copy::{LocalWorkingCopy, LocalWorkingCopyFactory};
use crate::op_store::{OperationId, WorkspaceId}; use crate::op_store::{OperationId, WorkspaceId};
use crate::repo::{ use crate::repo::{
read_store_type_compat, BackendInitializer, CheckOutCommitError, IndexStoreInitializer, read_store_type, BackendInitializer, CheckOutCommitError, IndexStoreInitializer,
OpHeadsStoreInitializer, OpStoreInitializer, ReadonlyRepo, Repo, RepoInitError, RepoLoader, OpHeadsStoreInitializer, OpStoreInitializer, ReadonlyRepo, Repo, RepoInitError, RepoLoader,
StoreFactories, StoreLoadError, SubmoduleStoreInitializer, StoreFactories, StoreLoadError, SubmoduleStoreInitializer,
}; };
@ -484,12 +484,8 @@ impl WorkspaceLoader {
&self, &self,
working_copy_factories: &'a WorkingCopyFactories, working_copy_factories: &'a WorkingCopyFactories,
) -> Result<&'a dyn WorkingCopyFactory, StoreLoadError> { ) -> Result<&'a dyn WorkingCopyFactory, StoreLoadError> {
// For compatibility with existing repos. TODO: Delete default in 0.17+ let working_copy_type =
let working_copy_type = read_store_type_compat( read_store_type("working copy", self.working_copy_state_path.join("type"))?;
"working copy",
self.working_copy_state_path.join("type"),
LocalWorkingCopy::name,
)?;
if let Some(factory) = working_copy_factories.get(&working_copy_type) { if let Some(factory) = working_copy_factories.get(&working_copy_type) {
Ok(factory.as_ref()) Ok(factory.as_ref())

View file

@ -727,29 +727,18 @@ fn test_reindex_missing_commit() {
assert_matches!(err, DefaultIndexStoreError::IndexCommits { op_id, .. } if op_id == *bad_op_id); assert_matches!(err, DefaultIndexStoreError::IndexCommits { op_id, .. } if op_id == *bad_op_id);
} }
/// Test that .jj/repo/index/type is created when the repo is created, and that /// Test that .jj/repo/index/type is created when the repo is created.
/// it is created when an old repo is loaded.
#[test] #[test]
fn test_index_store_type() { fn test_index_store_type() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init(); let test_repo = TestRepo::init();
let repo = &test_repo.repo; let repo = &test_repo.repo;
assert_eq!(as_readonly_composite(repo).num_commits(), 1); assert_eq!(as_readonly_composite(repo).num_commits(), 1);
let index_store_type_path = repo.repo_path().join("index").join("type"); let index_store_type_path = repo.repo_path().join("index").join("type");
assert_eq!( assert_eq!(
std::fs::read_to_string(&index_store_type_path).unwrap(), std::fs::read_to_string(index_store_type_path).unwrap(),
"default" "default"
); );
// Remove the file to simulate an old repo. Loading the repo should result in
// the file being created.
std::fs::remove_file(&index_store_type_path).unwrap();
let repo = load_repo_at_head(&settings, repo.repo_path());
assert_eq!(
std::fs::read_to_string(&index_store_type_path).unwrap(),
"default"
);
assert_eq!(as_readonly_composite(&repo).num_commits(), 1);
} }
#[test] #[test]