Materialize the repository view (or prefix) to the working copy. This is the main entry point for synchronizing the working copy with the repository graph state. It traverses the tree, outputs each file, and collects all conflicts.
(
txn: &T,
changes: &C,
working_copy: &W,
options: MaterializeOptions,
)
| 203 | /// the repository graph state. It traverses the tree, outputs each file, |
| 204 | /// and collects all conflicts. |
| 205 | pub fn materialize_view<T, C, W>( |
| 206 | txn: &T, |
| 207 | changes: &C, |
| 208 | working_copy: &W, |
| 209 | options: MaterializeOptions, |
| 210 | ) -> Result<MaterializeResult, MaterializeError<W::Error>> |
| 211 | where |
| 212 | T: TreeTxnT + GraphTxnT, |
| 213 | C: ChangeStore, |
| 214 | W: WorkingCopy, |
| 215 | W::Writer: std::io::Write, |
| 216 | { |
| 217 | let mut result = MaterializeResult::new(); |
| 218 | |
| 219 | // Collect items to output starting from root |
| 220 | let items = collect_children(txn, Inode::ROOT, "", &options)?; |
| 221 | |
| 222 | // Process each item |
| 223 | let file_options = options.to_file_options(); |
| 224 | |
| 225 | // ── View-aware pre-filter ────────────────────────────────────── |
| 226 | let (passing_file_paths, passing_ancestors) = |
| 227 | filter::compute_filters(&items, &options.change_filter); |
| 228 | |
| 229 | for item in items { |
| 230 | if item.is_directory { |
| 231 | // Only create directories that will contain files on this view |
| 232 | if !filter::dir_has_passing_children(&item.path, &passing_ancestors) { |
| 233 | result.record_skipped(); |
| 234 | continue; |
| 235 | } |
| 236 | // Selective materialize: skip directories with no target files. |
| 237 | if let Some(ref paths) = options.only_paths { |
| 238 | let has_target = paths.iter().any(|p| p.starts_with(&item.path)); |
| 239 | if !has_target { |
| 240 | result.record_skipped(); |
| 241 | continue; |
| 242 | } |
| 243 | } |
| 244 | // Create directory |
| 245 | working_copy |
| 246 | .create_dir_all(&item.path) |
| 247 | .map_err(MaterializeError::WorkingCopy)?; |
| 248 | result.record_directory(); |
| 249 | } else { |
| 250 | // Check prefix filter |
| 251 | if !options.matches_prefix(&item.path) { |
| 252 | result.record_skipped(); |
| 253 | continue; |
| 254 | } |
| 255 | |
| 256 | // Selective materialize: skip files not in the explicit path set. |
| 257 | if let Some(ref paths) = options.only_paths { |
| 258 | if !paths.contains(&item.path) { |
| 259 | result.record_skipped(); |
| 260 | continue; |
| 261 | } |
| 262 | } |
no test coverage detected