Fix flickering when staging and unstaging files (#27931)

This fixes a bug in #27568 that caused flickering in the git panel's
checkbox state when staging and unstaging entire files. The problem is
that that stage/unstage action first saves the target path (if it's open
as a buffer), and we do a targeted git status scan in response to that
filesystem event, which makes its way to the git panel and causes it to
clear its pending state before the actual stage or unstage has gone
through.

The fix is to not clear the panel's pending state for git repository
events that originated from a targeted scan (i.e. one that was triggered
by FS events for repo paths, as opposed to events inside `.git` which
cause all statuses to be recomputed).

Release Notes:

- N/A
This commit is contained in:
Cole Miller 2025-04-02 13:43:48 -04:00 committed by GitHub
parent 0be8bf1b12
commit e1a8a31fa4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 12 additions and 8 deletions

View file

@ -212,7 +212,7 @@ 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::RepositoryUpdated(_, RepositoryEvent::Updated { .. }, _)
| GitStoreEvent::RepositoryAdded(_)
| GitStoreEvent::RepositoryRemoved(_) => {
log::debug!("Status of git repositories updated. Regenerating blame data...",);

View file

@ -408,8 +408,12 @@ impl GitPanel {
this.active_repository = git_store.read(cx).active_repository();
this.schedule_update(true, window, cx);
}
GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::Updated, true) => {
this.schedule_update(true, window, cx);
GitStoreEvent::RepositoryUpdated(
_,
RepositoryEvent::Updated { full_scan },
true,
) => {
this.schedule_update(*full_scan, window, cx);
}
GitStoreEvent::RepositoryUpdated(_, _, _) => {}
GitStoreEvent::RepositoryAdded(_) | GitStoreEvent::RepositoryRemoved(_) => {

View file

@ -154,7 +154,7 @@ impl ProjectDiff {
window,
move |this, _git_store, event, _window, _cx| match event {
GitStoreEvent::ActiveRepositoryChanged(_)
| GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::Updated, true) => {
| GitStoreEvent::RepositoryUpdated(_, RepositoryEvent::Updated { .. }, true) => {
*this.update_needed.borrow_mut() = ();
}
_ => {}

View file

@ -258,7 +258,7 @@ pub enum RepositoryState {
#[derive(Clone, Debug)]
pub enum RepositoryEvent {
Updated,
Updated { full_scan: bool },
MergeHeadsChanged,
}
@ -3521,7 +3521,7 @@ impl Repository {
if update.is_last_update {
self.snapshot.scan_id = update.scan_id;
}
cx.emit(RepositoryEvent::Updated);
cx.emit(RepositoryEvent::Updated { full_scan: true });
Ok(())
}
@ -3866,7 +3866,7 @@ impl Repository {
.ok();
}
}
cx.emit(RepositoryEvent::Updated);
cx.emit(RepositoryEvent::Updated { full_scan: false });
})
},
);
@ -4106,7 +4106,7 @@ async fn compute_snapshot(
|| branch != prev_snapshot.branch
|| statuses_by_path != prev_snapshot.statuses_by_path
{
events.push(RepositoryEvent::Updated);
events.push(RepositoryEvent::Updated { full_scan: true });
}
let mut current_merge_conflicts = TreeSet::default();