Fix the project diff sometimes missing updates (#40662)
This PR does two related things: - First, it gets rid of the undifferentiated `RepositoryEvent::Updated` in favor of three new events that have clearer definitions: `BranchChanged`, `StashEntriesChanged`, and `StatusesChanged`. An implication of this is that we no longer emit a `RepositoryEvent` unless some git state changed; previously we would emit `RepositoryUpdated` after doing a git status scan even if no statuses changed. - Second, it changes the subscription strategy of the project diff to make it update more robustly. Previously, the project diff only subscribed to the `GitStore`, so it relied on getting a `GitStoreEvent` when some buffer's diff hunks changed, even if the git status of the buffer's file didn't change (e.g. a second hunk in a file that was already modified). After this PR, it also subscribes to the individual `BufferDiff` entities for buffers that have a git status, so the `GitStore` is freed from that responsibility. This also fixes some real cases where the previous strategy was not effective in keeping the project diff up to date (captured in a test). Release Notes: - Fixed some cases where the project diff would fail to update in response to git events.
This commit is contained in:
@@ -156,7 +156,7 @@ use project::{
|
||||
},
|
||||
session::{Session, SessionEvent},
|
||||
},
|
||||
git_store::{GitStoreEvent, RepositoryEvent},
|
||||
git_store::GitStoreEvent,
|
||||
lsp_store::{
|
||||
CacheInlayHints, CompletionDocumentation, FormatTrigger, LspFormatTarget,
|
||||
OpenLspBufferHandle,
|
||||
@@ -1978,14 +1978,7 @@ impl Editor {
|
||||
let git_store = project.read(cx).git_store().clone();
|
||||
let project = project.clone();
|
||||
project_subscriptions.push(cx.subscribe(&git_store, move |this, _, event, cx| {
|
||||
if let GitStoreEvent::RepositoryUpdated(
|
||||
_,
|
||||
RepositoryEvent::Updated {
|
||||
new_instance: true, ..
|
||||
},
|
||||
_,
|
||||
) = event
|
||||
{
|
||||
if let GitStoreEvent::RepositoryAdded = event {
|
||||
this.load_diff_task = Some(
|
||||
update_uncommitted_diff_for_buffer(
|
||||
cx.entity(),
|
||||
|
||||
@@ -12615,18 +12615,6 @@ async fn test_strip_whitespace_and_format_via_lsp(cx: &mut TestAppContext) {
|
||||
)
|
||||
.await;
|
||||
|
||||
cx.run_until_parked();
|
||||
// Set up a buffer white some trailing whitespace and no trailing newline.
|
||||
cx.set_state(
|
||||
&[
|
||||
"one ", //
|
||||
"twoˇ", //
|
||||
"three ", //
|
||||
"four", //
|
||||
]
|
||||
.join("\n"),
|
||||
);
|
||||
|
||||
// Record which buffer changes have been sent to the language server
|
||||
let buffer_changes = Arc::new(Mutex::new(Vec::new()));
|
||||
cx.lsp
|
||||
@@ -12641,8 +12629,6 @@ async fn test_strip_whitespace_and_format_via_lsp(cx: &mut TestAppContext) {
|
||||
);
|
||||
}
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
// Handle formatting requests to the language server.
|
||||
cx.lsp
|
||||
.set_request_handler::<lsp::request::Formatting, _, _>({
|
||||
@@ -12691,6 +12677,18 @@ async fn test_strip_whitespace_and_format_via_lsp(cx: &mut TestAppContext) {
|
||||
}
|
||||
});
|
||||
|
||||
// Set up a buffer white some trailing whitespace and no trailing newline.
|
||||
cx.set_state(
|
||||
&[
|
||||
"one ", //
|
||||
"twoˇ", //
|
||||
"three ", //
|
||||
"four", //
|
||||
]
|
||||
.join("\n"),
|
||||
);
|
||||
cx.run_until_parked();
|
||||
|
||||
// Submit a format request.
|
||||
let format = cx
|
||||
.update_editor(|editor, window, cx| editor.format(&Format, window, cx))
|
||||
|
||||
@@ -16,7 +16,7 @@ use markdown::Markdown;
|
||||
use multi_buffer::{MultiBuffer, RowInfo};
|
||||
use project::{
|
||||
Project, ProjectItem as _,
|
||||
git_store::{GitStoreEvent, Repository, RepositoryEvent},
|
||||
git_store::{GitStoreEvent, Repository},
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
@@ -235,8 +235,8 @@ impl GitBlame {
|
||||
let git_store = project.read(cx).git_store().clone();
|
||||
let git_store_subscription =
|
||||
cx.subscribe(&git_store, move |this, _, event, cx| match event {
|
||||
GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::Updated { .. }, _)
|
||||
| GitStoreEvent::RepositoryAdded(_)
|
||||
GitStoreEvent::RepositoryUpdated(_, _, _)
|
||||
| GitStoreEvent::RepositoryAdded
|
||||
| GitStoreEvent::RepositoryRemoved(_) => {
|
||||
log::debug!("Status of git repositories updated. Regenerating blame data...",);
|
||||
this.generate(cx);
|
||||
|
||||
Reference in New Issue
Block a user