Fix missing hunks in project diff after revert (#25906)

Release Notes:

- N/A
This commit is contained in:
Cole Miller 2025-03-03 13:53:34 -05:00 committed by GitHub
parent b774a4b8d1
commit 9e2b7bc5dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 158 additions and 11 deletions

View file

@ -57,6 +57,8 @@ zed_actions.workspace = true
windows.workspace = true
[dev-dependencies]
ctor.workspace = true
env_logger.workspace = true
editor = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }

View file

@ -400,6 +400,7 @@ impl ProjectDiff {
self.editor.update(cx, |editor, cx| {
if was_empty {
editor.change_selections(None, window, cx, |selections| {
// TODO select the very beginning (possibly inside a deletion)
selections.select_ranges([0..0])
});
}
@ -980,6 +981,11 @@ mod tests {
use super::*;
#[ctor::ctor]
fn init_logger() {
env_logger::init();
}
fn init_test(cx: &mut TestAppContext) {
cx.update(|cx| {
let store = SettingsStore::test(cx);
@ -1152,4 +1158,107 @@ mod tests {
.unindent(),
);
}
#[gpui::test]
async fn test_hunks_after_restore_then_modify(cx: &mut TestAppContext) {
init_test(cx);
let fs = FakeFs::new(cx.executor());
fs.insert_tree(
path!("/project"),
json!({
".git": {},
"foo": "modified\n",
}),
)
.await;
let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let buffer = project
.update(cx, |project, cx| {
project.open_local_buffer(path!("/project/foo"), cx)
})
.await
.unwrap();
let buffer_editor = cx.new_window_entity(|window, cx| {
Editor::for_buffer(buffer, Some(project.clone()), window, cx)
});
let diff = cx.new_window_entity(|window, cx| {
ProjectDiff::new(project.clone(), workspace, window, cx)
});
cx.run_until_parked();
fs.set_head_for_repo(
path!("/project/.git").as_ref(),
&[("foo".into(), "original\n".into())],
);
fs.with_git_state(path!("/project/.git").as_ref(), true, |state| {
state.statuses = HashMap::from_iter([(
"foo".into(),
TrackedStatus {
index_status: StatusCode::Unmodified,
worktree_status: StatusCode::Modified,
}
.into(),
)]);
});
cx.run_until_parked();
let diff_editor = diff.update(cx, |diff, _| diff.editor.clone());
assert_state_with_diff(
&diff_editor,
cx,
&"
- original
+ ˇmodified
"
.unindent(),
);
let prev_buffer_hunks =
cx.update_window_entity(&buffer_editor, |buffer_editor, window, cx| {
let snapshot = buffer_editor.snapshot(window, cx);
let snapshot = &snapshot.buffer_snapshot;
let prev_buffer_hunks = buffer_editor
.diff_hunks_in_ranges(&[editor::Anchor::min()..editor::Anchor::max()], snapshot)
.collect::<Vec<_>>();
buffer_editor.git_restore(&Default::default(), window, cx);
prev_buffer_hunks
});
assert_eq!(prev_buffer_hunks.len(), 1);
cx.run_until_parked();
let new_buffer_hunks =
cx.update_window_entity(&buffer_editor, |buffer_editor, window, cx| {
let snapshot = buffer_editor.snapshot(window, cx);
let snapshot = &snapshot.buffer_snapshot;
let new_buffer_hunks = buffer_editor
.diff_hunks_in_ranges(&[editor::Anchor::min()..editor::Anchor::max()], snapshot)
.collect::<Vec<_>>();
buffer_editor.git_restore(&Default::default(), window, cx);
new_buffer_hunks
});
assert_eq!(new_buffer_hunks.as_slice(), &[]);
cx.update_window_entity(&buffer_editor, |buffer_editor, window, cx| {
buffer_editor.set_text("different\n", window, cx);
buffer_editor.save(false, project.clone(), window, cx)
})
.await
.unwrap();
cx.run_until_parked();
assert_state_with_diff(
&diff_editor,
cx,
&"
- original
+ ˇdifferent
"
.unindent(),
);
}
}