Record a single added file from the working copy. Reads the file content and creates appropriate hunks for a new file. # Arguments `working_copy` - Working copy interface `detected` - The detected file `options` - Recording options # Returns A `RecordedFile` with the file's hunks and content. # Example ```rust,ignore use atomic_core::record::workflow::record::{record_added_file, RecordingOp
(
working_copy: &W,
detected: &DetectedFile,
options: &RecordingOptions,
)
| 214 | /// let recorded = record_added_file(&working_copy, &detected_file, &options)?; |
| 215 | /// ``` |
| 216 | pub fn record_added_file<W>( |
| 217 | working_copy: &W, |
| 218 | detected: &DetectedFile, |
| 219 | options: &RecordingOptions, |
| 220 | ) -> Result<RecordedFile, String> |
| 221 | where |
| 222 | W: WorkingCopyRead, |
| 223 | { |
| 224 | let mut recorded = RecordedFile::new(&detected.path); |
| 225 | recorded.set_kind(DetectionKind::Added); |
| 226 | |
| 227 | // Read content from working copy |
| 228 | let mut content = Vec::new(); |
| 229 | if let Err(e) = working_copy.read_file(&detected.path, &mut content) { |
| 230 | return Err(format!("Failed to read file {}: {}", detected.path, e)); |
| 231 | } |
| 232 | |
| 233 | // Check size limits |
| 234 | if options.exceeds_max_size(content.len()) { |
| 235 | return Err(format!( |
| 236 | "File {} exceeds maximum size ({} bytes)", |
| 237 | detected.path, |
| 238 | content.len() |
| 239 | )); |
| 240 | } |
| 241 | |
| 242 | // Skip empty files if configured |
| 243 | if content.is_empty() && !options.get_record_empty_files() { |
| 244 | return Err(format!("Skipping empty file {}", detected.path)); |
| 245 | } |
| 246 | |
| 247 | // Detect encoding |
| 248 | let encoding = detect_encoding(&content); |
| 249 | recorded.set_encoding(encoding); |
| 250 | |
| 251 | // Skip binary files if configured |
| 252 | if encoding == Encoding::Binary && options.get_skip_binary() { |
| 253 | return Err(format!("Skipping binary file {}", detected.path)); |
| 254 | } |
| 255 | |
| 256 | // Create an edit graph_op for the new content |
| 257 | let local = Local::new(&detected.path, 1); |
| 258 | let content_len = content.len() as u64; |
| 259 | let graph_op = BuiltHunk::new_edit(local, Some(encoding), 0, content_len); |
| 260 | recorded.add_hunk(graph_op); |
| 261 | |
| 262 | // Build the CRDT (Trunk → Branch → Leaf) operations for the new file so |
| 263 | // the semantic layer (token-level diff / blame) is populated, matching |
| 264 | // the modified-file path. |
| 265 | let (crdt_ops, crdt_stats) = |
| 266 | crdt::build_crdt_ops_for_added_file(&detected.path, &content, encoding); |
| 267 | recorded.set_crdt_ops(crdt_ops); |
| 268 | recorded.set_crdt_stats(crdt_stats); |
| 269 | |
| 270 | // Store the content |
| 271 | recorded.set_content(content); |
| 272 | |
| 273 | Ok(recorded) |