Detailed changes
@@ -308,7 +308,7 @@ impl Server {
.add_request_handler(forward_read_only_project_request::<proto::InlayHints>)
.add_request_handler(forward_read_only_project_request::<proto::ResolveInlayHint>)
.add_request_handler(forward_read_only_project_request::<proto::OpenBufferByPath>)
- .add_request_handler(forward_read_only_project_request::<proto::GitBranches>)
+ .add_request_handler(forward_read_only_project_request::<proto::GitGetBranches>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUnstagedDiff>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUncommittedDiff>)
.add_request_handler(
@@ -405,6 +405,8 @@ impl Server {
.add_request_handler(forward_read_only_project_request::<proto::GitCheckoutFiles>)
.add_request_handler(forward_mutating_project_request::<proto::SetIndexText>)
.add_request_handler(forward_mutating_project_request::<proto::OpenCommitMessageBuffer>)
+ .add_request_handler(forward_mutating_project_request::<proto::GitCreateBranch>)
+ .add_request_handler(forward_mutating_project_request::<proto::GitChangeBranch>)
.add_message_handler(broadcast_project_message_from_host::<proto::AdvertiseContexts>)
.add_message_handler(update_context)
.add_request_handler({
@@ -6741,19 +6741,24 @@ async fn test_remote_git_branches(
.collect::<HashSet<_>>();
let (project_a, worktree_id) = client_a.build_local_project("/project", cx_a).await;
+
let project_id = active_call_a
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await
.unwrap();
let project_b = client_b.join_remote_project(project_id, cx_b).await;
- let root_path = ProjectPath::root_path(worktree_id);
- // Client A sees that a guest has joined.
+ // Client A sees that a guest has joined and the repo has been populated
executor.run_until_parked();
+ let repo_b = cx_b.update(|cx| project_b.read(cx).active_repository(cx).unwrap());
+
+ let root_path = ProjectPath::root_path(worktree_id);
+
let branches_b = cx_b
- .update(|cx| project_b.update(cx, |project, cx| project.branches(root_path.clone(), cx)))
+ .update(|cx| repo_b.update(cx, |repository, _| repository.branches()))
.await
+ .unwrap()
.unwrap();
let new_branch = branches[2];
@@ -6765,13 +6770,10 @@ async fn test_remote_git_branches(
assert_eq!(branches_b, branches_set);
- cx_b.update(|cx| {
- project_b.update(cx, |project, cx| {
- project.update_or_create_branch(root_path.clone(), new_branch.to_string(), cx)
- })
- })
- .await
- .unwrap();
+ cx_b.update(|cx| repo_b.read(cx).change_branch(new_branch.to_string()))
+ .await
+ .unwrap()
+ .unwrap();
executor.run_until_parked();
@@ -6789,11 +6791,21 @@ async fn test_remote_git_branches(
// Also try creating a new branch
cx_b.update(|cx| {
- project_b.update(cx, |project, cx| {
- project.update_or_create_branch(root_path.clone(), "totally-new-branch".to_string(), cx)
- })
+ repo_b
+ .read(cx)
+ .create_branch("totally-new-branch".to_string())
+ })
+ .await
+ .unwrap()
+ .unwrap();
+
+ cx_b.update(|cx| {
+ repo_b
+ .read(cx)
+ .change_branch("totally-new-branch".to_string())
})
.await
+ .unwrap()
.unwrap();
executor.run_until_parked();
@@ -276,11 +276,13 @@ async fn test_ssh_collaboration_git_branches(
// has some git repositories
executor.run_until_parked();
+ let repo_b = cx_b.update(|cx| project_b.read(cx).active_repository(cx).unwrap());
let root_path = ProjectPath::root_path(worktree_id);
let branches_b = cx_b
- .update(|cx| project_b.update(cx, |project, cx| project.branches(root_path.clone(), cx)))
+ .update(|cx| repo_b.read(cx).branches())
.await
+ .unwrap()
.unwrap();
let new_branch = branches[2];
@@ -292,13 +294,10 @@ async fn test_ssh_collaboration_git_branches(
assert_eq!(&branches_b, &branches_set);
- cx_b.update(|cx| {
- project_b.update(cx, |project, cx| {
- project.update_or_create_branch(root_path.clone(), new_branch.to_string(), cx)
- })
- })
- .await
- .unwrap();
+ cx_b.update(|cx| repo_b.read(cx).change_branch(new_branch.to_string()))
+ .await
+ .unwrap()
+ .unwrap();
executor.run_until_parked();
@@ -318,11 +317,21 @@ async fn test_ssh_collaboration_git_branches(
// Also try creating a new branch
cx_b.update(|cx| {
- project_b.update(cx, |project, cx| {
- project.update_or_create_branch(root_path.clone(), "totally-new-branch".to_string(), cx)
- })
+ repo_b
+ .read(cx)
+ .create_branch("totally-new-branch".to_string())
+ })
+ .await
+ .unwrap()
+ .unwrap();
+
+ cx_b.update(|cx| {
+ repo_b
+ .read(cx)
+ .change_branch("totally-new-branch".to_string())
})
.await
+ .unwrap()
.unwrap();
executor.run_until_parked();
@@ -1,4 +1,4 @@
-use anyhow::Context as _;
+use anyhow::{anyhow, Context as _};
use fuzzy::{StringMatch, StringMatchCandidate};
use git::repository::Branch;
@@ -8,7 +8,7 @@ use gpui::{
Task, Window,
};
use picker::{Picker, PickerDelegate};
-use project::{Project, ProjectPath};
+use project::git::Repository;
use std::sync::Arc;
use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing, PopoverMenuHandle};
use util::ResultExt;
@@ -28,16 +28,20 @@ pub fn open(
window: &mut Window,
cx: &mut Context<Workspace>,
) {
- let project = workspace.project().clone();
+ let repository = workspace.project().read(cx).active_repository(cx).clone();
let style = BranchListStyle::Modal;
workspace.toggle_modal(window, cx, |window, cx| {
- BranchList::new(project, style, 34., window, cx)
+ BranchList::new(repository, style, 34., window, cx)
})
}
-pub fn popover(project: Entity<Project>, window: &mut Window, cx: &mut App) -> Entity<BranchList> {
+pub fn popover(
+ repository: Option<Entity<Repository>>,
+ window: &mut Window,
+ cx: &mut App,
+) -> Entity<BranchList> {
cx.new(|cx| {
- let list = BranchList::new(project, BranchListStyle::Popover, 15., window, cx);
+ let list = BranchList::new(repository, BranchListStyle::Popover, 15., window, cx);
list.focus_handle(cx).focus(window);
list
})
@@ -58,22 +62,21 @@ pub struct BranchList {
impl BranchList {
fn new(
- project_handle: Entity<Project>,
+ repository: Option<Entity<Repository>>,
style: BranchListStyle,
rem_width: f32,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let popover_handle = PopoverMenuHandle::default();
- let project = project_handle.read(cx);
- let all_branches_request = project
- .visible_worktrees(cx)
- .next()
- .map(|worktree| project.branches(ProjectPath::root_path(worktree.read(cx).id()), cx))
- .context("No worktrees found");
+ let all_branches_request = repository
+ .clone()
+ .map(|repository| repository.read(cx).branches());
cx.spawn_in(window, |this, mut cx| async move {
- let all_branches = all_branches_request?.await?;
+ let all_branches = all_branches_request
+ .context("No active repository")?
+ .await??;
this.update_in(&mut cx, |this, window, cx| {
this.picker.update(cx, |picker, cx| {
@@ -86,7 +89,7 @@ impl BranchList {
})
.detach_and_log_err(cx);
- let delegate = BranchListDelegate::new(project_handle.clone(), style, 20);
+ let delegate = BranchListDelegate::new(repository.clone(), style, 20);
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
let _subscription = cx.subscribe(&picker, |_, _, _, cx| {
@@ -145,7 +148,7 @@ impl BranchEntry {
pub struct BranchListDelegate {
matches: Vec<BranchEntry>,
all_branches: Option<Vec<Branch>>,
- project: Entity<Project>,
+ repo: Option<Entity<Repository>>,
style: BranchListStyle,
selected_index: usize,
last_query: String,
@@ -155,13 +158,13 @@ pub struct BranchListDelegate {
impl BranchListDelegate {
fn new(
- project: Entity<Project>,
+ repo: Option<Entity<Repository>>,
style: BranchListStyle,
branch_name_trailoff_after: usize,
) -> Self {
Self {
matches: vec![],
- project,
+ repo,
style,
all_branches: None,
selected_index: 0,
@@ -280,14 +283,16 @@ impl PickerDelegate for BranchListDelegate {
return;
};
- let current_branch = self.project.update(cx, |project, cx| {
- project
- .active_repository(cx)
- .and_then(|repo| repo.read(cx).current_branch())
- .map(|branch| branch.name.to_string())
+ let current_branch = self.repo.as_ref().map(|repo| {
+ repo.update(cx, |repo, _| {
+ repo.current_branch().map(|branch| branch.name.clone())
+ })
});
- if current_branch == Some(branch.name().to_string()) {
+ if current_branch
+ .flatten()
+ .is_some_and(|current_branch| current_branch == branch.name())
+ {
cx.emit(DismissEvent);
return;
}
@@ -296,19 +301,33 @@ impl PickerDelegate for BranchListDelegate {
let branch = branch.clone();
|picker, mut cx| async move {
let branch_change_task = picker.update(&mut cx, |this, cx| {
- let project = this.delegate.project.read(cx);
- let branch_to_checkout = match branch {
- BranchEntry::Branch(branch) => branch.string,
- BranchEntry::History(string) => string,
- BranchEntry::NewBranch { name: branch_name } => branch_name,
- };
- let worktree = project
- .visible_worktrees(cx)
- .next()
- .context("worktree disappeared")?;
- let repository = ProjectPath::root_path(worktree.read(cx).id());
-
- anyhow::Ok(project.update_or_create_branch(repository, branch_to_checkout, cx))
+ let repo = this
+ .delegate
+ .repo
+ .as_ref()
+ .ok_or_else(|| anyhow!("No active repository"))?
+ .clone();
+
+ let cx = cx.to_async();
+
+ anyhow::Ok(async move {
+ match branch {
+ BranchEntry::Branch(StringMatch {
+ string: branch_name,
+ ..
+ })
+ | BranchEntry::History(branch_name) => {
+ cx.update(|cx| repo.read(cx).change_branch(branch_name))?
+ .await?
+ }
+ BranchEntry::NewBranch { name: branch_name } => {
+ cx.update(|cx| repo.read(cx).create_branch(branch_name.clone()))?
+ .await??;
+ cx.update(|cx| repo.read(cx).change_branch(branch_name))?
+ .await?
+ }
+ }
+ })
})??;
branch_change_task.await?;
@@ -316,7 +335,7 @@ impl PickerDelegate for BranchListDelegate {
picker.update(&mut cx, |_, cx| {
cx.emit(DismissEvent);
- Ok::<(), anyhow::Error>(())
+ anyhow::Ok(())
})
}
})
@@ -4,7 +4,6 @@ use crate::branch_picker::{self, BranchList};
use crate::git_panel::{commit_message_editor, GitPanel};
use git::{Commit, ShowCommitEditor};
use panel::{panel_button, panel_editor_style, panel_filled_button};
-use project::Project;
use ui::{prelude::*, KeybindingHint, PopoverMenu, Tooltip};
use editor::{Editor, EditorElement};
@@ -129,10 +128,9 @@ impl CommitModal {
active_index,
};
- let project = workspace.project().clone();
workspace.open_panel::<GitPanel>(window, cx);
workspace.toggle_modal(window, cx, move |window, cx| {
- CommitModal::new(git_panel, restore_dock_position, project, window, cx)
+ CommitModal::new(git_panel, restore_dock_position, window, cx)
})
});
}
@@ -140,11 +138,11 @@ impl CommitModal {
fn new(
git_panel: Entity<GitPanel>,
restore_dock: RestoreDock,
- project: Entity<Project>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let panel = git_panel.read(cx);
+ let active_repository = panel.active_repository.clone();
let suggested_commit_message = panel.suggest_commit_message();
let commit_editor = git_panel.update(cx, |git_panel, cx| {
@@ -188,7 +186,7 @@ impl CommitModal {
let properties = ModalContainerProperties::new(window, 50);
Self {
- branch_list: branch_picker::popover(project.clone(), window, cx),
+ branch_list: branch_picker::popover(active_repository.clone(), window, cx),
git_panel,
commit_editor,
restore_dock,
@@ -3327,6 +3327,11 @@ impl RenderOnce for PanelRepoFooter {
.as_ref()
.map(|panel| panel.read(cx).project.clone());
+ let repo = self
+ .git_panel
+ .as_ref()
+ .and_then(|panel| panel.read(cx).active_repository.clone());
+
let single_repo = project
.as_ref()
.map(|project| project.read(cx).all_repositories(cx).len() == 1)
@@ -3366,7 +3371,7 @@ impl RenderOnce for PanelRepoFooter {
});
let branch_selector = PopoverMenu::new("popover-button")
- .menu(move |window, cx| Some(branch_picker::popover(project.clone()?, window, cx)))
+ .menu(move |window, cx| Some(branch_picker::popover(repo.clone(), window, cx)))
.trigger_with_tooltip(
branch_selector_button,
Tooltip::for_action_title("Switch Branch", &zed_actions::git::Branch),
@@ -96,6 +96,9 @@ impl GitStore {
pub fn init(client: &AnyProtoClient) {
client.add_entity_request_handler(Self::handle_get_remotes);
+ client.add_entity_request_handler(Self::handle_get_branches);
+ client.add_entity_request_handler(Self::handle_change_branch);
+ client.add_entity_request_handler(Self::handle_create_branch);
client.add_entity_request_handler(Self::handle_push);
client.add_entity_request_handler(Self::handle_pull);
client.add_entity_request_handler(Self::handle_fetch);
@@ -459,6 +462,67 @@ impl GitStore {
})
}
+ async fn handle_get_branches(
+ this: Entity<Self>,
+ envelope: TypedEnvelope<proto::GitGetBranches>,
+ mut cx: AsyncApp,
+ ) -> Result<proto::GitBranchesResponse> {
+ let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
+ let work_directory_id = ProjectEntryId::from_proto(envelope.payload.work_directory_id);
+ let repository_handle =
+ Self::repository_for_request(&this, worktree_id, work_directory_id, &mut cx)?;
+
+ let branches = repository_handle
+ .update(&mut cx, |repository_handle, _| repository_handle.branches())?
+ .await??;
+
+ Ok(proto::GitBranchesResponse {
+ branches: branches
+ .into_iter()
+ .map(|branch| worktree::branch_to_proto(&branch))
+ .collect::<Vec<_>>(),
+ })
+ }
+ async fn handle_create_branch(
+ this: Entity<Self>,
+ envelope: TypedEnvelope<proto::GitCreateBranch>,
+ mut cx: AsyncApp,
+ ) -> Result<proto::Ack> {
+ let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
+ let work_directory_id = ProjectEntryId::from_proto(envelope.payload.work_directory_id);
+ let repository_handle =
+ Self::repository_for_request(&this, worktree_id, work_directory_id, &mut cx)?;
+ let branch_name = envelope.payload.branch_name;
+
+ repository_handle
+ .update(&mut cx, |repository_handle, _| {
+ repository_handle.create_branch(branch_name)
+ })?
+ .await??;
+
+ Ok(proto::Ack {})
+ }
+
+ async fn handle_change_branch(
+ this: Entity<Self>,
+ envelope: TypedEnvelope<proto::GitChangeBranch>,
+ mut cx: AsyncApp,
+ ) -> Result<proto::Ack> {
+ let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
+ let work_directory_id = ProjectEntryId::from_proto(envelope.payload.work_directory_id);
+ let repository_handle =
+ Self::repository_for_request(&this, worktree_id, work_directory_id, &mut cx)?;
+ let branch_name = envelope.payload.branch_name;
+
+ repository_handle
+ .update(&mut cx, |repository_handle, _| {
+ repository_handle.change_branch(branch_name)
+ })?
+ .await??;
+
+ Ok(proto::Ack {})
+ }
+
async fn handle_show(
this: Entity<Self>,
envelope: TypedEnvelope<proto::GitShow>,
@@ -1279,4 +1343,84 @@ impl Repository {
}
})
}
+
+ pub fn branches(&self) -> oneshot::Receiver<Result<Vec<Branch>>> {
+ self.send_job(|repo| async move {
+ match repo {
+ GitRepo::Local(git_repository) => git_repository.branches(),
+ GitRepo::Remote {
+ project_id,
+ client,
+ worktree_id,
+ work_directory_id,
+ } => {
+ let response = client
+ .request(proto::GitGetBranches {
+ project_id: project_id.0,
+ worktree_id: worktree_id.to_proto(),
+ work_directory_id: work_directory_id.to_proto(),
+ })
+ .await?;
+
+ let branches = response
+ .branches
+ .into_iter()
+ .map(|branch| worktree::proto_to_branch(&branch))
+ .collect();
+
+ Ok(branches)
+ }
+ }
+ })
+ }
+
+ pub fn create_branch(&self, branch_name: String) -> oneshot::Receiver<Result<()>> {
+ self.send_job(|repo| async move {
+ match repo {
+ GitRepo::Local(git_repository) => git_repository.create_branch(&branch_name),
+ GitRepo::Remote {
+ project_id,
+ client,
+ worktree_id,
+ work_directory_id,
+ } => {
+ client
+ .request(proto::GitCreateBranch {
+ project_id: project_id.0,
+ worktree_id: worktree_id.to_proto(),
+ work_directory_id: work_directory_id.to_proto(),
+ branch_name,
+ })
+ .await?;
+
+ Ok(())
+ }
+ }
+ })
+ }
+
+ pub fn change_branch(&self, branch_name: String) -> oneshot::Receiver<Result<()>> {
+ self.send_job(|repo| async move {
+ match repo {
+ GitRepo::Local(git_repository) => git_repository.change_branch(&branch_name),
+ GitRepo::Remote {
+ project_id,
+ client,
+ worktree_id,
+ work_directory_id,
+ } => {
+ client
+ .request(proto::GitChangeBranch {
+ project_id: project_id.0,
+ worktree_id: worktree_id.to_proto(),
+ work_directory_id: work_directory_id.to_proto(),
+ branch_name,
+ })
+ .await?;
+
+ Ok(())
+ }
+ }
+ })
+ }
}
@@ -48,7 +48,7 @@ use image_store::{ImageItemEvent, ImageStoreEvent};
use ::git::{
blame::Blame,
- repository::{Branch, GitRepository, RepoPath},
+ repository::{GitRepository, RepoPath},
status::FileStatus,
};
use gpui::{
@@ -3705,21 +3705,6 @@ impl Project {
worktree.get_local_repo(&root_entry)?.repo().clone().into()
}
- pub fn branches(&self, project_path: ProjectPath, cx: &App) -> Task<Result<Vec<Branch>>> {
- self.worktree_store().read(cx).branches(project_path, cx)
- }
-
- pub fn update_or_create_branch(
- &self,
- repository: ProjectPath,
- new_branch: String,
- cx: &App,
- ) -> Task<Result<()>> {
- self.worktree_store()
- .read(cx)
- .update_or_create_branch(repository, new_branch, cx)
- }
-
pub fn blame_buffer(
&self,
buffer: &Entity<Buffer>,
@@ -27,10 +27,7 @@ use smol::{
};
use text::ReplicaId;
use util::{paths::SanitizedPath, ResultExt};
-use worktree::{
- branch_to_proto, Entry, ProjectEntryId, UpdatedEntriesSet, Worktree, WorktreeId,
- WorktreeSettings,
-};
+use worktree::{Entry, ProjectEntryId, UpdatedEntriesSet, Worktree, WorktreeId, WorktreeSettings};
use crate::{search::SearchQuery, ProjectPath};
@@ -83,8 +80,6 @@ impl WorktreeStore {
client.add_entity_request_handler(Self::handle_delete_project_entry);
client.add_entity_request_handler(Self::handle_expand_project_entry);
client.add_entity_request_handler(Self::handle_expand_all_for_project_entry);
- client.add_entity_request_handler(Self::handle_git_branches);
- client.add_entity_request_handler(Self::handle_update_branch);
}
pub fn local(retain_worktrees: bool, fs: Arc<dyn Fs>) -> Self {
@@ -890,150 +885,6 @@ impl WorktreeStore {
Ok(())
}
- pub fn branches(
- &self,
- project_path: ProjectPath,
- cx: &App,
- ) -> Task<Result<Vec<git::repository::Branch>>> {
- let Some(worktree) = self.worktree_for_id(project_path.worktree_id, cx) else {
- return Task::ready(Err(anyhow!("No worktree found for ProjectPath")));
- };
-
- match worktree.read(cx) {
- Worktree::Local(local_worktree) => {
- let branches = util::maybe!({
- let worktree_error = |error| {
- format!(
- "{} for worktree {}",
- error,
- local_worktree.abs_path().to_string_lossy()
- )
- };
-
- let entry = local_worktree
- .git_entry(project_path.path)
- .with_context(|| worktree_error("No git entry found"))?;
-
- let repo = local_worktree
- .get_local_repo(&entry)
- .with_context(|| worktree_error("No repository found"))?
- .repo()
- .clone();
-
- repo.branches()
- });
-
- Task::ready(branches)
- }
- Worktree::Remote(remote_worktree) => {
- let request = remote_worktree.client().request(proto::GitBranches {
- project_id: remote_worktree.project_id(),
- repository: Some(proto::ProjectPath {
- worktree_id: project_path.worktree_id.to_proto(),
- path: project_path.path.to_proto(), // Root path
- }),
- });
-
- cx.background_spawn(async move {
- let response = request.await?;
-
- let branches = response
- .branches
- .into_iter()
- .map(|proto_branch| git::repository::Branch {
- is_head: proto_branch.is_head,
- name: proto_branch.name.into(),
- upstream: proto_branch.upstream.map(|upstream| {
- git::repository::Upstream {
- ref_name: upstream.ref_name.into(),
- tracking: upstream
- .tracking
- .map(|tracking| {
- git::repository::UpstreamTracking::Tracked(
- git::repository::UpstreamTrackingStatus {
- ahead: tracking.ahead as u32,
- behind: tracking.behind as u32,
- },
- )
- })
- .unwrap_or(git::repository::UpstreamTracking::Gone),
- }
- }),
- most_recent_commit: proto_branch.most_recent_commit.map(|commit| {
- git::repository::CommitSummary {
- sha: commit.sha.into(),
- subject: commit.subject.into(),
- commit_timestamp: commit.commit_timestamp,
- }
- }),
- })
- .collect();
-
- Ok(branches)
- })
- }
- }
- }
-
- pub fn update_or_create_branch(
- &self,
- repository: ProjectPath,
- new_branch: String,
- cx: &App,
- ) -> Task<Result<()>> {
- let Some(worktree) = self.worktree_for_id(repository.worktree_id, cx) else {
- return Task::ready(Err(anyhow!("No worktree found for ProjectPath")));
- };
-
- match worktree.read(cx) {
- Worktree::Local(local_worktree) => {
- let result = util::maybe!({
- let worktree_error = |error| {
- format!(
- "{} for worktree {}",
- error,
- local_worktree.abs_path().to_string_lossy()
- )
- };
-
- let entry = local_worktree
- .git_entry(repository.path)
- .with_context(|| worktree_error("No git entry found"))?;
-
- let repo = local_worktree
- .get_local_repo(&entry)
- .with_context(|| worktree_error("No repository found"))?
- .repo()
- .clone();
-
- if !repo.branch_exits(&new_branch)? {
- repo.create_branch(&new_branch)?;
- }
-
- repo.change_branch(&new_branch)?;
- Ok(())
- });
-
- Task::ready(result)
- }
- Worktree::Remote(remote_worktree) => {
- let request = remote_worktree.client().request(proto::UpdateGitBranch {
- project_id: remote_worktree.project_id(),
- repository: Some(proto::ProjectPath {
- worktree_id: repository.worktree_id.to_proto(),
- path: repository.path.to_proto(), // Root path
- }),
- branch_name: new_branch,
- });
-
- cx.background_spawn(async move {
- request.await?;
- Ok(())
- })
- }
- }
- }
-
async fn filter_paths(
fs: &Arc<dyn Fs>,
mut input: Receiver<MatchingEntry>,
@@ -1130,54 +981,6 @@ impl WorktreeStore {
.ok_or_else(|| anyhow!("invalid request"))?;
Worktree::handle_expand_all_for_entry(worktree, envelope.payload, cx).await
}
-
- pub async fn handle_git_branches(
- this: Entity<Self>,
- branches: TypedEnvelope<proto::GitBranches>,
- cx: AsyncApp,
- ) -> Result<proto::GitBranchesResponse> {
- let project_path = branches
- .payload
- .repository
- .clone()
- .context("Invalid GitBranches call")?;
- let project_path = ProjectPath {
- worktree_id: WorktreeId::from_proto(project_path.worktree_id),
- path: Arc::<Path>::from_proto(project_path.path),
- };
-
- let branches = this
- .read_with(&cx, |this, cx| this.branches(project_path, cx))?
- .await?;
-
- Ok(proto::GitBranchesResponse {
- branches: branches.iter().map(branch_to_proto).collect(),
- })
- }
-
- pub async fn handle_update_branch(
- this: Entity<Self>,
- update_branch: TypedEnvelope<proto::UpdateGitBranch>,
- cx: AsyncApp,
- ) -> Result<proto::Ack> {
- let project_path = update_branch
- .payload
- .repository
- .clone()
- .context("Invalid GitBranches call")?;
- let project_path = ProjectPath {
- worktree_id: WorktreeId::from_proto(project_path.worktree_id),
- path: Arc::<Path>::from_proto(project_path.path),
- };
- let new_branch = update_branch.payload.branch_name;
-
- this.read_with(&cx, |this, cx| {
- this.update_or_create_branch(project_path, new_branch, cx)
- })?
- .await?;
-
- Ok(proto::Ack {})
- }
}
#[derive(Clone, Debug)]
@@ -1,3 +1,4 @@
+
syntax = "proto3";
package zed.messages;
@@ -278,7 +279,6 @@ message Envelope {
LanguageServerPromptRequest language_server_prompt_request = 268;
LanguageServerPromptResponse language_server_prompt_response = 269;
- GitBranches git_branches = 270;
GitBranchesResponse git_branches_response = 271;
UpdateGitBranch update_git_branch = 272;
@@ -332,7 +332,10 @@ message Envelope {
ApplyCodeActionKind apply_code_action_kind = 309;
ApplyCodeActionKindResponse apply_code_action_kind_response = 310;
- RemoteMessageResponse remote_message_response = 311; // current max
+ RemoteMessageResponse remote_message_response = 311;
+ GitGetBranches git_get_branches = 312;
+ GitCreateBranch git_create_branch = 313;
+ GitChangeBranch git_change_branch = 314; // current max
}
reserved 87 to 88;
@@ -348,6 +351,7 @@ message Envelope {
reserved 221;
reserved 224 to 229;
reserved 246;
+ reserved 270;
reserved 247 to 254;
reserved 255 to 256;
}
@@ -2851,3 +2855,23 @@ message RemoteMessageResponse {
string stdout = 1;
string stderr = 2;
}
+
+message GitGetBranches {
+ uint64 project_id = 1;
+ uint64 worktree_id = 2;
+ uint64 work_directory_id = 3;
+}
+
+message GitCreateBranch {
+ uint64 project_id = 1;
+ uint64 worktree_id = 2;
+ uint64 work_directory_id = 3;
+ string branch_name = 4;
+}
+
+message GitChangeBranch {
+ uint64 project_id = 1;
+ uint64 worktree_id = 2;
+ uint64 work_directory_id = 3;
+ string branch_name = 4;
+}
@@ -424,7 +424,7 @@ messages!(
(FlushBufferedMessages, Foreground),
(LanguageServerPromptRequest, Foreground),
(LanguageServerPromptResponse, Foreground),
- (GitBranches, Background),
+ (GitGetBranches, Background),
(GitBranchesResponse, Background),
(UpdateGitBranch, Background),
(ListToolchains, Foreground),
@@ -452,6 +452,8 @@ messages!(
(GetRemotesResponse, Background),
(Pull, Background),
(RemoteMessageResponse, Background),
+ (GitCreateBranch, Background),
+ (GitChangeBranch, Background),
);
request_messages!(
@@ -575,7 +577,7 @@ request_messages!(
(GetPermalinkToLine, GetPermalinkToLineResponse),
(FlushBufferedMessages, Ack),
(LanguageServerPromptRequest, LanguageServerPromptResponse),
- (GitBranches, GitBranchesResponse),
+ (GitGetBranches, GitBranchesResponse),
(UpdateGitBranch, Ack),
(ListToolchains, ListToolchainsResponse),
(ActivateToolchain, Ack),
@@ -594,6 +596,8 @@ request_messages!(
(Fetch, RemoteMessageResponse),
(GetRemotes, GetRemotesResponse),
(Pull, RemoteMessageResponse),
+ (GitCreateBranch, Ack),
+ (GitChangeBranch, Ack),
);
entity_messages!(
@@ -679,7 +683,7 @@ entity_messages!(
OpenServerSettings,
GetPermalinkToLine,
LanguageServerPromptRequest,
- GitBranches,
+ GitGetBranches,
UpdateGitBranch,
ListToolchains,
ActivateToolchain,
@@ -695,6 +699,8 @@ entity_messages!(
Fetch,
GetRemotes,
Pull,
+ GitChangeBranch,
+ GitCreateBranch,
);
entity_messages!(
@@ -1344,9 +1344,12 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
// Give the worktree a bit of time to index the file system
cx.run_until_parked();
- let remote_branches = project
- .update(cx, |project, cx| project.branches(root_path.clone(), cx))
+ let repository = project.update(cx, |project, cx| project.active_repository(cx).unwrap());
+
+ let remote_branches = repository
+ .update(cx, |repository, _| repository.branches())
.await
+ .unwrap()
.unwrap();
let new_branch = branches[2];
@@ -1358,13 +1361,10 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
assert_eq!(&remote_branches, &branches_set);
- cx.update(|cx| {
- project.update(cx, |project, cx| {
- project.update_or_create_branch(root_path.clone(), new_branch.to_string(), cx)
- })
- })
- .await
- .unwrap();
+ cx.update(|cx| repository.read(cx).change_branch(new_branch.to_string()))
+ .await
+ .unwrap()
+ .unwrap();
cx.run_until_parked();
@@ -1384,11 +1384,21 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
// Also try creating a new branch
cx.update(|cx| {
- project.update(cx, |project, cx| {
- project.update_or_create_branch(root_path.clone(), "totally-new-branch".to_string(), cx)
- })
+ repository
+ .read(cx)
+ .create_branch("totally-new-branch".to_string())
+ })
+ .await
+ .unwrap()
+ .unwrap();
+
+ cx.update(|cx| {
+ repository
+ .read(cx)
+ .change_branch("totally-new-branch".to_string())
})
.await
+ .unwrap()
.unwrap();
cx.run_until_parked();