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:
Cole Miller
2025-10-23 16:46:27 +00:00
committed by GitHub
parent a66098b485
commit 8b6f3ec647
13 changed files with 214 additions and 159 deletions
+3 -15
View File
@@ -8936,10 +8936,7 @@ async fn test_ignored_dirs_events(cx: &mut gpui::TestAppContext) {
assert_eq!(
repository_updates.lock().drain(..).collect::<Vec<_>>(),
vec![
RepositoryEvent::Updated {
full_scan: true,
new_instance: false,
},
RepositoryEvent::StatusesChanged { full_scan: true },
RepositoryEvent::MergeHeadsChanged,
],
"Initial worktree scan should produce a repo update event"
@@ -9000,7 +8997,6 @@ async fn test_ignored_dirs_events(cx: &mut gpui::TestAppContext) {
repository_updates
.lock()
.iter()
.filter(|update| !matches!(update, RepositoryEvent::PathsChanged))
.cloned()
.collect::<Vec<_>>(),
Vec::new(),
@@ -9104,17 +9100,10 @@ async fn test_odd_events_for_ignored_dirs(
});
assert_eq!(
repository_updates
.lock()
.drain(..)
.filter(|update| !matches!(update, RepositoryEvent::PathsChanged))
.collect::<Vec<_>>(),
repository_updates.lock().drain(..).collect::<Vec<_>>(),
vec![
RepositoryEvent::Updated {
full_scan: true,
new_instance: false,
},
RepositoryEvent::MergeHeadsChanged,
RepositoryEvent::BranchChanged
],
"Initial worktree scan should produce a repo update event"
);
@@ -9142,7 +9131,6 @@ async fn test_odd_events_for_ignored_dirs(
repository_updates
.lock()
.iter()
.filter(|update| !matches!(update, RepositoryEvent::PathsChanged))
.cloned()
.collect::<Vec<_>>(),
Vec::new(),