Move git status out of Entry (#22224)

- [x] Rewrite worktree git handling
- [x] Fix tests
- [x] Fix `test_propagate_statuses_for_repos_under_project`
- [x] Replace `WorkDirectoryEntry` with `WorkDirectory` in
`RepositoryEntry`
- [x] Add a worktree event for capturing git status changes
- [x] Confirm that the local repositories are correctly updating the new
WorkDirectory field
- [x] Implement the git statuses query as a join when pulling entries
out of worktree
- [x] Use this new join to implement the project panel and outline
panel.
- [x] Synchronize git statuses over the wire for collab and remote dev
(use the existing `worktree_repository_statuses` table, adjust as
needed)
- [x] Only send changed statuses to collab

Release Notes:

- N/A

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.com>
Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Mikayla Maki 2025-01-03 17:00:16 -08:00 committed by GitHub
parent 72057e5716
commit 9613084f59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 2824 additions and 1254 deletions

View file

@ -39,7 +39,10 @@ use futures::{
pub use image_store::{ImageItem, ImageStore};
use image_store::{ImageItemEvent, ImageStoreEvent};
use git::{blame::Blame, repository::GitRepository};
use git::{
blame::Blame,
repository::{GitFileStatus, GitRepository},
};
use gpui::{
AnyModel, AppContext, AsyncAppContext, BorrowAppContext, Context as _, EventEmitter, Hsla,
Model, ModelContext, SharedString, Task, WeakModel, WindowContext,
@ -95,9 +98,8 @@ pub use task_inventory::{
BasicContextProvider, ContextProviderWithTasks, Inventory, TaskSourceKind,
};
pub use worktree::{
Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, RepositoryEntry,
UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
FS_WATCH_LATENCY,
Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, UpdatedEntriesSet,
UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings, FS_WATCH_LATENCY,
};
pub use buffer_store::ProjectTransaction;
@ -242,6 +244,7 @@ pub enum Event {
ActivateProjectPanel,
WorktreeAdded(WorktreeId),
WorktreeOrderChanged,
GitRepositoryUpdated,
WorktreeRemoved(WorktreeId),
WorktreeUpdatedEntries(WorktreeId, UpdatedEntriesSet),
WorktreeUpdatedGitRepositories(WorktreeId),
@ -1433,6 +1436,15 @@ impl Project {
.unwrap_or(false)
}
pub fn project_path_git_status(
&self,
project_path: &ProjectPath,
cx: &AppContext,
) -> Option<GitFileStatus> {
self.worktree_for_id(project_path.worktree_id, cx)
.and_then(|worktree| worktree.read(cx).status_for_file(&project_path.path))
}
pub fn visibility_for_paths(&self, paths: &[PathBuf], cx: &AppContext) -> Option<bool> {
paths
.iter()
@ -2295,6 +2307,7 @@ impl Project {
}
WorktreeStoreEvent::WorktreeOrderChanged => cx.emit(Event::WorktreeOrderChanged),
WorktreeStoreEvent::WorktreeUpdateSent(_) => {}
WorktreeStoreEvent::GitRepositoryUpdated => cx.emit(Event::GitRepositoryUpdated),
}
}
@ -3516,17 +3529,6 @@ impl Project {
)
}
pub fn get_repo(
&self,
project_path: &ProjectPath,
cx: &AppContext,
) -> Option<Arc<dyn GitRepository>> {
self.worktree_for_id(project_path.worktree_id, cx)?
.read(cx)
.as_local()?
.local_git_repo(&project_path.path)
}
pub fn get_first_worktree_root_repo(&self, cx: &AppContext) -> Option<Arc<dyn GitRepository>> {
let worktree = self.visible_worktrees(cx).next()?.read(cx).as_local()?;
let root_entry = worktree.root_git_entry()?;
@ -4426,8 +4428,10 @@ impl Completion {
}
}
pub fn sort_worktree_entries(entries: &mut [Entry]) {
pub fn sort_worktree_entries(entries: &mut [impl AsRef<Entry>]) {
entries.sort_by(|entry_a, entry_b| {
let entry_a = entry_a.as_ref();
let entry_b = entry_b.as_ref();
compare_paths(
(&entry_a.path, entry_a.is_file()),
(&entry_b.path, entry_b.is_file()),