diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index ba6f71822b3cf6adb748f8dab12f503b7c1ca850..f3aa166a691b8a29ec8d174b1c9503afbaafc6a4 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -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(), diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index ea2ae32ba9a9d589b937e3cbc7939cd8b5bc1b2a..2a3909f069ac491adb8f5675807b647b77d23ac9 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -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::({ @@ -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)) diff --git a/crates/editor/src/git/blame.rs b/crates/editor/src/git/blame.rs index 836b61d56674f070abc13dbf6c67981c78818ff6..3d83e3a5cce937b92255810003a6ff951bb84d95 100644 --- a/crates/editor/src/git/blame.rs +++ b/crates/editor/src/git/blame.rs @@ -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); diff --git a/crates/fs/src/fake_git_repo.rs b/crates/fs/src/fake_git_repo.rs index 2c6db5b53987013d24a3a922e8f3b67adc9d43f5..409edade8a704bc79c00aab5acb3856c66d5b91e 100644 --- a/crates/fs/src/fake_git_repo.rs +++ b/crates/fs/src/fake_git_repo.rs @@ -11,14 +11,20 @@ use git::{ }, status::{FileStatus, GitStatus, StatusCode, TrackedStatus, UnmergedStatus}, }; -use gpui::{AsyncApp, BackgroundExecutor, SharedString, Task}; +use gpui::{AsyncApp, BackgroundExecutor, SharedString, Task, TaskLabel}; use ignore::gitignore::GitignoreBuilder; use parking_lot::Mutex; use rope::Rope; use smol::future::FutureExt as _; -use std::{path::PathBuf, sync::Arc}; +use std::{ + path::PathBuf, + sync::{Arc, LazyLock}, +}; use util::{paths::PathStyle, rel_path::RelPath}; +pub static LOAD_INDEX_TEXT_TASK: LazyLock = LazyLock::new(TaskLabel::new); +pub static LOAD_HEAD_TEXT_TASK: LazyLock = LazyLock::new(TaskLabel::new); + #[derive(Clone)] pub struct FakeGitRepository { pub(crate) fs: Arc, @@ -79,33 +85,29 @@ impl GitRepository for FakeGitRepository { fn reload_index(&self) {} fn load_index_text(&self, path: RepoPath) -> BoxFuture<'_, Option> { - async { - self.with_state_async(false, move |state| { - state - .index_contents - .get(&path) - .context("not present in index") - .cloned() - }) - .await - .ok() - } - .boxed() + let fut = self.with_state_async(false, move |state| { + state + .index_contents + .get(&path) + .context("not present in index") + .cloned() + }); + self.executor + .spawn_labeled(*LOAD_INDEX_TEXT_TASK, async move { fut.await.ok() }) + .boxed() } fn load_committed_text(&self, path: RepoPath) -> BoxFuture<'_, Option> { - async { - self.with_state_async(false, move |state| { - state - .head_contents - .get(&path) - .context("not present in HEAD") - .cloned() - }) - .await - .ok() - } - .boxed() + let fut = self.with_state_async(false, move |state| { + state + .head_contents + .get(&path) + .context("not present in HEAD") + .cloned() + }); + self.executor + .spawn_labeled(*LOAD_HEAD_TEXT_TASK, async move { fut.await.ok() }) + .boxed() } fn load_commit( diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index 69ac5fb0d3b4aed9e63166c60ba9550186fb204f..a6c7be1c9388302f04a1a0440d33d3f6322c2077 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -58,6 +58,9 @@ use smol::io::AsyncReadExt; #[cfg(any(test, feature = "test-support"))] use std::ffi::OsStr; +#[cfg(any(test, feature = "test-support"))] +pub use fake_git_repo::{LOAD_HEAD_TEXT_TASK, LOAD_INDEX_TEXT_TASK}; + pub trait Watcher: Send + Sync { fn add(&self, path: &Path) -> Result<()>; fn remove(&self, path: &Path) -> Result<()>; diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 2bd0fea7018a99a943efe91becd7c22962b27fb4..9ff8602a18fd1a7eec5804deecee5c21921c6eee 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -425,13 +425,20 @@ impl GitPanel { } GitStoreEvent::RepositoryUpdated( _, - RepositoryEvent::Updated { full_scan, .. }, + RepositoryEvent::StatusesChanged { full_scan: true } + | RepositoryEvent::BranchChanged + | RepositoryEvent::MergeHeadsChanged, true, ) => { - this.schedule_update(*full_scan, window, cx); + this.schedule_update(true, window, cx); } - - GitStoreEvent::RepositoryAdded(_) | GitStoreEvent::RepositoryRemoved(_) => { + GitStoreEvent::RepositoryUpdated( + _, + RepositoryEvent::StatusesChanged { full_scan: false }, + true, + ) + | GitStoreEvent::RepositoryAdded + | GitStoreEvent::RepositoryRemoved(_) => { this.schedule_update(false, window, cx); } GitStoreEvent::IndexWriteError(error) => { diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index b073b9dc3da17c10d9df1fa99c9bec53575818df..de16803965e0d8afb5bebcc37628d8c25ecc05e9 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -6,7 +6,7 @@ use crate::{ }; use anyhow::Result; use buffer_diff::{BufferDiff, DiffHunkSecondaryStatus}; -use collections::HashSet; +use collections::{HashMap, HashSet}; use editor::{ Editor, EditorEvent, SelectionEffects, actions::{GoToHunk, GoToPreviousHunk}, @@ -27,7 +27,7 @@ use language::{Anchor, Buffer, Capability, OffsetRangeExt}; use multi_buffer::{MultiBuffer, PathKey}; use project::{ Project, ProjectPath, - git_store::{GitStore, GitStoreEvent, Repository}, + git_store::{GitStore, GitStoreEvent, Repository, RepositoryEvent}, }; use settings::{Settings, SettingsStore}; use std::any::{Any, TypeId}; @@ -57,12 +57,13 @@ pub struct ProjectDiff { multibuffer: Entity, editor: Entity, git_store: Entity, + buffer_diff_subscriptions: HashMap, Subscription)>, workspace: WeakEntity, focus_handle: FocusHandle, update_needed: postage::watch::Sender<()>, pending_scroll: Option, _task: Task>, - _subscription: Subscription, + _git_store_subscription: Subscription, } #[derive(Debug)] @@ -177,7 +178,11 @@ impl ProjectDiff { window, move |this, _git_store, event, _window, _cx| match event { GitStoreEvent::ActiveRepositoryChanged(_) - | GitStoreEvent::RepositoryUpdated(_, _, true) + | GitStoreEvent::RepositoryUpdated( + _, + RepositoryEvent::StatusesChanged { full_scan: _ }, + true, + ) | GitStoreEvent::ConflictsUpdated => { *this.update_needed.borrow_mut() = (); } @@ -217,10 +222,11 @@ impl ProjectDiff { focus_handle, editor, multibuffer, + buffer_diff_subscriptions: Default::default(), pending_scroll: None, update_needed: send, _task: worker, - _subscription: git_store_subscription, + _git_store_subscription: git_store_subscription, } } @@ -365,6 +371,7 @@ impl ProjectDiff { self.multibuffer.update(cx, |multibuffer, cx| { multibuffer.clear(cx); }); + self.buffer_diff_subscriptions.clear(); return vec![]; }; @@ -407,6 +414,8 @@ impl ProjectDiff { }); self.multibuffer.update(cx, |multibuffer, cx| { for path in previous_paths { + self.buffer_diff_subscriptions + .remove(&path.path.clone().into()); multibuffer.remove_excerpts_for_path(path, cx); } }); @@ -419,9 +428,15 @@ impl ProjectDiff { window: &mut Window, cx: &mut Context, ) { - let path_key = diff_buffer.path_key; - let buffer = diff_buffer.buffer; - let diff = diff_buffer.diff; + let path_key = diff_buffer.path_key.clone(); + let buffer = diff_buffer.buffer.clone(); + let diff = diff_buffer.diff.clone(); + + let subscription = cx.subscribe(&diff, move |this, _, _, _| { + *this.update_needed.borrow_mut() = (); + }); + self.buffer_diff_subscriptions + .insert(path_key.path.clone().into(), (diff.clone(), subscription)); let conflict_addon = self .editor @@ -440,9 +455,10 @@ impl ProjectDiff { .unwrap_or_default(); let conflicts = conflicts.iter().map(|conflict| conflict.range.clone()); - let excerpt_ranges = merge_anchor_ranges(diff_hunk_ranges, conflicts, &snapshot) - .map(|range| range.to_point(&snapshot)) - .collect::>(); + let excerpt_ranges = + merge_anchor_ranges(diff_hunk_ranges.into_iter(), conflicts, &snapshot) + .map(|range| range.to_point(&snapshot)) + .collect::>(); let (was_empty, is_excerpt_newly_added) = self.multibuffer.update(cx, |multibuffer, cx| { let was_empty = multibuffer.is_empty(); @@ -519,8 +535,7 @@ impl ProjectDiff { self.multibuffer .read(cx) .excerpt_paths() - .map(|key| key.path()) - .cloned() + .map(|key| key.path.clone()) .collect() } } @@ -1621,8 +1636,8 @@ mod tests { cx, &" - original - + different - ˇ" + + ˇdifferent + " .unindent(), ); } @@ -1950,6 +1965,7 @@ mod tests { .unindent(), ); + // The project diff updates its excerpts when a new hunk appears in a buffer that already has a diff. let buffer = project .update(cx, |project, cx| { project.open_local_buffer(path!("/project/foo.txt"), cx) @@ -2002,4 +2018,63 @@ mod tests { .unindent(), ); } + + #[gpui::test] + async fn test_update_on_uncommit(cx: &mut TestAppContext) { + init_test(cx); + + let fs = FakeFs::new(cx.executor()); + fs.insert_tree( + path!("/project"), + json!({ + ".git": {}, + "README.md": "# My cool project\n".to_owned() + }), + ) + .await; + fs.set_head_and_index_for_repo( + Path::new(path!("/project/.git")), + &[("README.md", "# My cool project\n".to_owned())], + ); + let project = Project::test(fs.clone(), [Path::new(path!("/project"))], cx).await; + let worktree_id = project.read_with(cx, |project, cx| { + project.worktrees(cx).next().unwrap().read(cx).id() + }); + let (workspace, cx) = + cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx)); + cx.run_until_parked(); + + let _editor = workspace + .update_in(cx, |workspace, window, cx| { + workspace.open_path((worktree_id, rel_path("README.md")), None, true, window, cx) + }) + .await + .unwrap() + .downcast::() + .unwrap(); + + cx.focus(&workspace); + cx.update(|window, cx| { + window.dispatch_action(project_diff::Diff.boxed_clone(), cx); + }); + cx.run_until_parked(); + let item = workspace.update(cx, |workspace, cx| { + workspace.active_item_as::(cx).unwrap() + }); + cx.focus(&item); + let editor = item.read_with(cx, |item, _| item.editor.clone()); + + fs.set_head_and_index_for_repo( + Path::new(path!("/project/.git")), + &[( + "README.md", + "# My cool project\nDetails to come.\n".to_owned(), + )], + ); + cx.run_until_parked(); + + let mut cx = EditorTestContext::for_editor_in(editor, cx).await; + + cx.assert_excerpts_with_selections("[EXCERPT]\nˇ# My cool project\nDetails to come.\n"); + } } diff --git a/crates/git_ui/src/stash_picker.rs b/crates/git_ui/src/stash_picker.rs index a8e725eefcafb2f3742b23adfdd75ab129052773..58f17d7a3bb087ff058878f7889d6d83bc1727a6 100644 --- a/crates/git_ui/src/stash_picker.rs +++ b/crates/git_ui/src/stash_picker.rs @@ -72,7 +72,7 @@ impl StashList { if let Some(repo) = repository.clone() { _subscriptions.push( cx.subscribe_in(&repo, window, |this, _, event, window, cx| { - if matches!(event, RepositoryEvent::Updated { .. }) { + if matches!(event, RepositoryEvent::StashEntriesChanged) { let stash_entries = this.picker.read_with(cx, |picker, cx| { picker .delegate diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index e6e2f7f1c68f976473b5e6ee8b60ca8652aa4b1d..646d7fce825c05204c07f42619d5f9964d5cd321 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -166,8 +166,8 @@ impl MultiBufferDiffHunk { #[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Hash, Debug)] pub struct PathKey { // Used by the derived PartialOrd & Ord - sort_prefix: Option, - path: Arc, + pub sort_prefix: Option, + pub path: Arc, } impl PathKey { @@ -190,11 +190,6 @@ impl PathKey { } } } - - #[cfg(any(test, feature = "test-support"))] - pub fn path(&self) -> &Arc { - &self.path - } } pub type MultiBufferPoint = Point; diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 326af767102721987f753012ac82649046543ee0..8612c739a01c1a927dd071c73f789ea1ef4a2542 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -301,9 +301,13 @@ pub enum RepositoryState { #[derive(Clone, Debug, PartialEq, Eq)] pub enum RepositoryEvent { - Updated { full_scan: bool, new_instance: bool }, + StatusesChanged { + // TODO could report which statuses changed here + full_scan: bool, + }, MergeHeadsChanged, - PathsChanged, + BranchChanged, + StashEntriesChanged, } #[derive(Clone, Debug)] @@ -313,7 +317,7 @@ pub struct JobsUpdated; pub enum GitStoreEvent { ActiveRepositoryChanged(Option), RepositoryUpdated(RepositoryId, RepositoryEvent, bool), - RepositoryAdded(RepositoryId), + RepositoryAdded, RepositoryRemoved(RepositoryId), IndexWriteError(anyhow::Error), JobsUpdated, @@ -1218,7 +1222,7 @@ impl GitStore { self._subscriptions .push(cx.subscribe(&repo, Self::on_jobs_updated)); self.repositories.insert(id, repo); - cx.emit(GitStoreEvent::RepositoryAdded(id)); + cx.emit(GitStoreEvent::RepositoryAdded); self.active_repo_id.get_or_insert_with(|| { cx.emit(GitStoreEvent::ActiveRepositoryChanged(Some(id))); id @@ -1485,11 +1489,10 @@ impl GitStore { let id = RepositoryId::from_proto(update.id); let client = this.upstream_client().context("no upstream client")?; - let mut is_new = false; + let mut repo_subscription = None; let repo = this.repositories.entry(id).or_insert_with(|| { - is_new = true; let git_store = cx.weak_entity(); - cx.new(|cx| { + let repo = cx.new(|cx| { Repository::remote( id, Path::new(&update.abs_path).into(), @@ -1499,16 +1502,16 @@ impl GitStore { git_store, cx, ) - }) + }); + repo_subscription = Some(cx.subscribe(&repo, Self::on_repository_event)); + cx.emit(GitStoreEvent::RepositoryAdded); + repo }); - if is_new { - this._subscriptions - .push(cx.subscribe(repo, Self::on_repository_event)) - } + this._subscriptions.extend(repo_subscription); repo.update(cx, { let update = update.clone(); - |repo, cx| repo.apply_remote_update(update, is_new, cx) + |repo, cx| repo.apply_remote_update(update, cx) })?; this.active_repo_id.get_or_insert_with(|| { @@ -3877,18 +3880,15 @@ impl Repository { environment, .. } => { + // TODO would be nice to not have to do this manually let result = backend.stash_drop(index, environment).await; if result.is_ok() && let Ok(stash_entries) = backend.stash_entries().await { let snapshot = this.update(&mut cx, |this, cx| { this.snapshot.stash_entries = stash_entries; - let snapshot = this.snapshot.clone(); - cx.emit(RepositoryEvent::Updated { - full_scan: false, - new_instance: false, - }); - snapshot + cx.emit(RepositoryEvent::StashEntriesChanged); + this.snapshot.clone() })?; if let Some(updates_tx) = updates_tx { updates_tx @@ -4048,18 +4048,15 @@ impl Repository { cx.clone(), ) .await; + // TODO would be nice to not have to do this manually if result.is_ok() { let branches = backend.branches().await?; let branch = branches.into_iter().find(|branch| branch.is_head); log::info!("head branch after scan is {branch:?}"); let snapshot = this.update(&mut cx, |this, cx| { this.snapshot.branch = branch; - let snapshot = this.snapshot.clone(); - cx.emit(RepositoryEvent::Updated { - full_scan: false, - new_instance: false, - }); - snapshot + cx.emit(RepositoryEvent::BranchChanged); + this.snapshot.clone() })?; if let Some(updates_tx) = updates_tx { updates_tx @@ -4458,7 +4455,6 @@ impl Repository { pub(crate) fn apply_remote_update( &mut self, update: proto::UpdateRepository, - is_new: bool, cx: &mut Context, ) -> Result<()> { let conflicted_paths = TreeSet::from_ordered_entries( @@ -4467,21 +4463,30 @@ impl Repository { .into_iter() .filter_map(|path| RepoPath::from_proto(&path).log_err()), ); - self.snapshot.branch = update.branch_summary.as_ref().map(proto_to_branch); - self.snapshot.head_commit = update + let new_branch = update.branch_summary.as_ref().map(proto_to_branch); + let new_head_commit = update .head_commit_details .as_ref() .map(proto_to_commit_details); + if self.snapshot.branch != new_branch || self.snapshot.head_commit != new_head_commit { + cx.emit(RepositoryEvent::BranchChanged) + } + self.snapshot.branch = new_branch; + self.snapshot.head_commit = new_head_commit; self.snapshot.merge.conflicted_paths = conflicted_paths; self.snapshot.merge.message = update.merge_message.map(SharedString::from); - self.snapshot.stash_entries = GitStash { + let new_stash_entries = GitStash { entries: update .stash_entries .iter() .filter_map(|entry| proto_to_stash(entry).ok()) .collect(), }; + if self.snapshot.stash_entries != new_stash_entries { + cx.emit(RepositoryEvent::StashEntriesChanged) + } + self.snapshot.stash_entries = new_stash_entries; let edits = update .removed_statuses @@ -4500,14 +4505,13 @@ impl Repository { }), ) .collect::>(); + if !edits.is_empty() { + cx.emit(RepositoryEvent::StatusesChanged { full_scan: true }); + } self.snapshot.statuses_by_path.edit(edits, ()); if update.is_last_update { self.snapshot.scan_id = update.scan_id; } - cx.emit(RepositoryEvent::Updated { - full_scan: true, - new_instance: is_new, - }); Ok(()) } @@ -4830,23 +4834,19 @@ impl Repository { .await; this.update(&mut cx, |this, cx| { - let needs_update = !changed_path_statuses.is_empty() - || this.snapshot.stash_entries != stash_entries; - this.snapshot.stash_entries = stash_entries; + if this.snapshot.stash_entries != stash_entries { + cx.emit(RepositoryEvent::StashEntriesChanged); + this.snapshot.stash_entries = stash_entries; + } + if !changed_path_statuses.is_empty() { + cx.emit(RepositoryEvent::StatusesChanged { full_scan: false }); this.snapshot .statuses_by_path .edit(changed_path_statuses, ()); this.snapshot.scan_id += 1; } - if needs_update { - cx.emit(RepositoryEvent::Updated { - full_scan: false, - new_instance: false, - }); - } - if let Some(updates_tx) = updates_tx { updates_tx .unbounded_send(DownstreamUpdate::UpdateRepository( @@ -4854,7 +4854,6 @@ impl Repository { )) .ok(); } - cx.emit(RepositoryEvent::PathsChanged); }) }, ); @@ -5117,28 +5116,24 @@ async fn compute_snapshot( MergeDetails::load(&backend, &statuses_by_path, &prev_snapshot).await?; log::debug!("new merge details (changed={merge_heads_changed:?}): {merge_details:?}"); - if merge_heads_changed - || branch != prev_snapshot.branch - || statuses_by_path != prev_snapshot.statuses_by_path - { - events.push(RepositoryEvent::Updated { - full_scan: true, - new_instance: false, - }); - } - - // Cache merge conflict paths so they don't change from staging/unstaging, - // until the merge heads change (at commit time, etc.). if merge_heads_changed { events.push(RepositoryEvent::MergeHeadsChanged); } + if statuses_by_path != prev_snapshot.statuses_by_path { + events.push(RepositoryEvent::StatusesChanged { full_scan: true }) + } + // Useful when branch is None in detached head state let head_commit = match backend.head_sha().await { Some(head_sha) => backend.show(head_sha).await.log_err(), None => None, }; + if branch != prev_snapshot.branch || head_commit != prev_snapshot.head_commit { + events.push(RepositoryEvent::BranchChanged); + } + // Used by edit prediction data collection let remote_origin_url = backend.remote_url("origin"); let remote_upstream_url = backend.remote_url("upstream"); diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 89a49c6fb0185d36cf2dab3f07cfc6efedd1b6d1..859fe02cfa70d035a347c62ba7cbe93f250b674a 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -8936,10 +8936,7 @@ async fn test_ignored_dirs_events(cx: &mut gpui::TestAppContext) { assert_eq!( repository_updates.lock().drain(..).collect::>(), 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::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::>(), + repository_updates.lock().drain(..).collect::>(), 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::new(), diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index ff5a6b661e792ad7c9188fa99b288827efe55c48..8794b625e2b63384041264d67b7d8bf729707735 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -496,8 +496,12 @@ impl ProjectPanel { &git_store, window, |this, _, event, window, cx| match event { - GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::Updated { .. }, _) - | GitStoreEvent::RepositoryAdded(_) + GitStoreEvent::RepositoryUpdated( + _, + RepositoryEvent::StatusesChanged { full_scan: _ }, + _, + ) + | GitStoreEvent::RepositoryAdded | GitStoreEvent::RepositoryRemoved(_) => { this.update_visible_entries(None, false, false, window, cx); cx.notify(); diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index 3f3b009a19fa15a9e9b9c2abe09a66e90eceafb2..18a4592edb153dd204bf8df72b1d37fbc81567d5 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -30,10 +30,7 @@ use gpui::{ Subscription, WeakEntity, Window, actions, div, }; use onboarding_banner::OnboardingBanner; -use project::{ - Project, WorktreeSettings, - git_store::{GitStoreEvent, RepositoryEvent}, -}; +use project::{Project, WorktreeSettings, git_store::GitStoreEvent}; use remote::RemoteConnectionOptions; use settings::{Settings, SettingsLocation}; use std::sync::Arc; @@ -287,9 +284,7 @@ impl TitleBar { subscriptions.push( cx.subscribe(&git_store, move |_, _, event, cx| match event { GitStoreEvent::ActiveRepositoryChanged(_) - | GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::Updated { .. }, _) - | GitStoreEvent::RepositoryAdded(_) - | GitStoreEvent::RepositoryRemoved(_) => { + | GitStoreEvent::RepositoryUpdated(_, _, true) => { cx.notify(); } _ => {}