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

working_copy: make set_sparse_patterns() ignore existing working copy files

This doesn't work yet since write_file() overwrites the existing file, which
will be fixed by the next patch.

I've added a callback parameter to update() just because that's the easiest
option. If we want to report the number of the conflicting files (through
CheckoutStats), the callback interface wouldn't work nicely and the error
handling would have to be moved to the update() body. If we want to make
both check_out() and set_sparse_patterns() ignore EEXIST error, we can
eliminate the calback parameter at all.
This commit is contained in:
Yuya Nishihara 2022-08-07 10:35:19 +09:00 committed by Martin von Zweigbergk
parent f1df8215a2
commit b149cb07cc

View file

@ -281,6 +281,15 @@ impl CheckoutError {
}
}
fn suppress_file_exists_error(orig_err: CheckoutError) -> Result<(), CheckoutError> {
match orig_err {
CheckoutError::IoError { err, .. } if err.kind() == std::io::ErrorKind::AlreadyExists => {
Ok(())
}
_ => Err(orig_err),
}
}
#[derive(Debug, Error, PartialEq, Eq)]
pub enum ResetError {
// The current checkout was deleted, maybe by an overly aggressive GC that happened while
@ -748,7 +757,7 @@ impl TreeState {
BackendError::NotFound => CheckoutError::SourceNotFound,
other => CheckoutError::InternalBackendError(other),
})?;
let stats = self.update(&old_tree, new_tree, self.sparse_matcher().as_ref())?;
let stats = self.update(&old_tree, new_tree, self.sparse_matcher().as_ref(), Err)?;
self.tree_id = new_tree.id().clone();
Ok(stats)
}
@ -769,8 +778,13 @@ impl TreeState {
let added_matcher = DifferenceMatcher::new(&new_matcher, &old_matcher);
let removed_matcher = DifferenceMatcher::new(&old_matcher, &new_matcher);
let empty_tree = Tree::null(self.store.clone(), RepoPath::root());
let added_stats = self.update(&empty_tree, &tree, &added_matcher)?;
let removed_stats = self.update(&tree, &empty_tree, &removed_matcher)?;
let added_stats = self.update(
&empty_tree,
&tree,
&added_matcher,
suppress_file_exists_error, // Keep un-ignored file and mark it as modified
)?;
let removed_stats = self.update(&tree, &empty_tree, &removed_matcher, Err)?;
self.sparse_patterns = sparse_patterns;
assert_eq!(added_stats.updated_files, 0);
assert_eq!(added_stats.removed_files, 0);
@ -788,6 +802,7 @@ impl TreeState {
old_tree: &Tree,
new_tree: &Tree,
matcher: &dyn Matcher,
mut handle_error: impl FnMut(CheckoutError) -> Result<(), CheckoutError>,
) -> Result<CheckoutStats, CheckoutError> {
let mut stats = CheckoutStats {
updated_files: 0,
@ -873,7 +888,7 @@ impl TreeState {
};
for (path, diff) in old_tree.diff(new_tree, matcher) {
apply_diff(path, diff)?;
apply_diff(path, diff).or_else(&mut handle_error)?;
}
Ok(stats)
}