git: Add UI for deleting branches (#42703)
Closes #42641 Release Notes: - Added UI for deleting Git branches --------- Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
This commit is contained in:
co-authored by
Jakub Konka
parent
87e3d6e014
commit
c18481ed13
@@ -1334,5 +1334,12 @@
|
||||
"alt-left": "dev::Zeta2ContextGoBack",
|
||||
"alt-right": "dev::Zeta2ContextGoForward"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitBranchSelector || (GitBranchSelector > Picker > Editor)",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"ctrl-shift-backspace": "branch_picker::DeleteBranch"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1438,5 +1438,12 @@
|
||||
"alt-left": "dev::Zeta2ContextGoBack",
|
||||
"alt-right": "dev::Zeta2ContextGoForward"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitBranchSelector || (GitBranchSelector > Picker > Editor)",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-shift-backspace": "branch_picker::DeleteBranch"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1361,5 +1361,12 @@
|
||||
"alt-left": "dev::Zeta2ContextGoBack",
|
||||
"alt-right": "dev::Zeta2ContextGoForward"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitBranchSelector || (GitBranchSelector > Picker > Editor)",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"ctrl-shift-backspace": "branch_picker::DeleteBranch"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -432,6 +432,10 @@ impl GitRepository for FakeGitRepository {
|
||||
})
|
||||
}
|
||||
|
||||
fn delete_branch(&self, _name: String) -> BoxFuture<'_, Result<()>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn blame(&self, path: RepoPath, _content: Rope) -> BoxFuture<'_, Result<git::blame::Blame>> {
|
||||
self.with_state_async(false, move |state| {
|
||||
state
|
||||
|
||||
@@ -435,6 +435,8 @@ pub trait GitRepository: Send + Sync {
|
||||
-> BoxFuture<'_, Result<()>>;
|
||||
fn rename_branch(&self, branch: String, new_name: String) -> BoxFuture<'_, Result<()>>;
|
||||
|
||||
fn delete_branch(&self, name: String) -> BoxFuture<'_, Result<()>>;
|
||||
|
||||
fn worktrees(&self) -> BoxFuture<'_, Result<Vec<Worktree>>>;
|
||||
|
||||
fn create_worktree(
|
||||
@@ -1414,6 +1416,21 @@ impl GitRepository for RealGitRepository {
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn delete_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
|
||||
let git_binary_path = self.any_git_binary_path.clone();
|
||||
let working_directory = self.working_directory();
|
||||
let executor = self.executor.clone();
|
||||
|
||||
self.executor
|
||||
.spawn(async move {
|
||||
GitBinary::new(git_binary_path, working_directory?, executor)
|
||||
.run(&["branch", "-d", &name])
|
||||
.await?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn blame(&self, path: RepoPath, content: Rope) -> BoxFuture<'_, Result<crate::blame::Blame>> {
|
||||
let working_directory = self.working_directory();
|
||||
let git_binary_path = self.any_git_binary_path.clone();
|
||||
|
||||
@@ -4,9 +4,9 @@ use fuzzy::StringMatchCandidate;
|
||||
use collections::HashSet;
|
||||
use git::repository::Branch;
|
||||
use gpui::{
|
||||
App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
|
||||
IntoElement, Modifiers, ModifiersChangedEvent, ParentElement, Render, SharedString, Styled,
|
||||
Subscription, Task, Window, rems,
|
||||
Action, App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
|
||||
InteractiveElement, IntoElement, Modifiers, ModifiersChangedEvent, ParentElement, Render,
|
||||
SharedString, Styled, Subscription, Task, WeakEntity, Window, actions, rems,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate, PickerEditorPosition};
|
||||
use project::git_store::Repository;
|
||||
@@ -14,13 +14,25 @@ use project::project_settings::ProjectSettings;
|
||||
use settings::Settings;
|
||||
use std::sync::Arc;
|
||||
use time::OffsetDateTime;
|
||||
use ui::{HighlightedLabel, ListItem, ListItemSpacing, Tooltip, prelude::*};
|
||||
use ui::{HighlightedLabel, KeyBinding, ListItem, ListItemSpacing, Tooltip, prelude::*};
|
||||
use util::ResultExt;
|
||||
use workspace::notifications::DetachAndPromptErr;
|
||||
use workspace::{ModalView, Workspace};
|
||||
|
||||
use crate::{branch_picker, git_panel::show_error_toast};
|
||||
|
||||
actions!(
|
||||
branch_picker,
|
||||
[
|
||||
/// Deletes the selected git branch.
|
||||
DeleteBranch
|
||||
]
|
||||
);
|
||||
|
||||
pub fn register(workspace: &mut Workspace) {
|
||||
workspace.register_action(open);
|
||||
workspace.register_action(|workspace, branch: &zed_actions::git::Branch, window, cx| {
|
||||
open(workspace, branch, window, cx);
|
||||
});
|
||||
workspace.register_action(switch);
|
||||
workspace.register_action(checkout_branch);
|
||||
}
|
||||
@@ -49,10 +61,18 @@ pub fn open(
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
let workspace_handle = workspace.weak_handle();
|
||||
let repository = workspace.project().read(cx).active_repository(cx);
|
||||
let style = BranchListStyle::Modal;
|
||||
workspace.toggle_modal(window, cx, |window, cx| {
|
||||
BranchList::new(repository, style, rems(34.), window, cx)
|
||||
BranchList::new(
|
||||
Some(workspace_handle),
|
||||
repository,
|
||||
style,
|
||||
rems(34.),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,7 +82,14 @@ pub fn popover(
|
||||
cx: &mut App,
|
||||
) -> Entity<BranchList> {
|
||||
cx.new(|cx| {
|
||||
let list = BranchList::new(repository, BranchListStyle::Popover, rems(20.), window, cx);
|
||||
let list = BranchList::new(
|
||||
None,
|
||||
repository,
|
||||
BranchListStyle::Popover,
|
||||
rems(20.),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
list.focus_handle(cx).focus(window);
|
||||
list
|
||||
})
|
||||
@@ -77,11 +104,13 @@ enum BranchListStyle {
|
||||
pub struct BranchList {
|
||||
width: Rems,
|
||||
pub picker: Entity<Picker<BranchListDelegate>>,
|
||||
picker_focus_handle: FocusHandle,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
||||
impl BranchList {
|
||||
fn new(
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
repository: Option<Entity<Repository>>,
|
||||
style: BranchListStyle,
|
||||
width: Rems,
|
||||
@@ -148,8 +177,12 @@ impl BranchList {
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
||||
let delegate = BranchListDelegate::new(repository, style);
|
||||
let delegate = BranchListDelegate::new(workspace, repository, style, cx);
|
||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||
let picker_focus_handle = picker.focus_handle(cx);
|
||||
picker.update(cx, |picker, _| {
|
||||
picker.delegate.focus_handle = picker_focus_handle.clone();
|
||||
});
|
||||
|
||||
let _subscription = cx.subscribe(&picker, |_, _, _, cx| {
|
||||
cx.emit(DismissEvent);
|
||||
@@ -157,6 +190,7 @@ impl BranchList {
|
||||
|
||||
Self {
|
||||
picker,
|
||||
picker_focus_handle,
|
||||
width,
|
||||
_subscription,
|
||||
}
|
||||
@@ -171,13 +205,26 @@ impl BranchList {
|
||||
self.picker
|
||||
.update(cx, |picker, _| picker.delegate.modifiers = ev.modifiers)
|
||||
}
|
||||
|
||||
fn handle_delete_branch(
|
||||
&mut self,
|
||||
_: &branch_picker::DeleteBranch,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.picker.update(cx, |picker, cx| {
|
||||
picker
|
||||
.delegate
|
||||
.delete_branch_at(picker.delegate.selected_index, window, cx)
|
||||
})
|
||||
}
|
||||
}
|
||||
impl ModalView for BranchList {}
|
||||
impl EventEmitter<DismissEvent> for BranchList {}
|
||||
|
||||
impl Focusable for BranchList {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
fn focus_handle(&self, _cx: &App) -> FocusHandle {
|
||||
self.picker_focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +234,7 @@ impl Render for BranchList {
|
||||
.key_context("GitBranchSelector")
|
||||
.w(self.width)
|
||||
.on_modifiers_changed(cx.listener(Self::handle_modifiers_changed))
|
||||
.on_action(cx.listener(Self::handle_delete_branch))
|
||||
.child(self.picker.clone())
|
||||
.on_mouse_down_out({
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
@@ -206,6 +254,7 @@ struct BranchEntry {
|
||||
}
|
||||
|
||||
pub struct BranchListDelegate {
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
matches: Vec<BranchEntry>,
|
||||
all_branches: Option<Vec<Branch>>,
|
||||
default_branch: Option<SharedString>,
|
||||
@@ -214,11 +263,18 @@ pub struct BranchListDelegate {
|
||||
selected_index: usize,
|
||||
last_query: String,
|
||||
modifiers: Modifiers,
|
||||
focus_handle: FocusHandle,
|
||||
}
|
||||
|
||||
impl BranchListDelegate {
|
||||
fn new(repo: Option<Entity<Repository>>, style: BranchListStyle) -> Self {
|
||||
fn new(
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
repo: Option<Entity<Repository>>,
|
||||
style: BranchListStyle,
|
||||
cx: &mut Context<BranchList>,
|
||||
) -> Self {
|
||||
Self {
|
||||
workspace,
|
||||
matches: vec![],
|
||||
repo,
|
||||
style,
|
||||
@@ -227,6 +283,7 @@ impl BranchListDelegate {
|
||||
selected_index: 0,
|
||||
last_query: Default::default(),
|
||||
modifiers: Default::default(),
|
||||
focus_handle: cx.focus_handle(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +312,59 @@ impl BranchListDelegate {
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
|
||||
fn delete_branch_at(&self, idx: usize, window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
let Some(branch_entry) = self.matches.get(idx) else {
|
||||
return;
|
||||
};
|
||||
let Some(repo) = self.repo.clone() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let workspace = self.workspace.clone();
|
||||
let branch_name = branch_entry.branch.name().to_string();
|
||||
let branch_ref = branch_entry.branch.ref_name.clone();
|
||||
|
||||
cx.spawn_in(window, async move |picker, cx| {
|
||||
let result = repo
|
||||
.update(cx, |repo, _| repo.delete_branch(branch_name.clone()))?
|
||||
.await?;
|
||||
|
||||
if let Err(e) = result {
|
||||
log::error!("Failed to delete branch: {}", e);
|
||||
|
||||
if let Some(workspace) = workspace.and_then(|w| w.upgrade()) {
|
||||
cx.update(|_window, cx| {
|
||||
show_error_toast(workspace, format!("branch -d {branch_name}"), e, cx)
|
||||
})?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
picker.update_in(cx, |picker, _, cx| {
|
||||
picker
|
||||
.delegate
|
||||
.matches
|
||||
.retain(|entry| entry.branch.ref_name != branch_ref);
|
||||
|
||||
if let Some(all_branches) = &mut picker.delegate.all_branches {
|
||||
all_branches.retain(|branch| branch.ref_name != branch_ref);
|
||||
}
|
||||
|
||||
if picker.delegate.matches.is_empty() {
|
||||
picker.delegate.selected_index = 0;
|
||||
} else if picker.delegate.selected_index >= picker.delegate.matches.len() {
|
||||
picker.delegate.selected_index = picker.delegate.matches.len() - 1;
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
})?;
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
|
||||
impl PickerDelegate for BranchListDelegate {
|
||||
@@ -372,6 +482,7 @@ impl PickerDelegate for BranchListDelegate {
|
||||
let Some(entry) = self.matches.get(self.selected_index()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if entry.is_new {
|
||||
let from_branch = if secondary {
|
||||
self.default_branch.clone()
|
||||
@@ -565,6 +676,39 @@ impl PickerDelegate for BranchListDelegate {
|
||||
)
|
||||
}
|
||||
|
||||
fn render_footer(
|
||||
&self,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<AnyElement> {
|
||||
let focus_handle = self.focus_handle.clone();
|
||||
|
||||
Some(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.p_1p5()
|
||||
.gap_0p5()
|
||||
.justify_end()
|
||||
.border_t_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.child(
|
||||
Button::new("delete-branch", "Delete")
|
||||
.key_binding(
|
||||
KeyBinding::for_action_in(
|
||||
&branch_picker::DeleteBranch,
|
||||
&focus_handle,
|
||||
cx,
|
||||
)
|
||||
.map(|kb| kb.size(rems_from_px(12.))),
|
||||
)
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(branch_picker::DeleteBranch.boxed_clone(), cx);
|
||||
}),
|
||||
)
|
||||
.into_any(),
|
||||
)
|
||||
}
|
||||
|
||||
fn no_matches_text(&self, _window: &mut Window, _cx: &mut App) -> Option<SharedString> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -3024,35 +3024,10 @@ impl GitPanel {
|
||||
}
|
||||
|
||||
fn show_error_toast(&self, action: impl Into<SharedString>, e: anyhow::Error, cx: &mut App) {
|
||||
let action = action.into();
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let message = e.to_string().trim().to_string();
|
||||
if message
|
||||
.matches(git::repository::REMOTE_CANCELLED_BY_USER)
|
||||
.next()
|
||||
.is_some()
|
||||
{ // Hide the cancelled by user message
|
||||
} else {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let workspace_weak = cx.weak_entity();
|
||||
let toast = StatusToast::new(format!("git {} failed", action), cx, |this, _cx| {
|
||||
this.icon(ToastIcon::new(IconName::XCircle).color(Color::Error))
|
||||
.action("View Log", move |window, cx| {
|
||||
let message = message.clone();
|
||||
let action = action.clone();
|
||||
workspace_weak
|
||||
.update(cx, move |workspace, cx| {
|
||||
Self::open_output(action, workspace, &message, window, cx)
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
});
|
||||
workspace.toggle_status_toast(toast, cx)
|
||||
});
|
||||
}
|
||||
show_error_toast(workspace, action, e, cx)
|
||||
}
|
||||
|
||||
fn show_commit_message_error<E>(weak_this: &WeakEntity<Self>, err: &E, cx: &mut AsyncApp)
|
||||
@@ -3097,7 +3072,7 @@ impl GitPanel {
|
||||
format!("stdout:\n{}\nstderr:\n{}", output.stdout, output.stderr);
|
||||
workspace_weak
|
||||
.update(cx, move |workspace, cx| {
|
||||
Self::open_output(operation, workspace, &output, window, cx)
|
||||
open_output(operation, workspace, &output, window, cx)
|
||||
})
|
||||
.ok();
|
||||
}),
|
||||
@@ -3110,30 +3085,6 @@ impl GitPanel {
|
||||
});
|
||||
}
|
||||
|
||||
fn open_output(
|
||||
operation: impl Into<SharedString>,
|
||||
workspace: &mut Workspace,
|
||||
output: &str,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
let operation = operation.into();
|
||||
let buffer = cx.new(|cx| Buffer::local(output, cx));
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
buffer.set_capability(language::Capability::ReadOnly, cx);
|
||||
});
|
||||
let editor = cx.new(|cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, None, window, cx);
|
||||
editor.buffer().update(cx, |buffer, cx| {
|
||||
buffer.set_title(format!("Output from git {operation}"), cx);
|
||||
});
|
||||
editor.set_read_only(true);
|
||||
editor
|
||||
});
|
||||
|
||||
workspace.add_item_to_center(Box::new(editor), window, cx);
|
||||
}
|
||||
|
||||
pub fn can_commit(&self) -> bool {
|
||||
(self.has_staged_changes() || self.has_tracked_changes()) && !self.has_unstaged_conflicts()
|
||||
}
|
||||
@@ -5178,6 +5129,63 @@ impl Component for PanelRepoFooter {
|
||||
}
|
||||
}
|
||||
|
||||
fn open_output(
|
||||
operation: impl Into<SharedString>,
|
||||
workspace: &mut Workspace,
|
||||
output: &str,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
let operation = operation.into();
|
||||
let buffer = cx.new(|cx| Buffer::local(output, cx));
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
buffer.set_capability(language::Capability::ReadOnly, cx);
|
||||
});
|
||||
let editor = cx.new(|cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, None, window, cx);
|
||||
editor.buffer().update(cx, |buffer, cx| {
|
||||
buffer.set_title(format!("Output from git {operation}"), cx);
|
||||
});
|
||||
editor.set_read_only(true);
|
||||
editor
|
||||
});
|
||||
|
||||
workspace.add_item_to_center(Box::new(editor), window, cx);
|
||||
}
|
||||
|
||||
pub(crate) fn show_error_toast(
|
||||
workspace: Entity<Workspace>,
|
||||
action: impl Into<SharedString>,
|
||||
e: anyhow::Error,
|
||||
cx: &mut App,
|
||||
) {
|
||||
let action = action.into();
|
||||
let message = e.to_string().trim().to_string();
|
||||
if message
|
||||
.matches(git::repository::REMOTE_CANCELLED_BY_USER)
|
||||
.next()
|
||||
.is_some()
|
||||
{ // Hide the cancelled by user message
|
||||
} else {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let workspace_weak = cx.weak_entity();
|
||||
let toast = StatusToast::new(format!("git {} failed", action), cx, |this, _cx| {
|
||||
this.icon(ToastIcon::new(IconName::XCircle).color(Color::Error))
|
||||
.action("View Log", move |window, cx| {
|
||||
let message = message.clone();
|
||||
let action = action.clone();
|
||||
workspace_weak
|
||||
.update(cx, move |workspace, cx| {
|
||||
open_output(action, workspace, &message, window, cx)
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
});
|
||||
workspace.toggle_status_toast(toast, cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use git::{
|
||||
|
||||
@@ -472,6 +472,7 @@ impl GitStore {
|
||||
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_rename_branch);
|
||||
client.add_entity_request_handler(Self::handle_delete_branch);
|
||||
client.add_entity_request_handler(Self::handle_git_init);
|
||||
client.add_entity_request_handler(Self::handle_push);
|
||||
client.add_entity_request_handler(Self::handle_pull);
|
||||
@@ -2247,6 +2248,24 @@ impl GitStore {
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
|
||||
async fn handle_delete_branch(
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::GitDeleteBranch>,
|
||||
mut cx: AsyncApp,
|
||||
) -> Result<proto::Ack> {
|
||||
let repository_id = RepositoryId::from_proto(envelope.payload.repository_id);
|
||||
let repository_handle = Self::repository_for_request(&this, repository_id, &mut cx)?;
|
||||
let branch_name = envelope.payload.branch_name;
|
||||
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.delete_branch(branch_name)
|
||||
})?
|
||||
.await??;
|
||||
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
|
||||
async fn handle_show(
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::GitShow>,
|
||||
@@ -5035,6 +5054,29 @@ impl Repository {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn delete_branch(&mut self, branch_name: String) -> oneshot::Receiver<Result<()>> {
|
||||
let id = self.id;
|
||||
self.send_job(
|
||||
Some(format!("git branch -d {branch_name}").into()),
|
||||
move |repo, _cx| async move {
|
||||
match repo {
|
||||
RepositoryState::Local(state) => state.backend.delete_branch(branch_name).await,
|
||||
RepositoryState::Remote(RemoteRepositoryState { project_id, client }) => {
|
||||
client
|
||||
.request(proto::GitDeleteBranch {
|
||||
project_id: project_id.0,
|
||||
repository_id: id.to_proto(),
|
||||
branch_name,
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn rename_branch(
|
||||
&mut self,
|
||||
branch: String,
|
||||
|
||||
@@ -190,6 +190,12 @@ message GitRenameBranch {
|
||||
string new_name = 4;
|
||||
}
|
||||
|
||||
message GitDeleteBranch {
|
||||
uint64 project_id = 1;
|
||||
uint64 repository_id = 2;
|
||||
string branch_name = 3;
|
||||
}
|
||||
|
||||
message GitDiff {
|
||||
uint64 project_id = 1;
|
||||
reserved 2;
|
||||
|
||||
@@ -439,7 +439,9 @@ message Envelope {
|
||||
|
||||
ExternalExtensionAgentsUpdated external_extension_agents_updated = 394;
|
||||
|
||||
RunGitHook run_git_hook = 395; // current max
|
||||
RunGitHook run_git_hook = 395;
|
||||
|
||||
GitDeleteBranch git_delete_branch = 396; // current max
|
||||
}
|
||||
|
||||
reserved 87 to 88;
|
||||
|
||||
@@ -290,6 +290,7 @@ messages!(
|
||||
(RemoveRepository, Foreground),
|
||||
(UsersResponse, Foreground),
|
||||
(GitReset, Background),
|
||||
(GitDeleteBranch, Background),
|
||||
(GitCheckoutFiles, Background),
|
||||
(GitShow, Background),
|
||||
(GitCommitDetails, Background),
|
||||
@@ -492,6 +493,7 @@ request_messages!(
|
||||
(RegisterBufferWithLanguageServers, Ack),
|
||||
(GitShow, GitCommitDetails),
|
||||
(GitReset, Ack),
|
||||
(GitDeleteBranch, Ack),
|
||||
(GitCheckoutFiles, Ack),
|
||||
(SetIndexText, Ack),
|
||||
(Push, RemoteMessageResponse),
|
||||
@@ -656,6 +658,7 @@ entity_messages!(
|
||||
RegisterBufferWithLanguageServers,
|
||||
GitShow,
|
||||
GitReset,
|
||||
GitDeleteBranch,
|
||||
GitCheckoutFiles,
|
||||
SetIndexText,
|
||||
ToggleLspLogs,
|
||||
|
||||
@@ -4731,6 +4731,7 @@ mod tests {
|
||||
"assistant",
|
||||
"assistant2",
|
||||
"auto_update",
|
||||
"branch_picker",
|
||||
"bedrock",
|
||||
"branches",
|
||||
"buffer_search",
|
||||
|
||||
Reference in New Issue
Block a user