mirror of
https://github.com/martinvonz/jj.git
synced 2025-05-30 19:32:39 +00:00
working_copy: extract visit_directory
function for snapshotting
This commit is contained in:
parent
515fb02049
commit
174704d752
@ -51,6 +51,7 @@ use crate::op_store::{OperationId, WorkspaceId};
|
||||
use crate::repo_path::{FsPathParseError, RepoPath, RepoPathComponent, RepoPathJoin};
|
||||
use crate::store::Store;
|
||||
use crate::tree::{Diff, Tree};
|
||||
use crate::tree_builder::TreeBuilder;
|
||||
|
||||
#[cfg(unix)]
|
||||
type FileExecutableFlag = bool;
|
||||
@ -654,23 +655,56 @@ impl TreeState {
|
||||
git_ignore: base_ignores,
|
||||
}];
|
||||
trace_span!("traverse filesystem").in_scope(|| -> Result<(), SnapshotError> {
|
||||
while let Some(WorkItem {
|
||||
while let Some(work_item) = work.pop() {
|
||||
work.extend(self.visit_directory(
|
||||
&matcher,
|
||||
¤t_tree,
|
||||
&mut tree_builder,
|
||||
&mut deleted_files,
|
||||
work_item,
|
||||
progress,
|
||||
)?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
for file in &deleted_files {
|
||||
self.file_states.remove(file);
|
||||
tree_builder.remove(file.clone());
|
||||
}
|
||||
let has_changes = tree_builder.has_overrides();
|
||||
self.tree_id = tree_builder.write_tree();
|
||||
self.watchman_clock = watchman_clock;
|
||||
Ok(has_changes || fsmonitor_clock_needs_save)
|
||||
}
|
||||
|
||||
fn visit_directory(
|
||||
&mut self,
|
||||
matcher: &dyn Matcher,
|
||||
current_tree: &Tree,
|
||||
tree_builder: &mut TreeBuilder,
|
||||
deleted_files: &mut HashSet<RepoPath>,
|
||||
work_item: WorkItem,
|
||||
progress: Option<&SnapshotProgress>,
|
||||
) -> Result<Vec<WorkItem>, SnapshotError> {
|
||||
let WorkItem {
|
||||
dir,
|
||||
disk_dir,
|
||||
git_ignore,
|
||||
}) = work.pop()
|
||||
{
|
||||
} = work_item;
|
||||
|
||||
if matcher.visit(&dir).is_nothing() {
|
||||
continue;
|
||||
return Ok(Default::default());
|
||||
}
|
||||
let git_ignore = git_ignore
|
||||
.chain_with_file(&dir.to_internal_dir_string(), disk_dir.join(".gitignore"));
|
||||
let git_ignore =
|
||||
git_ignore.chain_with_file(&dir.to_internal_dir_string(), disk_dir.join(".gitignore"));
|
||||
let mut work = Vec::new();
|
||||
for maybe_entry in disk_dir.read_dir().unwrap() {
|
||||
let entry = maybe_entry.unwrap();
|
||||
let file_type = entry.file_type().unwrap();
|
||||
let file_name = entry.file_name();
|
||||
let name =
|
||||
file_name
|
||||
let name = file_name
|
||||
.to_str()
|
||||
.ok_or_else(|| SnapshotError::InvalidUtf8Path {
|
||||
path: file_name.clone(),
|
||||
@ -693,9 +727,7 @@ impl TreeState {
|
||||
.file_states
|
||||
.range((Bound::Excluded(&path), Bound::Unbounded))
|
||||
.take_while(|(sub_path, _)| path.contains(sub_path))
|
||||
.map(|(sub_path, file_state)| {
|
||||
(sub_path.clone(), file_state.clone())
|
||||
})
|
||||
.map(|(sub_path, file_state)| (sub_path.clone(), file_state.clone()))
|
||||
.collect_vec();
|
||||
for (tracked_path, current_file_state) in tracked_paths {
|
||||
if !matcher.matches(&tracked_path) {
|
||||
@ -709,10 +741,7 @@ impl TreeState {
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(SnapshotError::IoError {
|
||||
message: format!(
|
||||
"Failed to stat file {}",
|
||||
disk_path.display()
|
||||
),
|
||||
message: format!("Failed to stat file {}", disk_path.display()),
|
||||
err,
|
||||
});
|
||||
}
|
||||
@ -723,7 +752,7 @@ impl TreeState {
|
||||
&tracked_path,
|
||||
disk_path,
|
||||
Some(¤t_file_state),
|
||||
¤t_tree,
|
||||
current_tree,
|
||||
&new_file_state,
|
||||
)?;
|
||||
if let Some(tree_value) = update {
|
||||
@ -751,12 +780,8 @@ impl TreeState {
|
||||
// the ignored paths, then
|
||||
// ignore it.
|
||||
} else {
|
||||
let metadata =
|
||||
entry.metadata().map_err(|err| SnapshotError::IoError {
|
||||
message: format!(
|
||||
"Failed to stat file {}",
|
||||
entry.path().display()
|
||||
),
|
||||
let metadata = entry.metadata().map_err(|err| SnapshotError::IoError {
|
||||
message: format!("Failed to stat file {}", entry.path().display()),
|
||||
err,
|
||||
})?;
|
||||
if let Some(new_file_state) = file_state(&metadata) {
|
||||
@ -765,7 +790,7 @@ impl TreeState {
|
||||
&path,
|
||||
entry.path(),
|
||||
maybe_current_file_state,
|
||||
¤t_tree,
|
||||
current_tree,
|
||||
&new_file_state,
|
||||
)?;
|
||||
if let Some(tree_value) = update {
|
||||
@ -776,18 +801,7 @@ impl TreeState {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
for file in &deleted_files {
|
||||
self.file_states.remove(file);
|
||||
tree_builder.remove(file.clone());
|
||||
}
|
||||
let has_changes = tree_builder.has_overrides();
|
||||
self.tree_id = tree_builder.write_tree();
|
||||
self.watchman_clock = watchman_clock;
|
||||
Ok(has_changes || fsmonitor_clock_needs_save)
|
||||
Ok(work)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user