git: Implement a basic repository selector (#23419)

This PR adds a rough-and-ready picker for selecting which of the
project's repositories the git panel should display.

Release Notes:

- N/A

---------

Co-authored-by: Nate Butler <iamnbutler@gmail.com>
Co-authored-by: Nate <nate@zed.dev>
This commit is contained in:
Cole Miller 2025-01-21 18:11:53 -05:00 committed by GitHub
parent 417760ade7
commit 31909bf334
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 661 additions and 356 deletions

View file

@ -22,6 +22,7 @@ mod project_tests;
mod direnv;
mod environment;
pub use environment::EnvironmentErrorMessage;
use git::RepositoryHandle;
pub mod search_history;
mod yarn;
@ -691,7 +692,8 @@ impl Project {
)
});
let git_state = Some(cx.new_model(|cx| GitState::new(languages.clone(), cx)));
let git_state =
Some(cx.new_model(|cx| GitState::new(&worktree_store, languages.clone(), cx)));
cx.subscribe(&lsp_store, Self::on_lsp_store_event).detach();
@ -2324,6 +2326,18 @@ impl Project {
}
WorktreeStoreEvent::WorktreeOrderChanged => cx.emit(Event::WorktreeOrderChanged),
WorktreeStoreEvent::WorktreeUpdateSent(_) => {}
WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
self.client()
.telemetry()
.report_discovered_project_events(*worktree_id, changes);
cx.emit(Event::WorktreeUpdatedEntries(*worktree_id, changes.clone()))
}
WorktreeStoreEvent::WorktreeUpdatedGitRepositories(worktree_id) => {
cx.emit(Event::WorktreeUpdatedGitRepositories(*worktree_id))
}
WorktreeStoreEvent::WorktreeDeletedEntry(worktree_id, id) => {
cx.emit(Event::DeletedEntry(*worktree_id, *id))
}
}
}
@ -2335,27 +2349,6 @@ impl Project {
}
}
cx.observe(worktree, |_, _, cx| cx.notify()).detach();
cx.subscribe(worktree, |project, worktree, event, cx| {
let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
match event {
worktree::Event::UpdatedEntries(changes) => {
cx.emit(Event::WorktreeUpdatedEntries(
worktree.read(cx).id(),
changes.clone(),
));
project
.client()
.telemetry()
.report_discovered_project_events(worktree_id, changes);
}
worktree::Event::UpdatedGitRepositories(_) => {
cx.emit(Event::WorktreeUpdatedGitRepositories(worktree_id));
}
worktree::Event::DeletedEntry(id) => cx.emit(Event::DeletedEntry(worktree_id, *id)),
}
})
.detach();
cx.notify();
}
@ -4169,6 +4162,17 @@ impl Project {
pub fn git_state(&self) -> Option<&Model<GitState>> {
self.git_state.as_ref()
}
pub fn active_repository(&self, cx: &AppContext) -> Option<RepositoryHandle> {
self.git_state()
.and_then(|git_state| git_state.read(cx).active_repository())
}
pub fn all_repositories(&self, cx: &AppContext) -> Vec<RepositoryHandle> {
self.git_state()
.map(|git_state| git_state.read(cx).all_repositories())
.unwrap_or_default()
}
}
fn deserialize_code_actions(code_actions: &HashMap<String, bool>) -> Vec<lsp::CodeActionKind> {