fix: show revision-aware blame in diff buffers
Diff and snapshot sources were excluded before scheduling, and the separate diff renderer never painted attribution. Capture per-side Git provenance, preserve private object stores for historical tabs, and reuse the current-line worker and cache.
This commit is contained in:
+71
-1
@@ -226,6 +226,13 @@ fn comparison_revisions_freeze_commits_and_address_working_contents() {
|
||||
.unwrap();
|
||||
assert_eq!(first.revisions[0], id);
|
||||
assert!(first.revisions[1].starts_with("working:"));
|
||||
assert_eq!(first.blame[0].as_ref().unwrap().commit, id);
|
||||
assert_eq!(
|
||||
first.blame[1]
|
||||
.as_ref()
|
||||
.map(|baseline| baseline.commit.as_str()),
|
||||
(kind == RepoKind::Git).then_some(id.as_str())
|
||||
);
|
||||
let reopened = open(&root)
|
||||
.compare(2, &before, &after, ComparisonMode::Snapshots, &[])
|
||||
.unwrap();
|
||||
@@ -255,6 +262,10 @@ fn comparison_revisions_freeze_commits_and_address_working_contents() {
|
||||
.unwrap();
|
||||
assert_eq!(working_pair.revisions[0], first.revisions[1]);
|
||||
assert_eq!(working_pair.revisions[0], working_pair.revisions[1]);
|
||||
assert_eq!(
|
||||
working_pair.blame,
|
||||
[first.blame[1].clone(), first.blame[1].clone()]
|
||||
);
|
||||
assert_eq!(disk_state(&root), state);
|
||||
fs::write(root.join("file"), "working").unwrap();
|
||||
let no_newline = repository
|
||||
@@ -785,6 +796,8 @@ fn jj_bookmark_refresh_tracks_movement_and_same_change_rewrites_without_touching
|
||||
panic!("Bookmark movement must replace contents even when follow is disabled");
|
||||
};
|
||||
assert_eq!(comparison.after, topic.label);
|
||||
assert!(comparison.blame[0].is_none());
|
||||
assert_eq!(comparison.blame[1].as_ref().unwrap().commit, next);
|
||||
assert_eq!(repository.load_file(2, 0).unwrap().after, ["next"]);
|
||||
assert!(repository.load_file(1, 0).is_err());
|
||||
assert!(
|
||||
@@ -944,6 +957,8 @@ fn jj_bookmark_refresh_recomputes_branch_merge_base_and_recovers_after_deletion(
|
||||
.unwrap();
|
||||
assert!(original.before.ends_with(&base));
|
||||
assert_eq!(original.revisions, [base.clone(), tip.clone()]);
|
||||
assert_eq!(original.blame[0].as_ref().unwrap().commit, base);
|
||||
assert_eq!(original.blame[1].as_ref().unwrap().commit, tip);
|
||||
jj(&root, &["bookmark", "set", "before", "-r", &tip]);
|
||||
let Some(CheckoutRefresh::Bookmark(comparison)) =
|
||||
repository.refresh_checkout(1, 2, false, &[]).unwrap()
|
||||
@@ -952,6 +967,8 @@ fn jj_bookmark_refresh_recomputes_branch_merge_base_and_recovers_after_deletion(
|
||||
};
|
||||
assert!(comparison.before.ends_with(&tip));
|
||||
assert_eq!(comparison.revisions, [tip.clone(), tip.clone()]);
|
||||
assert_eq!(comparison.blame[0].as_ref().unwrap().commit, tip);
|
||||
assert_eq!(comparison.blame[1].as_ref().unwrap().commit, tip);
|
||||
assert!(comparison.files.is_empty());
|
||||
jj(&root, &["bookmark", "delete", "after"]);
|
||||
let state = disk_state(&root);
|
||||
@@ -1331,6 +1348,7 @@ fn jj_private_fetch_discovers_never_fetched_bookmark_and_searchable_remote_chang
|
||||
.unwrap();
|
||||
assert_eq!(promoted.before, branch.before);
|
||||
assert_eq!(promoted.after, branch.after);
|
||||
assert_eq!(promoted.blame, branch.blame);
|
||||
assert!(promoted.editable_paths.contains(Path::new("file")));
|
||||
assert_eq!(repository.load_file(62, 0).unwrap().after, ["remote tip"]);
|
||||
assert_eq!(disk_state(&active), checked_out_state);
|
||||
@@ -2260,6 +2278,8 @@ fn git_working_after_advances_only_to_descendants_with_new_paths_and_unsaved_tex
|
||||
.unwrap();
|
||||
assert_eq!(refreshed.before, original.before);
|
||||
assert_eq!(refreshed.after, original.after);
|
||||
assert_eq!(refreshed.blame[0], original.blame[0]);
|
||||
assert_eq!(refreshed.blame[1].as_ref().unwrap().commit, tip);
|
||||
for (index, file) in refreshed.files.iter_mut().enumerate() {
|
||||
*file = repository.load_file(2, index).unwrap();
|
||||
}
|
||||
@@ -2526,13 +2546,14 @@ fn jj_working_after_follows_changes_not_rewrites_and_rejects_other_history() {
|
||||
jj(&root, &["new"]);
|
||||
fs::write(root.join("file"), "original disk\n").unwrap();
|
||||
let mut repository = open(&root);
|
||||
compare_loaded(
|
||||
let initial = compare_loaded(
|
||||
&mut repository,
|
||||
&revision(&base, RepoKind::Jujutsu),
|
||||
&working(RepoKind::Jujutsu),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(initial.blame[1].as_ref().unwrap().commit, base);
|
||||
fs::write(root.join("file"), "same-change rewrite\n").unwrap();
|
||||
jj(&root, &["describe", "-m", "rewritten"]);
|
||||
let state = disk_state(&root);
|
||||
@@ -2545,6 +2566,7 @@ fn jj_working_after_follows_changes_not_rewrites_and_rejects_other_history() {
|
||||
assert_eq!(repository.load_file(1, 0).unwrap().after, ["original disk"]);
|
||||
assert_eq!(disk_state(&root), state);
|
||||
jj(&root, &["new"]);
|
||||
let parent = jj(&root, &["log", "--no-graph", "-r", "@-", "-T", "commit_id"]);
|
||||
fs::remove_file(root.join("removed")).unwrap();
|
||||
fs::write(root.join("added"), "new file\n").unwrap();
|
||||
let state = disk_state(&root);
|
||||
@@ -2553,6 +2575,8 @@ fn jj_working_after_follows_changes_not_rewrites_and_rejects_other_history() {
|
||||
.unwrap()
|
||||
.map(checkout_comparison)
|
||||
.unwrap();
|
||||
assert_eq!(comparison.blame[0], initial.blame[0]);
|
||||
assert_eq!(comparison.blame[1].as_ref().unwrap().commit, parent);
|
||||
for (index, file) in comparison.files.iter_mut().enumerate() {
|
||||
*file = repository.load_file(2, index).unwrap();
|
||||
}
|
||||
@@ -2727,12 +2751,16 @@ fn branch_changes_resolves_local_and_private_remote_ancestry_without_active_muta
|
||||
assert_eq!(branch.files.len(), 1);
|
||||
assert_eq!(branch.files[0].path, Path::new("remote-only"));
|
||||
assert!(branch.before.ends_with(&base));
|
||||
assert_eq!(branch.blame[0].as_ref().unwrap().commit, base);
|
||||
assert!(!branch.blame[1].as_ref().unwrap().store.starts_with(&active));
|
||||
assert_eq!(repository.load_file(40, 0).unwrap().after, ["remote"]);
|
||||
let reverse = repository
|
||||
.compare(41, remote, &local, ComparisonMode::BranchChanges, &[])
|
||||
.unwrap();
|
||||
assert_eq!(reverse.files.len(), 1);
|
||||
assert_eq!(reverse.files[0].path, Path::new("local-only"));
|
||||
assert_eq!(reverse.blame[0].as_ref().unwrap().commit, base);
|
||||
assert_eq!(reverse.blame[1].as_ref().unwrap().commit, local.label);
|
||||
assert_eq!(repository.load_file(41, 0).unwrap().after, ["local"]);
|
||||
assert!(
|
||||
repository
|
||||
@@ -2866,3 +2894,45 @@ fn pull_request_refs_fetch_pinned_fork_heads_privately_for_git_and_jj() {
|
||||
assert_eq!(disk_state(&root), state);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jj_working_blame_captures_one_parent_and_never_selects_an_arbitrary_merge_parent() {
|
||||
let fixture = Fixture::new();
|
||||
let root = fixture.dir("blame-parents");
|
||||
init_jj(&root, false);
|
||||
fs::write(root.join("file"), "base\n").unwrap();
|
||||
jj(&root, &["describe", "-m", "base"]);
|
||||
let base = jj(&root, &["log", "--no-graph", "-r", "@", "-T", "commit_id"]);
|
||||
jj(&root, &["new"]);
|
||||
let state = disk_state(&root);
|
||||
let mut repository = open(&root);
|
||||
let one_parent = repository
|
||||
.compare(
|
||||
1,
|
||||
&working(RepoKind::Jujutsu),
|
||||
&working(RepoKind::Jujutsu),
|
||||
ComparisonMode::Snapshots,
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(one_parent.blame[0].as_ref().unwrap().commit, base);
|
||||
assert_eq!(one_parent.blame[0], one_parent.blame[1]);
|
||||
assert_eq!(disk_state(&root), state);
|
||||
jj(&root, &["new", "root()"]);
|
||||
fs::write(root.join("other"), "sibling\n").unwrap();
|
||||
jj(&root, &["describe", "-m", "sibling"]);
|
||||
let sibling = jj(&root, &["log", "--no-graph", "-r", "@", "-T", "commit_id"]);
|
||||
jj(&root, &["new", &base, &sibling]);
|
||||
let state = disk_state(&root);
|
||||
let merged = repository
|
||||
.compare(
|
||||
2,
|
||||
&working(RepoKind::Jujutsu),
|
||||
&working(RepoKind::Jujutsu),
|
||||
ComparisonMode::Snapshots,
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(merged.blame, [None, None]);
|
||||
assert_eq!(disk_state(&root), state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user