From 63654d064bd5e8cf99ad07e2bd44c2d043d28e54 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Thu, 12 Oct 2023 09:44:24 -0700 Subject: [PATCH] working copy: add sparse pattern functions to backend trait --- cli/src/cli_util.rs | 3 +- cli/src/commands/mod.rs | 2 +- lib/src/local_working_copy.rs | 49 +++++++++------------ lib/src/working_copy.rs | 30 +++++++++++++ lib/src/workspace.rs | 6 ++- lib/tests/test_local_working_copy.rs | 4 +- lib/tests/test_local_working_copy_sparse.rs | 2 +- 7 files changed, 62 insertions(+), 34 deletions(-) diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index b3eff2739..e4e8d403f 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -41,7 +41,7 @@ use jj_lib::git_backend::GitBackend; use jj_lib::gitignore::GitIgnoreFile; use jj_lib::hex_util::to_reverse_hex; use jj_lib::id_prefix::IdPrefixContext; -use jj_lib::local_working_copy::{LocalWorkingCopy, LockedLocalWorkingCopy, WorkingCopyStateError}; +use jj_lib::local_working_copy::{LocalWorkingCopy, LockedLocalWorkingCopy}; use jj_lib::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit}; use jj_lib::merged_tree::{MergedTree, MergedTreeBuilder}; use jj_lib::op_heads_store::{self, OpHeadResolutionError, OpHeadsStore}; @@ -62,6 +62,7 @@ use jj_lib::transaction::Transaction; use jj_lib::tree::TreeMergeError; use jj_lib::working_copy::{ CheckoutStats, LockedWorkingCopy, ResetError, SnapshotError, SnapshotOptions, WorkingCopy, + WorkingCopyStateError, }; use jj_lib::workspace::{ LockedWorkspace, Workspace, WorkspaceInitError, WorkspaceLoadError, WorkspaceLoader, diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index 7f6a61d29..2a087e570 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -47,7 +47,7 @@ use jj_lib::revset_graph::{ }; use jj_lib::rewrite::{back_out_commit, merge_commit_trees, rebase_commit, DescendantRebaser}; use jj_lib::settings::UserSettings; -use jj_lib::working_copy::{LockedWorkingCopy, SnapshotOptions}; +use jj_lib::working_copy::{LockedWorkingCopy, SnapshotOptions, WorkingCopy}; use jj_lib::workspace::Workspace; use jj_lib::{conflicts, file_util, revset}; use maplit::{hashmap, hashset}; diff --git a/lib/src/local_working_copy.rs b/lib/src/local_working_copy.rs index ffb29c550..8c2302e13 100644 --- a/lib/src/local_working_copy.rs +++ b/lib/src/local_working_copy.rs @@ -60,7 +60,7 @@ use crate::store::Store; use crate::tree::Tree; use crate::working_copy::{ CheckoutError, CheckoutStats, LockedWorkingCopy, ResetError, SnapshotError, SnapshotOptions, - SnapshotProgress, WorkingCopy, + SnapshotProgress, WorkingCopy, WorkingCopyStateError, }; #[cfg(unix)] @@ -1268,13 +1268,6 @@ fn checkout_error_for_stat_error(err: std::io::Error, path: &Path) -> CheckoutEr } } -#[derive(Debug, Error)] -#[error("{message}: {err:?}")] -pub struct WorkingCopyStateError { - message: String, - err: Box, -} - /// Working copy state stored in "checkout" file. #[derive(Clone, Debug)] struct CheckoutState { @@ -1310,6 +1303,10 @@ impl WorkingCopy for LocalWorkingCopy { fn operation_id(&self) -> &OperationId { &self.checkout_state().operation_id } + + fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError> { + Ok(self.tree_state()?.sparse_patterns()) + } } impl LocalWorkingCopy { @@ -1430,10 +1427,6 @@ impl LocalWorkingCopy { Ok(self.tree_state()?.file_states()) } - pub fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError> { - Ok(self.tree_state()?.sparse_patterns()) - } - #[instrument(skip_all)] fn save(&mut self) { self.write_proto(crate::protos::working_copy::Checkout { @@ -1543,26 +1536,12 @@ impl LockedWorkingCopy for LockedLocalWorkingCopy { self.tree_state_dirty = true; Ok(()) } -} -impl LockedLocalWorkingCopy { - pub fn reset_watchman(&mut self) -> Result<(), SnapshotError> { - self.wc - .tree_state_mut() - .map_err(|err| SnapshotError::Other { - message: "Failed to read the working copy state".to_string(), - err: err.into(), - })? - .reset_watchman(); - self.tree_state_dirty = true; - Ok(()) - } - - pub fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError> { + fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError> { self.wc.sparse_patterns() } - pub fn set_sparse_patterns( + fn set_sparse_patterns( &mut self, new_sparse_patterns: Vec, ) -> Result { @@ -1579,6 +1558,20 @@ impl LockedLocalWorkingCopy { self.tree_state_dirty = true; Ok(stats) } +} + +impl LockedLocalWorkingCopy { + pub fn reset_watchman(&mut self) -> Result<(), SnapshotError> { + self.wc + .tree_state_mut() + .map_err(|err| SnapshotError::Other { + message: "Failed to read the working copy state".to_string(), + err: err.into(), + })? + .reset_watchman(); + self.tree_state_dirty = true; + Ok(()) + } #[instrument(skip_all)] pub fn finish( diff --git a/lib/src/working_copy.rs b/lib/src/working_copy.rs index 7561b7e20..191abeef3 100644 --- a/lib/src/working_copy.rs +++ b/lib/src/working_copy.rs @@ -47,6 +47,12 @@ pub trait WorkingCopy { /// The operation this working copy was most recently updated to. fn operation_id(&self) -> &OperationId; + + /// Patterns that decide which paths from the current tree should be checked + /// out in the working copy. An empty list means that no paths should be + /// checked out in the working copy. A single `RepoPath::root()` entry means + /// that all files should be checked out. + fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError>; } /// A working copy that's being modified. @@ -69,6 +75,20 @@ pub trait LockedWorkingCopy { /// Update to another tree without touching the files in the working copy. fn reset(&mut self, new_tree: &MergedTree) -> Result<(), ResetError>; + + /// See `WorkingCopy::sparse_patterns()` + fn sparse_patterns(&self) -> Result<&[RepoPath], WorkingCopyStateError>; + + /// Updates the patterns that decide which paths from the current tree + /// should be checked out in the working copy. + // TODO: Use a different error type here so we can include a + // `SparseNotSupported` variants for working copies that don't support sparse + // checkouts (e.g. because they use a virtual file system so there's no reason + // to use sparse). + fn set_sparse_patterns( + &mut self, + new_sparse_patterns: Vec, + ) -> Result; } /// An error while snapshotting the working copy. @@ -220,3 +240,13 @@ pub enum ResetError { err: Box, }, } + +/// An error while reading the working copy state. +#[derive(Debug, Error)] +#[error("{message}: {err:?}")] +pub struct WorkingCopyStateError { + /// Error message. + pub message: String, + /// The underlying error. + pub err: Box, +} diff --git a/lib/src/workspace.rs b/lib/src/workspace.rs index 5a46cb561..4dbf634dc 100644 --- a/lib/src/workspace.rs +++ b/lib/src/workspace.rs @@ -27,7 +27,7 @@ use crate::file_util::{self, IoResultExt as _, PathError}; use crate::git_backend::GitBackend; use crate::index::IndexStore; use crate::local_backend::LocalBackend; -use crate::local_working_copy::{LocalWorkingCopy, LockedLocalWorkingCopy, WorkingCopyStateError}; +use crate::local_working_copy::{LocalWorkingCopy, LockedLocalWorkingCopy}; use crate::merged_tree::MergedTree; use crate::op_heads_store::OpHeadsStore; use crate::op_store::{OpStore, OperationId, WorkspaceId}; @@ -37,7 +37,9 @@ use crate::repo::{ }; use crate::settings::UserSettings; use crate::submodule_store::SubmoduleStore; -use crate::working_copy::{CheckoutError, CheckoutStats, LockedWorkingCopy, WorkingCopy}; +use crate::working_copy::{ + CheckoutError, CheckoutStats, LockedWorkingCopy, WorkingCopy, WorkingCopyStateError, +}; #[derive(Error, Debug)] pub enum WorkspaceInitError { diff --git a/lib/tests/test_local_working_copy.rs b/lib/tests/test_local_working_copy.rs index 25f66802a..63d149cd3 100644 --- a/lib/tests/test_local_working_copy.rs +++ b/lib/tests/test_local_working_copy.rs @@ -34,7 +34,9 @@ use jj_lib::op_store::{OperationId, WorkspaceId}; use jj_lib::repo::{ReadonlyRepo, Repo}; use jj_lib::repo_path::{RepoPath, RepoPathComponent, RepoPathJoin}; use jj_lib::settings::UserSettings; -use jj_lib::working_copy::{CheckoutStats, LockedWorkingCopy, SnapshotError, SnapshotOptions}; +use jj_lib::working_copy::{ + CheckoutStats, LockedWorkingCopy, SnapshotError, SnapshotOptions, WorkingCopy, +}; use jj_lib::workspace::LockedWorkspace; use test_case::test_case; use testutils::{create_tree, write_random_commit, TestRepoBackend, TestWorkspace}; diff --git a/lib/tests/test_local_working_copy_sparse.rs b/lib/tests/test_local_working_copy_sparse.rs index 5399199ef..bab907e0a 100644 --- a/lib/tests/test_local_working_copy_sparse.rs +++ b/lib/tests/test_local_working_copy_sparse.rs @@ -17,7 +17,7 @@ use jj_lib::local_working_copy::LocalWorkingCopy; use jj_lib::matchers::EverythingMatcher; use jj_lib::repo::Repo; use jj_lib::repo_path::RepoPath; -use jj_lib::working_copy::{CheckoutStats, WorkingCopy}; +use jj_lib::working_copy::{CheckoutStats, LockedWorkingCopy, WorkingCopy}; use testutils::{create_tree, TestWorkspace}; #[test]