git_graph: Fix long commit message overflow in detail panel (#61163)
Follow-up to zed-industries/zed#60721. The Taffy 0.12 upgrade exposed that the message height limit was applied to its grid parent while percentage-sized children retained the Markdown content's intrinsic height. Long messages therefore painted over the changed-files summary instead of scrolling. Move the height limit to the scroll container itself, matching the commit view. Add a GPUI regression test that verifies the viewport stays bounded, remains scrollable, and does not overlap the changed-files list. > On `main`: <img width="697" height="873" alt="Screenshot 2026-07-17 at 14 59 21" src="https://github.com/user-attachments/assets/51e6cc0e-aeac-4ad1-a6af-2120efcef901" /> --- Release Notes: - N/A
This commit is contained in:
1 parent
9552acc2bc
commit
94e59ce2f8
1 file changed
+131
-1
@@ -3725,7 +3725,6 @@ impl GitGraph {
|
||||
// grid, on the other hand, doesn't appear to give taffy the same
|
||||
// problems.
|
||||
.w_full()
|
||||
.max_h(line_height * 12.)
|
||||
.py_2()
|
||||
.pl_2()
|
||||
.grid()
|
||||
@@ -3740,6 +3739,7 @@ impl GitGraph {
|
||||
.id("commit-message")
|
||||
.text_sm()
|
||||
.size_full()
|
||||
.max_h(line_height * 12.)
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(scroll_handle)
|
||||
.child(MarkdownElement::new(message.clone(), message_style)),
|
||||
@@ -7381,6 +7381,136 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_long_commit_message_is_constrained_to_scroll_viewport(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
Path::new("/project"),
|
||||
json!({ ".git": {}, "file.txt": "content" }),
|
||||
)
|
||||
.await;
|
||||
|
||||
let commit_sha = Oid::from_bytes(&[1; 20]).expect("commit SHA should be valid");
|
||||
let commits = vec![Arc::new(InitialGraphCommitData {
|
||||
sha: commit_sha,
|
||||
parents: smallvec![],
|
||||
ref_names: vec!["HEAD -> main".into()],
|
||||
})];
|
||||
fs.set_graph_commits(Path::new("/project/.git"), commits);
|
||||
|
||||
let message = (0..40)
|
||||
.map(|line_number| {
|
||||
format!(
|
||||
"Line {line_number}: This commit message is long enough to require scrolling."
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n");
|
||||
fs.set_commit_data(
|
||||
Path::new("/project/.git"),
|
||||
[(
|
||||
CommitData {
|
||||
sha: commit_sha,
|
||||
parents: smallvec![],
|
||||
author_name: "Author".into(),
|
||||
author_email: "author@example.com".into(),
|
||||
commit_timestamp: 1_700_000_000,
|
||||
subject: "Long commit message".into(),
|
||||
message: message.into(),
|
||||
},
|
||||
false,
|
||||
)],
|
||||
);
|
||||
|
||||
let project = Project::test(fs.clone(), [Path::new("/project")], cx).await;
|
||||
cx.run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project
|
||||
.active_repository(cx)
|
||||
.expect("should have a repository")
|
||||
});
|
||||
let (multi_workspace, cx) = cx.add_window_view(|window, cx| {
|
||||
workspace::MultiWorkspace::test_new(project.clone(), window, cx)
|
||||
});
|
||||
let workspace_weak =
|
||||
multi_workspace.read_with(&*cx, |multi, _| multi.workspace().downgrade());
|
||||
let git_graph = cx.new_window_entity(|window, cx| {
|
||||
GitGraph::new(
|
||||
repository.read(cx).id,
|
||||
project.read(cx).git_store().clone(),
|
||||
workspace_weak,
|
||||
None,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_first(&menu::SelectFirst, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
git_graph.update(cx, |graph, cx| {
|
||||
graph.selected_commit_diff = Some(CommitDiff {
|
||||
files: vec![CommitFile {
|
||||
path: RepoPath::new("file.txt").expect("repository path should be valid"),
|
||||
old_text: Some("content".into()),
|
||||
new_text: Some("updated content".into()),
|
||||
is_binary: false,
|
||||
}],
|
||||
});
|
||||
graph.selected_commit_diff_stats = Some((1, 1));
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
cx.draw(
|
||||
point(px(0.), px(0.)),
|
||||
gpui::size(px(1200.), px(800.)),
|
||||
|_, _| git_graph.clone().into_any_element(),
|
||||
);
|
||||
cx.run_until_parked();
|
||||
|
||||
let (message_scroll_handle, changed_files_scroll_handle) =
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
(
|
||||
graph
|
||||
.selected_commit_message
|
||||
.as_ref()
|
||||
.expect("selected commit message should be loaded")
|
||||
.scroll_handle
|
||||
.clone(),
|
||||
graph.changed_files_scroll_handle.clone(),
|
||||
)
|
||||
});
|
||||
let maximum_message_height = git_graph.update_in(cx, |_, window, cx| {
|
||||
editor::hover_markdown_style(window, cx)
|
||||
.base_text_style
|
||||
.line_height_in_pixels(window.rem_size())
|
||||
* 12.
|
||||
});
|
||||
let message_bounds = message_scroll_handle.bounds();
|
||||
let changed_files_bounds = changed_files_scroll_handle.0.borrow().base_handle.bounds();
|
||||
|
||||
assert!(
|
||||
message_bounds.size.height <= maximum_message_height,
|
||||
"commit message viewport height ({}) should not exceed its maximum ({})",
|
||||
message_bounds.size.height,
|
||||
maximum_message_height,
|
||||
);
|
||||
assert!(
|
||||
message_scroll_handle.max_offset().y > px(0.),
|
||||
"long commit message should be scrollable"
|
||||
);
|
||||
assert!(
|
||||
message_bounds.bottom() <= changed_files_bounds.top(),
|
||||
"commit message viewport {message_bounds:?} should not overlap changed files {changed_files_bounds:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_commit_message_not_reloaded_for_same_sha(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
Reference in new issue
Block a user