| 402 | } |
| 403 | |
| 404 | pub(super) fn build_git_import_file_diffs( |
| 405 | change: &Change, |
| 406 | ) -> Option<(Vec<FileDiff>, DiffStats)> { |
| 407 | let diff_files_value = change |
| 408 | .unhashed |
| 409 | .as_ref()? |
| 410 | .get("git")? |
| 411 | .get("diff_lines")? |
| 412 | .clone(); |
| 413 | |
| 414 | let diff_files: Vec<GitMetadataDiffFile> = serde_json::from_value(diff_files_value).ok()?; |
| 415 | let mut file_diffs = Vec::new(); |
| 416 | let mut stats = DiffStats::new(); |
| 417 | |
| 418 | for entry in diff_files { |
| 419 | let mut insertions = 0usize; |
| 420 | let mut deletions = 0usize; |
| 421 | let mut hunk_lines = Vec::new(); |
| 422 | let mut old_start = None; |
| 423 | let mut new_start = None; |
| 424 | |
| 425 | for line in entry.lines { |
| 426 | let content = String::from_utf8_lossy(&line.content) |
| 427 | .trim_end_matches('\n') |
| 428 | .to_string(); |
| 429 | match line.origin { |
| 430 | '+' => { |
| 431 | let new_num = line.new_lineno.unwrap_or((insertions + 1) as u32) as usize; |
| 432 | if new_start.is_none() { |
| 433 | new_start = Some(new_num); |
| 434 | } |
| 435 | hunk_lines.push(HunkLine::added(content, new_num)); |
| 436 | insertions += 1; |
| 437 | } |
| 438 | '-' => { |
| 439 | let old_num = line.old_lineno.unwrap_or((deletions + 1) as u32) as usize; |
| 440 | if old_start.is_none() { |
| 441 | old_start = Some(old_num); |
| 442 | } |
| 443 | hunk_lines.push(HunkLine::removed(content, old_num)); |
| 444 | deletions += 1; |
| 445 | } |
| 446 | _ => {} |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | if hunk_lines.is_empty() { |
| 451 | continue; |
| 452 | } |
| 453 | |
| 454 | let status = match (insertions > 0, deletions > 0) { |
| 455 | (true, false) => FileChangeStatus::Added, |
| 456 | (false, true) => FileChangeStatus::Deleted, |
| 457 | _ => FileChangeStatus::Modified, |
| 458 | }; |
| 459 | |
| 460 | let mut file_diff = match status { |
| 461 | FileChangeStatus::Added => FileDiff::added(&entry.path), |