Show diff using the semantic layer (FileOps). This is the preferred path - it displays line-level and token-level changes directly from the stored CRDT operations, without recomputing.
(
&self,
change: &Change,
change_hash: &Hash,
config: &DiffOutputConfig,
)
| 70 | /// This is the preferred path - it displays line-level and token-level |
| 71 | /// changes directly from the stored CRDT operations, without recomputing. |
| 72 | fn show_change_diff_from_file_ops( |
| 73 | &self, |
| 74 | change: &Change, |
| 75 | change_hash: &Hash, |
| 76 | config: &DiffOutputConfig, |
| 77 | ) -> CliResult<()> { |
| 78 | if let Some((file_diffs, stats)) = Self::build_git_import_file_diffs(change) { |
| 79 | if file_diffs.is_empty() { |
| 80 | self.print_no_changes(); |
| 81 | return Ok(()); |
| 82 | } |
| 83 | |
| 84 | if config.format == DiffFormat::Unified { |
| 85 | self.print_change_header(change, change_hash, config); |
| 86 | } |
| 87 | |
| 88 | return match config.format { |
| 89 | DiffFormat::Unified => self.print_unified(&file_diffs, config), |
| 90 | DiffFormat::Stat => self.print_stat(&stats, config), |
| 91 | DiffFormat::NameOnly => self.print_name_only(&file_diffs), |
| 92 | DiffFormat::NameStatus => self.print_name_status(&file_diffs, config), |
| 93 | }; |
| 94 | } |
| 95 | |
| 96 | let file_ops = change.file_ops(); |
| 97 | |
| 98 | if file_ops.is_empty() { |
| 99 | self.print_no_changes(); |
| 100 | return Ok(()); |
| 101 | } |
| 102 | |
| 103 | let mut file_diffs = Vec::new(); |
| 104 | let mut stats = DiffStats::new(); |
| 105 | |
| 106 | for ops in file_ops { |
| 107 | let file_path = ops.path(); |
| 108 | let trunk_op = ops.trunk_op(); |
| 109 | let line_ops = ops.line_ops(); |
| 110 | |
| 111 | // Determine file change status from trunk operation |
| 112 | let change_status = match trunk_op { |
| 113 | Some(TrunkOp::Create { .. }) => FileChangeStatus::Added, |
| 114 | Some(TrunkOp::Delete { .. }) => FileChangeStatus::Deleted, |
| 115 | Some(TrunkOp::Move { .. }) => FileChangeStatus::Renamed, |
| 116 | Some(TrunkOp::Undelete { .. }) => FileChangeStatus::Modified, |
| 117 | None => FileChangeStatus::Modified, |
| 118 | }; |
| 119 | |
| 120 | let mut file_diff = match change_status { |
| 121 | FileChangeStatus::Added => FileDiff::added(file_path), |
| 122 | FileChangeStatus::Deleted => FileDiff::deleted(file_path), |
| 123 | FileChangeStatus::Renamed => FileDiff::modified(file_path), |
| 124 | _ => FileDiff::modified(file_path), |
| 125 | }; |
| 126 | |
| 127 | // Build hunks from line operations |
| 128 | let mut insertions = 0usize; |
| 129 | let mut deletions = 0usize; |
no test coverage detected