improve: show whole-diff totals alongside file stats

This commit is contained in:
Valdemar Lorenzen
2026-10-20 12:29:06 +02:00
parent a5a246db77
commit 759947736e
15 changed files with 394 additions and 48 deletions
+91
View File
@@ -275,6 +275,93 @@ fn comparison_revisions_freeze_commits_and_address_working_contents() {
}
}
#[test]
fn unopened_catalog_counts_frozen_text_but_not_binary_modes_or_exact_renames() {
let fixture = Fixture::new();
let root = fixture.dir("stats");
init_git(&root);
for (path, bytes) in [
("first", &b"old\nkeep\n"[..]),
("second", b"remove\nkeep\n"),
("removed", b"gone\n"),
("rename-old", b"move\n"),
("binary", b"\0old"),
("mode", b"script\n"),
("crlf", b"a\r\n"),
("eof", b"same\n"),
] {
fs::write(root.join(path), bytes).unwrap();
}
git(&root, &["add", "."]);
git(&root, &["commit", "-m", "before"]);
let before = revision(&git(&root, &["rev-parse", "HEAD"]), RepoKind::Git);
for (path, bytes) in [
("first", &b"new\nextra\nkeep\n"[..]),
("second", b"keep\n"),
("added", b"one\nlast"),
("binary", b"\0new"),
("crlf", b"b\r\n"),
("eof", b"same"),
] {
fs::write(root.join(path), bytes).unwrap();
}
fs::remove_file(root.join("removed")).unwrap();
fs::rename(root.join("rename-old"), root.join("-renamed\t\n")).unwrap();
fs::set_permissions(root.join("mode"), fs::Permissions::from_mode(0o755)).unwrap();
let mut repository = open(&root);
let catalog = repository
.compare(
1,
&before,
&working(RepoKind::Git),
ComparisonMode::Snapshots,
&[],
)
.unwrap();
assert!(catalog.files.iter().all(|file| !file.loaded
&& file.before.is_empty()
&& file.after.is_empty()
&& file.hunks.is_empty()));
for (path, counts) in [
("first", (2, 1)),
("second", (0, 1)),
("added", (2, 0)),
("removed", (0, 1)),
("-renamed\t\n", (0, 0)),
("binary", (0, 0)),
("mode", (0, 0)),
("crlf", (1, 1)),
("eof", (1, 1)),
] {
assert_eq!(
changed(&catalog, Path::new(path)).stats,
Some(counts),
"{path}"
);
}
assert_eq!(
changed(&catalog, Path::new("-renamed\t\n")).status,
FileStatus::Renamed
);
fs::write(root.join("second"), "changed after freezing\n").unwrap();
for (index, file) in catalog.files.iter().enumerate() {
let loaded = repository.load_file(1, index).unwrap();
let counts = loaded.hunks.iter().fold((0, 0), |(added, removed), hunk| {
(added + hunk.after_len, removed + hunk.before_len)
});
assert_eq!(file.stats, Some(counts), "{}", file.path.display());
}
git(&root, &["add", "-A"]);
git(&root, &["commit", "-m", "advance checkout"]);
let refreshed = repository
.refresh_checkout(1, 2, true, &[])
.unwrap()
.map(checkout_comparison)
.unwrap();
assert_eq!(changed(&refreshed, Path::new("first")).stats, Some((2, 1)));
assert_eq!(changed(&refreshed, Path::new("second")).stats, Some((1, 2)));
}
#[test]
fn git_working_reads_disk_and_handles_ranges_ignored_files_binary_links_and_odd_paths() {
let fixture = Fixture::new();
@@ -1710,6 +1797,8 @@ fn jj_conflicted_revisions_show_cli_projection_and_keep_ordinary_files_navigable
&[],
)
.unwrap();
assert_eq!(changed(&branch, Path::new("conflict")).stats, None);
assert_eq!(changed(&branch, Path::new("ordinary")).stats, Some((1, 1)));
let index = branch
.files
.iter()
@@ -2003,6 +2092,8 @@ fn comparison_size_and_line_ceilings_are_lazy_and_explicit() {
.unwrap();
assert_eq!(catalog.files.len(), 3);
assert!(catalog.files.iter().all(|file| !file.loaded));
assert_eq!(changed(&catalog, Path::new("too-many-bytes")).stats, None);
assert_eq!(changed(&catalog, Path::new("selected")).stats, Some((1, 0)));
for (index, entry) in catalog.files.iter().enumerate() {
match entry.path.to_str().unwrap() {
"selected" => assert_eq!(