MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / change_file_diffs

Function change_file_diffs

atomic-cli/src/commands/diff/helpers.rs:886–1038  ·  view source on GitHub ↗

Build the real per-file unified diff for a recorded change WITHOUT printing. This is the computation `atomic diff -c ` runs, factored out so other surfaces (e.g. the triage report) can embed actual code hunks instead of re-implementing diffing. It returns every changed file's [`FileDiff`] plus the aggregate [`DiffStats`], using the semantic layer (FileOps) with true hunk offsets and before-

(
    repo: &Repository,
    change: &Change,
    change_hash: &Hash,
    config: &DiffOutputConfig,
)

Source from the content-addressed store, hash-verified

884/// `atomic diff` path applies `filter_file_diffs` afterward, which yields the
885/// same result as the previous in-loop filtering.
886pub(crate) fn change_file_diffs(
887 repo: &Repository,
888 change: &Change,
889 change_hash: &Hash,
890 config: &DiffOutputConfig,
891) -> CliResult<(Vec<FileDiff>, DiffStats)> {
892 // Git-imported changes carry Git's captured +/- lines in unhashed metadata.
893 if let Some((file_diffs, stats)) = Diff::build_git_import_file_diffs(change) {
894 return Ok((file_diffs, stats));
895 }
896
897 let file_ops = change.file_ops();
898
899 let mut file_diffs = Vec::new();
900 let mut stats = DiffStats::new();
901
902 for ops in file_ops {
903 let file_path = ops.path();
904
905 let trunk_op = ops.trunk_op();
906 let line_ops = ops.line_ops();
907
908 // Determine file change status from trunk operation
909 let change_status = match trunk_op {
910 Some(TrunkOp::Create { .. }) => FileChangeStatus::Added,
911 Some(TrunkOp::Delete { .. }) => FileChangeStatus::Deleted,
912 Some(TrunkOp::Move { .. }) => FileChangeStatus::Renamed,
913 Some(TrunkOp::Undelete { .. }) => FileChangeStatus::Modified,
914 None => FileChangeStatus::Modified,
915 };
916
917 let mut file_diff = match change_status {
918 FileChangeStatus::Added => FileDiff::added(file_path),
919 FileChangeStatus::Deleted => FileDiff::deleted(file_path),
920 FileChangeStatus::Renamed => FileDiff::modified(file_path),
921 _ => FileDiff::modified(file_path),
922 };
923
924 // Pass 1: flatten line operations into numbered changed lines.
925 let mut insertions = 0usize;
926 let mut deletions = 0usize;
927 let mut new_line_num = 1usize;
928 let mut old_line_num = 1usize;
929 let mut net: isize = 0;
930 let mut changed: Vec<NumberedLine> = Vec::new();
931
932 for line_op in line_ops {
933 match line_op.operation() {
934 BranchOp::Insert { content, .. } => {
935 let line_content = Diff::reconstruct_line_from_leaf_ops(content);
936 let line_num = line_op.new_line_num().unwrap_or(new_line_num);
937 changed.push(NumberedLine::added(line_content, line_num, net));
938 new_line_num = line_num + 1;
939 insertions += 1;
940 net += 1;
941 }
942 BranchOp::Delete { content, .. } => {
943 let line_content = if content.is_empty() {

Callers 2

build_change_diffFunction · 0.85

Calls 15

addedFunction · 0.85
deletedFunction · 0.85
modifiedFunction · 0.85
is_git_import_changeFunction · 0.85
file_opsMethod · 0.45
pathMethod · 0.45
trunk_opMethod · 0.45
line_opsMethod · 0.45
operationMethod · 0.45
new_line_numMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected