Fix git branches in non-active repository (#26148)
Release Notes: - Git Beta: Fixed a bug where the branch selector would only show for the first repository opened. --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com> Co-authored-by: Richard Feldman <oss@rtfeldman.com>
This commit is contained in:
parent
2a919ad1d0
commit
9d54e63a11
12 changed files with 316 additions and 299 deletions
|
@ -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::InlayHints>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::ResolveInlayHint>)
|
.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::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::OpenUnstagedDiff>)
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::OpenUncommittedDiff>)
|
.add_request_handler(forward_read_only_project_request::<proto::OpenUncommittedDiff>)
|
||||||
.add_request_handler(
|
.add_request_handler(
|
||||||
|
@ -405,6 +405,8 @@ impl Server {
|
||||||
.add_request_handler(forward_read_only_project_request::<proto::GitCheckoutFiles>)
|
.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::SetIndexText>)
|
||||||
.add_request_handler(forward_mutating_project_request::<proto::OpenCommitMessageBuffer>)
|
.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(broadcast_project_message_from_host::<proto::AdvertiseContexts>)
|
||||||
.add_message_handler(update_context)
|
.add_message_handler(update_context)
|
||||||
.add_request_handler({
|
.add_request_handler({
|
||||||
|
|
|
@ -6741,19 +6741,24 @@ async fn test_remote_git_branches(
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
let (project_a, worktree_id) = client_a.build_local_project("/project", cx_a).await;
|
let (project_a, worktree_id) = client_a.build_local_project("/project", cx_a).await;
|
||||||
|
|
||||||
let project_id = active_call_a
|
let project_id = active_call_a
|
||||||
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
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 and the repo has been populated
|
||||||
// Client A sees that a guest has joined.
|
|
||||||
executor.run_until_parked();
|
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
|
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
|
.await
|
||||||
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let new_branch = branches[2];
|
let new_branch = branches[2];
|
||||||
|
@ -6765,13 +6770,10 @@ async fn test_remote_git_branches(
|
||||||
|
|
||||||
assert_eq!(branches_b, branches_set);
|
assert_eq!(branches_b, branches_set);
|
||||||
|
|
||||||
cx_b.update(|cx| {
|
cx_b.update(|cx| repo_b.read(cx).change_branch(new_branch.to_string()))
|
||||||
project_b.update(cx, |project, cx| {
|
.await
|
||||||
project.update_or_create_branch(root_path.clone(), new_branch.to_string(), cx)
|
.unwrap()
|
||||||
})
|
.unwrap();
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
|
||||||
|
@ -6789,11 +6791,21 @@ async fn test_remote_git_branches(
|
||||||
|
|
||||||
// Also try creating a new branch
|
// Also try creating a new branch
|
||||||
cx_b.update(|cx| {
|
cx_b.update(|cx| {
|
||||||
project_b.update(cx, |project, cx| {
|
repo_b
|
||||||
project.update_or_create_branch(root_path.clone(), "totally-new-branch".to_string(), cx)
|
.read(cx)
|
||||||
})
|
.create_branch("totally-new-branch".to_string())
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
cx_b.update(|cx| {
|
||||||
|
repo_b
|
||||||
|
.read(cx)
|
||||||
|
.change_branch("totally-new-branch".to_string())
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
|
|
@ -276,11 +276,13 @@ async fn test_ssh_collaboration_git_branches(
|
||||||
// has some git repositories
|
// has some git repositories
|
||||||
executor.run_until_parked();
|
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 root_path = ProjectPath::root_path(worktree_id);
|
||||||
|
|
||||||
let branches_b = cx_b
|
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
|
.await
|
||||||
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let new_branch = branches[2];
|
let new_branch = branches[2];
|
||||||
|
@ -292,13 +294,10 @@ async fn test_ssh_collaboration_git_branches(
|
||||||
|
|
||||||
assert_eq!(&branches_b, &branches_set);
|
assert_eq!(&branches_b, &branches_set);
|
||||||
|
|
||||||
cx_b.update(|cx| {
|
cx_b.update(|cx| repo_b.read(cx).change_branch(new_branch.to_string()))
|
||||||
project_b.update(cx, |project, cx| {
|
.await
|
||||||
project.update_or_create_branch(root_path.clone(), new_branch.to_string(), cx)
|
.unwrap()
|
||||||
})
|
.unwrap();
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
|
||||||
|
@ -318,11 +317,21 @@ async fn test_ssh_collaboration_git_branches(
|
||||||
|
|
||||||
// Also try creating a new branch
|
// Also try creating a new branch
|
||||||
cx_b.update(|cx| {
|
cx_b.update(|cx| {
|
||||||
project_b.update(cx, |project, cx| {
|
repo_b
|
||||||
project.update_or_create_branch(root_path.clone(), "totally-new-branch".to_string(), cx)
|
.read(cx)
|
||||||
})
|
.create_branch("totally-new-branch".to_string())
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
cx_b.update(|cx| {
|
||||||
|
repo_b
|
||||||
|
.read(cx)
|
||||||
|
.change_branch("totally-new-branch".to_string())
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
executor.run_until_parked();
|
executor.run_until_parked();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::Context as _;
|
use anyhow::{anyhow, Context as _};
|
||||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||||
|
|
||||||
use git::repository::Branch;
|
use git::repository::Branch;
|
||||||
|
@ -8,7 +8,7 @@ use gpui::{
|
||||||
Task, Window,
|
Task, Window,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use project::{Project, ProjectPath};
|
use project::git::Repository;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing, PopoverMenuHandle};
|
use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing, PopoverMenuHandle};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
@ -28,16 +28,20 @@ pub fn open(
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Workspace>,
|
cx: &mut Context<Workspace>,
|
||||||
) {
|
) {
|
||||||
let project = workspace.project().clone();
|
let repository = workspace.project().read(cx).active_repository(cx).clone();
|
||||||
let style = BranchListStyle::Modal;
|
let style = BranchListStyle::Modal;
|
||||||
workspace.toggle_modal(window, cx, |window, cx| {
|
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| {
|
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.focus_handle(cx).focus(window);
|
||||||
list
|
list
|
||||||
})
|
})
|
||||||
|
@ -58,22 +62,21 @@ pub struct BranchList {
|
||||||
|
|
||||||
impl BranchList {
|
impl BranchList {
|
||||||
fn new(
|
fn new(
|
||||||
project_handle: Entity<Project>,
|
repository: Option<Entity<Repository>>,
|
||||||
style: BranchListStyle,
|
style: BranchListStyle,
|
||||||
rem_width: f32,
|
rem_width: f32,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let popover_handle = PopoverMenuHandle::default();
|
let popover_handle = PopoverMenuHandle::default();
|
||||||
let project = project_handle.read(cx);
|
let all_branches_request = repository
|
||||||
let all_branches_request = project
|
.clone()
|
||||||
.visible_worktrees(cx)
|
.map(|repository| repository.read(cx).branches());
|
||||||
.next()
|
|
||||||
.map(|worktree| project.branches(ProjectPath::root_path(worktree.read(cx).id()), cx))
|
|
||||||
.context("No worktrees found");
|
|
||||||
|
|
||||||
cx.spawn_in(window, |this, mut cx| async move {
|
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.update_in(&mut cx, |this, window, cx| {
|
||||||
this.picker.update(cx, |picker, cx| {
|
this.picker.update(cx, |picker, cx| {
|
||||||
|
@ -86,7 +89,7 @@ impl BranchList {
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.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 picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||||
|
|
||||||
let _subscription = cx.subscribe(&picker, |_, _, _, cx| {
|
let _subscription = cx.subscribe(&picker, |_, _, _, cx| {
|
||||||
|
@ -145,7 +148,7 @@ impl BranchEntry {
|
||||||
pub struct BranchListDelegate {
|
pub struct BranchListDelegate {
|
||||||
matches: Vec<BranchEntry>,
|
matches: Vec<BranchEntry>,
|
||||||
all_branches: Option<Vec<Branch>>,
|
all_branches: Option<Vec<Branch>>,
|
||||||
project: Entity<Project>,
|
repo: Option<Entity<Repository>>,
|
||||||
style: BranchListStyle,
|
style: BranchListStyle,
|
||||||
selected_index: usize,
|
selected_index: usize,
|
||||||
last_query: String,
|
last_query: String,
|
||||||
|
@ -155,13 +158,13 @@ pub struct BranchListDelegate {
|
||||||
|
|
||||||
impl BranchListDelegate {
|
impl BranchListDelegate {
|
||||||
fn new(
|
fn new(
|
||||||
project: Entity<Project>,
|
repo: Option<Entity<Repository>>,
|
||||||
style: BranchListStyle,
|
style: BranchListStyle,
|
||||||
branch_name_trailoff_after: usize,
|
branch_name_trailoff_after: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
matches: vec![],
|
matches: vec![],
|
||||||
project,
|
repo,
|
||||||
style,
|
style,
|
||||||
all_branches: None,
|
all_branches: None,
|
||||||
selected_index: 0,
|
selected_index: 0,
|
||||||
|
@ -280,14 +283,16 @@ impl PickerDelegate for BranchListDelegate {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_branch = self.project.update(cx, |project, cx| {
|
let current_branch = self.repo.as_ref().map(|repo| {
|
||||||
project
|
repo.update(cx, |repo, _| {
|
||||||
.active_repository(cx)
|
repo.current_branch().map(|branch| branch.name.clone())
|
||||||
.and_then(|repo| repo.read(cx).current_branch())
|
})
|
||||||
.map(|branch| branch.name.to_string())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if current_branch == Some(branch.name().to_string()) {
|
if current_branch
|
||||||
|
.flatten()
|
||||||
|
.is_some_and(|current_branch| current_branch == branch.name())
|
||||||
|
{
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -296,19 +301,33 @@ impl PickerDelegate for BranchListDelegate {
|
||||||
let branch = branch.clone();
|
let branch = branch.clone();
|
||||||
|picker, mut cx| async move {
|
|picker, mut cx| async move {
|
||||||
let branch_change_task = picker.update(&mut cx, |this, cx| {
|
let branch_change_task = picker.update(&mut cx, |this, cx| {
|
||||||
let project = this.delegate.project.read(cx);
|
let repo = this
|
||||||
let branch_to_checkout = match branch {
|
.delegate
|
||||||
BranchEntry::Branch(branch) => branch.string,
|
.repo
|
||||||
BranchEntry::History(string) => string,
|
.as_ref()
|
||||||
BranchEntry::NewBranch { name: branch_name } => branch_name,
|
.ok_or_else(|| anyhow!("No active repository"))?
|
||||||
};
|
.clone();
|
||||||
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 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?;
|
branch_change_task.await?;
|
||||||
|
@ -316,7 +335,7 @@ impl PickerDelegate for BranchListDelegate {
|
||||||
picker.update(&mut cx, |_, cx| {
|
picker.update(&mut cx, |_, cx| {
|
||||||
cx.emit(DismissEvent);
|
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 crate::git_panel::{commit_message_editor, GitPanel};
|
||||||
use git::{Commit, ShowCommitEditor};
|
use git::{Commit, ShowCommitEditor};
|
||||||
use panel::{panel_button, panel_editor_style, panel_filled_button};
|
use panel::{panel_button, panel_editor_style, panel_filled_button};
|
||||||
use project::Project;
|
|
||||||
use ui::{prelude::*, KeybindingHint, PopoverMenu, Tooltip};
|
use ui::{prelude::*, KeybindingHint, PopoverMenu, Tooltip};
|
||||||
|
|
||||||
use editor::{Editor, EditorElement};
|
use editor::{Editor, EditorElement};
|
||||||
|
@ -129,10 +128,9 @@ impl CommitModal {
|
||||||
active_index,
|
active_index,
|
||||||
};
|
};
|
||||||
|
|
||||||
let project = workspace.project().clone();
|
|
||||||
workspace.open_panel::<GitPanel>(window, cx);
|
workspace.open_panel::<GitPanel>(window, cx);
|
||||||
workspace.toggle_modal(window, cx, move |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(
|
fn new(
|
||||||
git_panel: Entity<GitPanel>,
|
git_panel: Entity<GitPanel>,
|
||||||
restore_dock: RestoreDock,
|
restore_dock: RestoreDock,
|
||||||
project: Entity<Project>,
|
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let panel = git_panel.read(cx);
|
let panel = git_panel.read(cx);
|
||||||
|
let active_repository = panel.active_repository.clone();
|
||||||
let suggested_commit_message = panel.suggest_commit_message();
|
let suggested_commit_message = panel.suggest_commit_message();
|
||||||
|
|
||||||
let commit_editor = git_panel.update(cx, |git_panel, cx| {
|
let commit_editor = git_panel.update(cx, |git_panel, cx| {
|
||||||
|
@ -188,7 +186,7 @@ impl CommitModal {
|
||||||
let properties = ModalContainerProperties::new(window, 50);
|
let properties = ModalContainerProperties::new(window, 50);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
branch_list: branch_picker::popover(project.clone(), window, cx),
|
branch_list: branch_picker::popover(active_repository.clone(), window, cx),
|
||||||
git_panel,
|
git_panel,
|
||||||
commit_editor,
|
commit_editor,
|
||||||
restore_dock,
|
restore_dock,
|
||||||
|
|
|
@ -3327,6 +3327,11 @@ impl RenderOnce for PanelRepoFooter {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|panel| panel.read(cx).project.clone());
|
.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
|
let single_repo = project
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|project| project.read(cx).all_repositories(cx).len() == 1)
|
.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")
|
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(
|
.trigger_with_tooltip(
|
||||||
branch_selector_button,
|
branch_selector_button,
|
||||||
Tooltip::for_action_title("Switch Branch", &zed_actions::git::Branch),
|
Tooltip::for_action_title("Switch Branch", &zed_actions::git::Branch),
|
||||||
|
|
|
@ -96,6 +96,9 @@ impl GitStore {
|
||||||
|
|
||||||
pub fn init(client: &AnyProtoClient) {
|
pub fn init(client: &AnyProtoClient) {
|
||||||
client.add_entity_request_handler(Self::handle_get_remotes);
|
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_push);
|
||||||
client.add_entity_request_handler(Self::handle_pull);
|
client.add_entity_request_handler(Self::handle_pull);
|
||||||
client.add_entity_request_handler(Self::handle_fetch);
|
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(
|
async fn handle_show(
|
||||||
this: Entity<Self>,
|
this: Entity<Self>,
|
||||||
envelope: TypedEnvelope<proto::GitShow>,
|
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::{
|
use ::git::{
|
||||||
blame::Blame,
|
blame::Blame,
|
||||||
repository::{Branch, GitRepository, RepoPath},
|
repository::{GitRepository, RepoPath},
|
||||||
status::FileStatus,
|
status::FileStatus,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -3705,21 +3705,6 @@ impl Project {
|
||||||
worktree.get_local_repo(&root_entry)?.repo().clone().into()
|
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(
|
pub fn blame_buffer(
|
||||||
&self,
|
&self,
|
||||||
buffer: &Entity<Buffer>,
|
buffer: &Entity<Buffer>,
|
||||||
|
|
|
@ -27,10 +27,7 @@ use smol::{
|
||||||
};
|
};
|
||||||
use text::ReplicaId;
|
use text::ReplicaId;
|
||||||
use util::{paths::SanitizedPath, ResultExt};
|
use util::{paths::SanitizedPath, ResultExt};
|
||||||
use worktree::{
|
use worktree::{Entry, ProjectEntryId, UpdatedEntriesSet, Worktree, WorktreeId, WorktreeSettings};
|
||||||
branch_to_proto, Entry, ProjectEntryId, UpdatedEntriesSet, Worktree, WorktreeId,
|
|
||||||
WorktreeSettings,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{search::SearchQuery, ProjectPath};
|
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_delete_project_entry);
|
||||||
client.add_entity_request_handler(Self::handle_expand_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_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 {
|
pub fn local(retain_worktrees: bool, fs: Arc<dyn Fs>) -> Self {
|
||||||
|
@ -890,150 +885,6 @@ impl WorktreeStore {
|
||||||
Ok(())
|
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(
|
async fn filter_paths(
|
||||||
fs: &Arc<dyn Fs>,
|
fs: &Arc<dyn Fs>,
|
||||||
mut input: Receiver<MatchingEntry>,
|
mut input: Receiver<MatchingEntry>,
|
||||||
|
@ -1130,54 +981,6 @@ impl WorktreeStore {
|
||||||
.ok_or_else(|| anyhow!("invalid request"))?;
|
.ok_or_else(|| anyhow!("invalid request"))?;
|
||||||
Worktree::handle_expand_all_for_entry(worktree, envelope.payload, cx).await
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
package zed.messages;
|
package zed.messages;
|
||||||
|
|
||||||
|
@ -278,7 +279,6 @@ message Envelope {
|
||||||
LanguageServerPromptRequest language_server_prompt_request = 268;
|
LanguageServerPromptRequest language_server_prompt_request = 268;
|
||||||
LanguageServerPromptResponse language_server_prompt_response = 269;
|
LanguageServerPromptResponse language_server_prompt_response = 269;
|
||||||
|
|
||||||
GitBranches git_branches = 270;
|
|
||||||
GitBranchesResponse git_branches_response = 271;
|
GitBranchesResponse git_branches_response = 271;
|
||||||
|
|
||||||
UpdateGitBranch update_git_branch = 272;
|
UpdateGitBranch update_git_branch = 272;
|
||||||
|
@ -332,7 +332,10 @@ message Envelope {
|
||||||
ApplyCodeActionKind apply_code_action_kind = 309;
|
ApplyCodeActionKind apply_code_action_kind = 309;
|
||||||
ApplyCodeActionKindResponse apply_code_action_kind_response = 310;
|
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;
|
reserved 87 to 88;
|
||||||
|
@ -348,6 +351,7 @@ message Envelope {
|
||||||
reserved 221;
|
reserved 221;
|
||||||
reserved 224 to 229;
|
reserved 224 to 229;
|
||||||
reserved 246;
|
reserved 246;
|
||||||
|
reserved 270;
|
||||||
reserved 247 to 254;
|
reserved 247 to 254;
|
||||||
reserved 255 to 256;
|
reserved 255 to 256;
|
||||||
}
|
}
|
||||||
|
@ -2851,3 +2855,23 @@ message RemoteMessageResponse {
|
||||||
string stdout = 1;
|
string stdout = 1;
|
||||||
string stderr = 2;
|
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),
|
(FlushBufferedMessages, Foreground),
|
||||||
(LanguageServerPromptRequest, Foreground),
|
(LanguageServerPromptRequest, Foreground),
|
||||||
(LanguageServerPromptResponse, Foreground),
|
(LanguageServerPromptResponse, Foreground),
|
||||||
(GitBranches, Background),
|
(GitGetBranches, Background),
|
||||||
(GitBranchesResponse, Background),
|
(GitBranchesResponse, Background),
|
||||||
(UpdateGitBranch, Background),
|
(UpdateGitBranch, Background),
|
||||||
(ListToolchains, Foreground),
|
(ListToolchains, Foreground),
|
||||||
|
@ -452,6 +452,8 @@ messages!(
|
||||||
(GetRemotesResponse, Background),
|
(GetRemotesResponse, Background),
|
||||||
(Pull, Background),
|
(Pull, Background),
|
||||||
(RemoteMessageResponse, Background),
|
(RemoteMessageResponse, Background),
|
||||||
|
(GitCreateBranch, Background),
|
||||||
|
(GitChangeBranch, Background),
|
||||||
);
|
);
|
||||||
|
|
||||||
request_messages!(
|
request_messages!(
|
||||||
|
@ -575,7 +577,7 @@ request_messages!(
|
||||||
(GetPermalinkToLine, GetPermalinkToLineResponse),
|
(GetPermalinkToLine, GetPermalinkToLineResponse),
|
||||||
(FlushBufferedMessages, Ack),
|
(FlushBufferedMessages, Ack),
|
||||||
(LanguageServerPromptRequest, LanguageServerPromptResponse),
|
(LanguageServerPromptRequest, LanguageServerPromptResponse),
|
||||||
(GitBranches, GitBranchesResponse),
|
(GitGetBranches, GitBranchesResponse),
|
||||||
(UpdateGitBranch, Ack),
|
(UpdateGitBranch, Ack),
|
||||||
(ListToolchains, ListToolchainsResponse),
|
(ListToolchains, ListToolchainsResponse),
|
||||||
(ActivateToolchain, Ack),
|
(ActivateToolchain, Ack),
|
||||||
|
@ -594,6 +596,8 @@ request_messages!(
|
||||||
(Fetch, RemoteMessageResponse),
|
(Fetch, RemoteMessageResponse),
|
||||||
(GetRemotes, GetRemotesResponse),
|
(GetRemotes, GetRemotesResponse),
|
||||||
(Pull, RemoteMessageResponse),
|
(Pull, RemoteMessageResponse),
|
||||||
|
(GitCreateBranch, Ack),
|
||||||
|
(GitChangeBranch, Ack),
|
||||||
);
|
);
|
||||||
|
|
||||||
entity_messages!(
|
entity_messages!(
|
||||||
|
@ -679,7 +683,7 @@ entity_messages!(
|
||||||
OpenServerSettings,
|
OpenServerSettings,
|
||||||
GetPermalinkToLine,
|
GetPermalinkToLine,
|
||||||
LanguageServerPromptRequest,
|
LanguageServerPromptRequest,
|
||||||
GitBranches,
|
GitGetBranches,
|
||||||
UpdateGitBranch,
|
UpdateGitBranch,
|
||||||
ListToolchains,
|
ListToolchains,
|
||||||
ActivateToolchain,
|
ActivateToolchain,
|
||||||
|
@ -695,6 +699,8 @@ entity_messages!(
|
||||||
Fetch,
|
Fetch,
|
||||||
GetRemotes,
|
GetRemotes,
|
||||||
Pull,
|
Pull,
|
||||||
|
GitChangeBranch,
|
||||||
|
GitCreateBranch,
|
||||||
);
|
);
|
||||||
|
|
||||||
entity_messages!(
|
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
|
// Give the worktree a bit of time to index the file system
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
|
|
||||||
let remote_branches = project
|
let repository = project.update(cx, |project, cx| project.active_repository(cx).unwrap());
|
||||||
.update(cx, |project, cx| project.branches(root_path.clone(), cx))
|
|
||||||
|
let remote_branches = repository
|
||||||
|
.update(cx, |repository, _| repository.branches())
|
||||||
.await
|
.await
|
||||||
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let new_branch = branches[2];
|
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);
|
assert_eq!(&remote_branches, &branches_set);
|
||||||
|
|
||||||
cx.update(|cx| {
|
cx.update(|cx| repository.read(cx).change_branch(new_branch.to_string()))
|
||||||
project.update(cx, |project, cx| {
|
.await
|
||||||
project.update_or_create_branch(root_path.clone(), new_branch.to_string(), cx)
|
.unwrap()
|
||||||
})
|
.unwrap();
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
cx.run_until_parked();
|
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
|
// Also try creating a new branch
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
project.update(cx, |project, cx| {
|
repository
|
||||||
project.update_or_create_branch(root_path.clone(), "totally-new-branch".to_string(), cx)
|
.read(cx)
|
||||||
})
|
.create_branch("totally-new-branch".to_string())
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
cx.update(|cx| {
|
||||||
|
repository
|
||||||
|
.read(cx)
|
||||||
|
.change_branch("totally-new-branch".to_string())
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue