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

working copy: don't expose TreeStateError in LocalWorkingCopy API

The `TreeStateError` type is specific to the current local-disk
working-copy backend, so it should not be part of the generic
working-copy interface I'm trying to create.
This commit is contained in:
Martin von Zweigbergk 2023-10-11 13:20:25 -07:00 committed by Martin von Zweigbergk
parent 0e09d53ce6
commit 9e43207911
3 changed files with 55 additions and 27 deletions

View file

@ -43,7 +43,7 @@ use jj_lib::hex_util::to_reverse_hex;
use jj_lib::id_prefix::IdPrefixContext;
use jj_lib::local_working_copy::{
CheckoutStats, LocalWorkingCopy, LockedLocalWorkingCopy, ResetError, SnapshotError,
SnapshotOptions, TreeStateError,
SnapshotOptions, WorkingCopyStateError,
};
use jj_lib::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit};
use jj_lib::merged_tree::{MergedTree, MergedTreeBuilder};
@ -189,7 +189,7 @@ impl From<WorkspaceInitError> for CommandError {
WorkspaceInitError::Backend(err) => {
user_error(format!("Failed to access the repository: {err}"))
}
WorkspaceInitError::TreeState(err) => {
WorkspaceInitError::WorkingCopyState(err) => {
CommandError::InternalError(format!("Failed to access the repository: {err}"))
}
}
@ -395,9 +395,9 @@ impl From<GitConfigParseError> for CommandError {
}
}
impl From<TreeStateError> for CommandError {
fn from(err: TreeStateError) -> Self {
CommandError::InternalError(format!("Failed to access tree state: {err}"))
impl From<WorkingCopyStateError> for CommandError {
fn from(err: WorkingCopyStateError) -> Self {
CommandError::InternalError(format!("Failed to access working copy state: {err}"))
}
}

View file

@ -1356,6 +1356,13 @@ impl TreeState {
}
}
#[derive(Debug, Error)]
#[error("{message}: {err:?}")]
pub struct WorkingCopyStateError {
message: String,
err: Box<dyn std::error::Error + Send + Sync>,
}
/// Working copy state stored in "checkout" file.
#[derive(Clone, Debug)]
struct CheckoutState {
@ -1403,7 +1410,7 @@ impl LocalWorkingCopy {
state_path: PathBuf,
operation_id: OperationId,
workspace_id: WorkspaceId,
) -> Result<LocalWorkingCopy, TreeStateError> {
) -> Result<LocalWorkingCopy, WorkingCopyStateError> {
let proto = crate::protos::working_copy::Checkout {
operation_id: operation_id.to_bytes(),
workspace_id: workspace_id.as_str().to_string(),
@ -1416,7 +1423,12 @@ impl LocalWorkingCopy {
.unwrap();
file.write_all(&proto.encode_to_vec()).unwrap();
let tree_state =
TreeState::init(store.clone(), working_copy_path.clone(), state_path.clone())?;
TreeState::init(store.clone(), working_copy_path.clone(), state_path.clone()).map_err(
|err| WorkingCopyStateError {
message: "Failed to initialize working copy state".to_string(),
err: err.into(),
},
)?;
Ok(LocalWorkingCopy {
store,
working_copy_path,
@ -1478,30 +1490,35 @@ impl LocalWorkingCopy {
}
#[instrument(skip_all)]
fn tree_state(&self) -> Result<&TreeState, TreeStateError> {
self.tree_state.get_or_try_init(|| {
TreeState::load(
self.store.clone(),
self.working_copy_path.clone(),
self.state_path.clone(),
)
})
fn tree_state(&self) -> Result<&TreeState, WorkingCopyStateError> {
self.tree_state
.get_or_try_init(|| {
TreeState::load(
self.store.clone(),
self.working_copy_path.clone(),
self.state_path.clone(),
)
})
.map_err(|err| WorkingCopyStateError {
message: "Failed to read working copy state".to_string(),
err: err.into(),
})
}
fn tree_state_mut(&mut self) -> Result<&mut TreeState, TreeStateError> {
fn tree_state_mut(&mut self) -> Result<&mut TreeState, WorkingCopyStateError> {
self.tree_state()?; // ensure loaded
Ok(self.tree_state.get_mut().unwrap())
}
pub fn current_tree_id(&self) -> Result<&MergedTreeId, TreeStateError> {
pub fn current_tree_id(&self) -> Result<&MergedTreeId, WorkingCopyStateError> {
Ok(self.tree_state()?.current_tree_id())
}
pub fn file_states(&self) -> Result<&BTreeMap<RepoPath, FileState>, TreeStateError> {
pub fn file_states(&self) -> Result<&BTreeMap<RepoPath, FileState>, WorkingCopyStateError> {
Ok(self.tree_state()?.file_states())
}
pub fn sparse_patterns(&self) -> Result<&[RepoPath], TreeStateError> {
pub fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError> {
Ok(self.tree_state()?.sparse_patterns())
}
@ -1514,7 +1531,7 @@ impl LocalWorkingCopy {
});
}
pub fn start_mutation(&mut self) -> Result<LockedLocalWorkingCopy, TreeStateError> {
pub fn start_mutation(&mut self) -> Result<LockedLocalWorkingCopy, WorkingCopyStateError> {
let lock_path = self.state_path.join("working_copy.lock");
let lock = FileLock::lock(lock_path);
@ -1568,8 +1585,13 @@ impl LocalWorkingCopy {
#[cfg(feature = "watchman")]
pub fn query_watchman(
&self,
) -> Result<(watchman::Clock, Option<Vec<PathBuf>>), TreeStateError> {
self.tree_state()?.query_watchman()
) -> Result<(watchman::Clock, Option<Vec<PathBuf>>), WorkingCopyStateError> {
self.tree_state()?
.query_watchman()
.map_err(|err| WorkingCopyStateError {
message: "Failed to query watchman".to_string(),
err: err.into(),
})
}
}
@ -1650,7 +1672,7 @@ impl LockedLocalWorkingCopy<'_> {
Ok(())
}
pub fn sparse_patterns(&self) -> Result<&[RepoPath], TreeStateError> {
pub fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError> {
self.wc.sparse_patterns()
}
@ -1673,10 +1695,16 @@ impl LockedLocalWorkingCopy<'_> {
}
#[instrument(skip_all)]
pub fn finish(mut self, operation_id: OperationId) -> Result<(), TreeStateError> {
pub fn finish(mut self, operation_id: OperationId) -> Result<(), WorkingCopyStateError> {
assert!(self.tree_state_dirty || &self.old_tree_id == self.wc.current_tree_id()?);
if self.tree_state_dirty {
self.wc.tree_state_mut()?.save()?;
self.wc
.tree_state_mut()?
.save()
.map_err(|err| WorkingCopyStateError {
message: "Failed to write working copy state".to_string(),
err: Box::new(err),
})?;
}
if self.old_operation_id != operation_id {
self.wc.checkout_state_mut().operation_id = operation_id;

View file

@ -27,7 +27,7 @@ use crate::file_util::{IoResultExt as _, PathError};
use crate::git_backend::GitBackend;
use crate::index::IndexStore;
use crate::local_backend::LocalBackend;
use crate::local_working_copy::{LocalWorkingCopy, TreeStateError};
use crate::local_working_copy::{LocalWorkingCopy, WorkingCopyStateError};
use crate::op_heads_store::OpHeadsStore;
use crate::op_store::{OpStore, WorkspaceId};
use crate::repo::{
@ -47,7 +47,7 @@ pub enum WorkspaceInitError {
#[error(transparent)]
CheckOutCommit(#[from] CheckOutCommitError),
#[error(transparent)]
TreeState(#[from] TreeStateError),
WorkingCopyState(#[from] WorkingCopyStateError),
#[error(transparent)]
Path(#[from] PathError),
#[error(transparent)]