Introduce diff crate to unite BufferDiff and BufferChangeSet (#24392)

This is a refactoring PR that does three things:

- First, it introduces a new `diff` crate that holds the previous
contents of the `git::diff` module, plus the `BufferChangeSet` type
formerly of `project::buffer_store`. The new crate is necessary since
simply moving `BufferChangeSet` into `git::diff` results in a dependency
cycle due to the use of `language::Buffer` to represent the diff base in
`BufferChangeSet`.
- Second, it renames the two main types in the new diff crate:
`BufferDiff` becomes `BufferDiffSnapshot`, and `BufferChangeSet` becomes
`BufferDiff`. This reflects that the relationship between these two
types (immutable cheaply-cloneable "value" type + stateful "resource
type" with subscriptions) mirrors existing pairs like
`Buffer`/`BufferSnapshot`. References to "change sets" throughout the
codebase are updated to refer to "diffs" instead.
- Finally, it moves the base_text field of the new BufferDiff type to
BufferDiffSnapshot.

Release Notes:

- N/A

---------

Co-authored-by: maxbrunsfeld <max@zed.dev>
This commit is contained in:
Cole Miller 2025-02-06 18:52:32 -05:00 committed by GitHub
parent ffcad71bfa
commit 73c487c222
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 922 additions and 875 deletions

View file

@ -33,6 +33,7 @@ clock.workspace = true
collections.workspace = true
dashmap.workspace = true
derive_more.workspace = true
diff.workspace = true
envy = "0.4.2"
futures.workspace = true
google_ai.workspace = true

View file

@ -309,8 +309,8 @@ impl Server {
.add_request_handler(forward_read_only_project_request::<proto::ResolveInlayHint>)
.add_request_handler(forward_read_only_project_request::<proto::OpenBufferByPath>)
.add_request_handler(forward_read_only_project_request::<proto::GitBranches>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUnstagedChanges>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUncommittedChanges>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUnstagedDiff>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUncommittedDiff>)
.add_request_handler(
forward_mutating_project_request::<proto::RegisterBufferWithLanguageServers>,
)

View file

@ -2598,25 +2598,25 @@ async fn test_git_diff_base_change(
.update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
.await
.unwrap();
let local_unstaged_changes_a = project_local
let local_unstaged_diff_a = project_local
.update(cx_a, |p, cx| {
p.open_unstaged_changes(buffer_local_a.clone(), cx)
p.open_unstaged_diff(buffer_local_a.clone(), cx)
})
.await
.unwrap();
// Wait for it to catch up to the new diff
executor.run_until_parked();
local_unstaged_changes_a.read_with(cx_a, |change_set, cx| {
local_unstaged_diff_a.read_with(cx_a, |diff, cx| {
let buffer = buffer_local_a.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(1..2, "", "two\n")],
);
});
@ -2626,47 +2626,47 @@ async fn test_git_diff_base_change(
.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
.await
.unwrap();
let remote_unstaged_changes_a = project_remote
let remote_unstaged_diff_a = project_remote
.update(cx_b, |p, cx| {
p.open_unstaged_changes(buffer_remote_a.clone(), cx)
p.open_unstaged_diff(buffer_remote_a.clone(), cx)
})
.await
.unwrap();
// Wait remote buffer to catch up to the new diff
executor.run_until_parked();
remote_unstaged_changes_a.read_with(cx_b, |change_set, cx| {
remote_unstaged_diff_a.read_with(cx_b, |diff, cx| {
let buffer = buffer_remote_a.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(1..2, "", "two\n")],
);
});
// Open uncommitted changes on the guest, without opening them on the host first
let remote_uncommitted_changes_a = project_remote
let remote_uncommitted_diff_a = project_remote
.update(cx_b, |p, cx| {
p.open_uncommitted_changes(buffer_remote_a.clone(), cx)
p.open_uncommitted_diff(buffer_remote_a.clone(), cx)
})
.await
.unwrap();
executor.run_until_parked();
remote_uncommitted_changes_a.read_with(cx_b, |change_set, cx| {
remote_uncommitted_diff_a.read_with(cx_b, |diff, cx| {
let buffer = buffer_remote_a.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(committed_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(1..2, "TWO\n", "two\n")],
);
});
@ -2683,44 +2683,44 @@ async fn test_git_diff_base_change(
// Wait for buffer_local_a to receive it
executor.run_until_parked();
local_unstaged_changes_a.read_with(cx_a, |change_set, cx| {
local_unstaged_diff_a.read_with(cx_a, |diff, cx| {
let buffer = buffer_local_a.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(new_staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(2..3, "", "three\n")],
);
});
remote_unstaged_changes_a.read_with(cx_b, |change_set, cx| {
remote_unstaged_diff_a.read_with(cx_b, |diff, cx| {
let buffer = buffer_remote_a.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(new_staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(2..3, "", "three\n")],
);
});
remote_uncommitted_changes_a.read_with(cx_b, |change_set, cx| {
remote_uncommitted_diff_a.read_with(cx_b, |diff, cx| {
let buffer = buffer_remote_a.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(new_committed_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(1..2, "TWO_HUNDRED\n", "two\n")],
);
});
@ -2748,25 +2748,25 @@ async fn test_git_diff_base_change(
.update(cx_a, |p, cx| p.open_buffer((worktree_id, "sub/b.txt"), cx))
.await
.unwrap();
let local_unstaged_changes_b = project_local
let local_unstaged_diff_b = project_local
.update(cx_a, |p, cx| {
p.open_unstaged_changes(buffer_local_b.clone(), cx)
p.open_unstaged_diff(buffer_local_b.clone(), cx)
})
.await
.unwrap();
// Wait for it to catch up to the new diff
executor.run_until_parked();
local_unstaged_changes_b.read_with(cx_a, |change_set, cx| {
local_unstaged_diff_b.read_with(cx_a, |diff, cx| {
let buffer = buffer_local_b.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&change_set.base_text_string().unwrap(),
&diff.base_text_string().unwrap(),
&[(1..2, "", "two\n")],
);
});
@ -2776,22 +2776,22 @@ async fn test_git_diff_base_change(
.update(cx_b, |p, cx| p.open_buffer((worktree_id, "sub/b.txt"), cx))
.await
.unwrap();
let remote_unstaged_changes_b = project_remote
let remote_unstaged_diff_b = project_remote
.update(cx_b, |p, cx| {
p.open_unstaged_changes(buffer_remote_b.clone(), cx)
p.open_unstaged_diff(buffer_remote_b.clone(), cx)
})
.await
.unwrap();
executor.run_until_parked();
remote_unstaged_changes_b.read_with(cx_b, |change_set, cx| {
remote_unstaged_diff_b.read_with(cx_b, |diff, cx| {
let buffer = buffer_remote_b.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&staged_text,
&[(1..2, "", "two\n")],
@ -2806,28 +2806,28 @@ async fn test_git_diff_base_change(
// Wait for buffer_local_b to receive it
executor.run_until_parked();
local_unstaged_changes_b.read_with(cx_a, |change_set, cx| {
local_unstaged_diff_b.read_with(cx_a, |diff, cx| {
let buffer = buffer_local_b.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(new_staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&new_staged_text,
&[(2..3, "", "three\n")],
);
});
remote_unstaged_changes_b.read_with(cx_b, |change_set, cx| {
remote_unstaged_diff_b.read_with(cx_b, |diff, cx| {
let buffer = buffer_remote_b.read(cx);
assert_eq!(
change_set.base_text_string().as_deref(),
diff.base_text_string().as_deref(),
Some(new_staged_text.as_str())
);
git::diff::assert_hunks(
change_set.diff_to_buffer.hunks_in_row_range(0..4, buffer),
diff::assert_hunks(
diff.snapshot.hunks_in_row_range(0..4, buffer),
buffer,
&new_staged_text,
&[(2..3, "", "three\n")],

View file

@ -1339,7 +1339,7 @@ impl RandomizedTest for ProjectCollaborationTest {
project
.buffer_store()
.read(cx)
.get_unstaged_changes(host_buffer.read(cx).remote_id(), cx)
.get_unstaged_diff(host_buffer.read(cx).remote_id(), cx)
.unwrap()
.read(cx)
.base_text_string()
@ -1348,7 +1348,7 @@ impl RandomizedTest for ProjectCollaborationTest {
project
.buffer_store()
.read(cx)
.get_unstaged_changes(guest_buffer.read(cx).remote_id(), cx)
.get_unstaged_diff(guest_buffer.read(cx).remote_id(), cx)
.unwrap()
.read(cx)
.base_text_string()