This is the main entry point for creating a change from working copy modifications. It detects changes, creates hunks, globalizes positions, and assembles a complete change. # Arguments `header` - The change header (message, author, etc.) `options` - Options controlling recording behavior # Returns A `RecordOutcome` containing the recorded change, hash, and statistics. # Errors Returns an er
(
&self,
header: ChangeHeader,
options: RecordOptions,
)
| 43 | /// println!("Created change: {}", result.hash().to_base32()); |
| 44 | /// ``` |
| 45 | pub fn record( |
| 46 | &self, |
| 47 | header: ChangeHeader, |
| 48 | options: RecordOptions, |
| 49 | ) -> Result<RecordOutcome, RecordError> { |
| 50 | let trace_record = std::env::var_os("ATOMIC_TRACE_RECORD").is_some(); |
| 51 | use atomic_core::output::Memory; |
| 52 | use atomic_core::record::workflow::{ |
| 53 | assemble_change, record_added_file, record_deleted_file, record_modified_file, |
| 54 | DetectedFile, RecordedFile, |
| 55 | }; |
| 56 | |
| 57 | // Build the final header (may get message from options) |
| 58 | let final_header = build_header(header, &options); |
| 59 | |
| 60 | // Get repository status to find modified files |
| 61 | let status_t0 = std::time::Instant::now(); |
| 62 | let status = self |
| 63 | .status(StatusOptions::default()) |
| 64 | .map_err(RecordError::Repository)?; |
| 65 | if trace_record { |
| 66 | eprintln!( |
| 67 | "[record] status: {:.1}ms ({} entries)", |
| 68 | status_t0.elapsed().as_secs_f64() * 1000.0, |
| 69 | status.entries().len(), |
| 70 | ); |
| 71 | } |
| 72 | |
| 73 | log::debug!( |
| 74 | "record: status returned {} entries (modified={}, added={}, deleted={}, clean={}, untracked={})", |
| 75 | status.entries().len(), |
| 76 | status.modified_count(), |
| 77 | status.added_count(), |
| 78 | status.deleted_count(), |
| 79 | status.entries().iter().filter(|e| e.status() == FileStatus::Clean).count(), |
| 80 | status.untracked_count(), |
| 81 | ); |
| 82 | |
| 83 | // Filter to recordable files |
| 84 | let files_to_record = filter_files(status.entries(), &options); |
| 85 | |
| 86 | log::debug!( |
| 87 | "record: filter_files returned {} recordable files", |
| 88 | files_to_record.len(), |
| 89 | ); |
| 90 | for f in &files_to_record { |
| 91 | log::debug!("record: {:?} {}", f.status(), f.path().display(),); |
| 92 | } |
| 93 | |
| 94 | if files_to_record.is_empty() { |
| 95 | return Err(RecordError::NothingToRecord); |
| 96 | } |
| 97 | |
| 98 | // Statistics tracking |
| 99 | let mut stats = RecordStats::new(); |
| 100 | let mut recorded_files: Vec<RecordedFile> = Vec::new(); |
| 101 | let mut recorded_paths: Vec<String> = Vec::new(); |
| 102 | let mut deleted_paths: Vec<String> = Vec::new(); |