Git commit modal branch list (#26417)

Closes #26273

Release Notes:

- git: Fixes opening the branch selector in the commit modal with
cmd-option-b
- git: Truncates the branch selector in the commit modal
This commit is contained in:
Conrad Irwin 2025-03-10 22:10:52 -06:00 committed by GitHub
parent bf11b888c3
commit c2e4fdf63d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 53 deletions

View file

@ -12,9 +12,7 @@ use project::git::Repository;
use std::sync::Arc;
use time::OffsetDateTime;
use time_format::format_local_timestamp;
use ui::{
prelude::*, HighlightedLabel, KeyBinding, ListItem, ListItemSpacing, PopoverMenuHandle, Tooltip,
};
use ui::{prelude::*, HighlightedLabel, KeyBinding, ListItem, ListItemSpacing, Tooltip};
use util::ResultExt;
use workspace::notifications::DetachAndPromptErr;
use workspace::{ModalView, Workspace};
@ -79,7 +77,6 @@ enum BranchListStyle {
pub struct BranchList {
width: Rems,
pub popover_handle: PopoverMenuHandle<Self>,
pub picker: Entity<Picker<BranchListDelegate>>,
_subscription: Subscription,
}
@ -92,7 +89,6 @@ impl BranchList {
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let popover_handle = PopoverMenuHandle::default();
let all_branches_request = repository
.clone()
.map(|repository| repository.read(cx).branches());
@ -130,7 +126,6 @@ impl BranchList {
Self {
picker,
width,
popover_handle,
_subscription,
}
}

View file

@ -4,7 +4,7 @@ use crate::branch_picker::{self, BranchList};
use crate::git_panel::{commit_message_editor, GitPanel};
use git::{Commit, GenerateCommitMessage};
use panel::{panel_button, panel_editor_style, panel_filled_button};
use ui::{prelude::*, KeybindingHint, PopoverMenu, Tooltip};
use ui::{prelude::*, KeybindingHint, PopoverMenu, PopoverMenuHandle, Tooltip};
use editor::{Editor, EditorElement};
use gpui::*;
@ -65,11 +65,11 @@ pub fn init(cx: &mut App) {
}
pub struct CommitModal {
branch_list: Entity<BranchList>,
git_panel: Entity<GitPanel>,
commit_editor: Entity<Editor>,
restore_dock: RestoreDock,
properties: ModalContainerProperties,
branch_list_handle: PopoverMenuHandle<BranchList>,
}
impl Focusable for CommitModal {
@ -146,7 +146,6 @@ impl CommitModal {
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| {
@ -177,11 +176,7 @@ impl CommitModal {
let focus_handle = commit_editor.focus_handle(cx);
cx.on_focus_out(&focus_handle, window, |this, _, window, cx| {
if !this
.branch_list
.focus_handle(cx)
.contains_focused(window, cx)
{
if !this.branch_list_handle.is_focused(window, cx) {
cx.emit(DismissEvent);
}
})
@ -190,11 +185,11 @@ impl CommitModal {
let properties = ModalContainerProperties::new(window, 50);
Self {
branch_list: branch_picker::popover(active_repository.clone(), window, cx),
git_panel,
commit_editor,
restore_dock,
properties,
branch_list_handle: PopoverMenuHandle::default(),
}
}
@ -232,32 +227,29 @@ impl CommitModal {
}
pub fn render_footer(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let (branch, can_commit, tooltip, commit_label, co_authors, generate_commit_message) =
let (can_commit, tooltip, commit_label, co_authors, generate_commit_message, active_repo) =
self.git_panel.update(cx, |git_panel, cx| {
let branch = git_panel
.active_repository
.as_ref()
.and_then(|repo| {
repo.read(cx)
.repository_entry
.branch()
.map(|b| b.name.clone())
})
.unwrap_or_else(|| "<no branch>".into());
let (can_commit, tooltip) = git_panel.configure_commit_button(cx);
let title = git_panel.commit_button_title();
let co_authors = git_panel.render_co_authors(cx);
let generate_commit_message = git_panel.render_generate_commit_message_button(cx);
let active_repo = git_panel.active_repository.clone();
(
branch,
can_commit,
tooltip,
title,
co_authors,
generate_commit_message,
active_repo,
)
});
let branch = active_repo
.as_ref()
.and_then(|repo| repo.read(cx).repository_entry.branch())
.map(|b| b.name.clone())
.unwrap_or_else(|| "<no branch>".into());
let branch_picker_button = panel_button(branch)
.icon(IconName::GitBranch)
.icon_size(IconSize::Small)
@ -274,10 +266,8 @@ impl CommitModal {
.style(ButtonStyle::Transparent);
let branch_picker = PopoverMenu::new("popover-button")
.menu({
let branch_list = self.branch_list.clone();
move |_window, _cx| Some(branch_list.clone())
})
.menu(move |window, cx| Some(branch_picker::popover(active_repo.clone(), window, cx)))
.with_handle(self.branch_list_handle.clone())
.trigger_with_tooltip(
branch_picker_button,
Tooltip::for_action_title("Switch Branch", &zed_actions::git::Branch),
@ -326,7 +316,14 @@ impl CommitModal {
.child(
h_flex()
.gap_1()
.child(branch_picker)
.flex_shrink()
.overflow_x_hidden()
.child(
h_flex()
.flex_shrink()
.overflow_x_hidden()
.child(branch_picker),
)
.children(generate_commit_message)
.children(co_authors),
)
@ -353,6 +350,14 @@ impl CommitModal {
.update(cx, |git_panel, cx| git_panel.commit_changes(window, cx));
cx.emit(DismissEvent);
}
fn toggle_branch_selector(&mut self, window: &mut Window, cx: &mut Context<Self>) {
if self.branch_list_handle.is_focused(window, cx) {
self.focus_handle(cx).focus(window)
} else {
self.branch_list_handle.toggle(window, cx);
}
}
}
impl Render for CommitModal {
@ -375,17 +380,17 @@ impl Render for CommitModal {
}))
.on_action(
cx.listener(|this, _: &zed_actions::git::Branch, window, cx| {
toggle_branch_picker(this, window, cx);
this.toggle_branch_selector(window, cx);
}),
)
.on_action(
cx.listener(|this, _: &zed_actions::git::CheckoutBranch, window, cx| {
toggle_branch_picker(this, window, cx);
this.toggle_branch_selector(window, cx);
}),
)
.on_action(
cx.listener(|this, _: &zed_actions::git::Switch, window, cx| {
toggle_branch_picker(this, window, cx);
this.toggle_branch_selector(window, cx);
}),
)
.elevation_3(cx)
@ -424,13 +429,3 @@ impl Render for CommitModal {
)
}
}
fn toggle_branch_picker(
this: &mut CommitModal,
window: &mut Window,
cx: &mut Context<'_, CommitModal>,
) {
this.branch_list.update(cx, |branch_list, cx| {
branch_list.popover_handle.toggle(window, cx);
})
}

View file

@ -2361,10 +2361,7 @@ impl GitPanel {
cx,
)
} else {
Tooltip::simple(
"You must have either staged changes or tracked files to generate a commit message",
cx,
)
Tooltip::simple("No changes to commit", cx)
}
})
.disabled(!can_commit)
@ -2414,10 +2411,7 @@ impl GitPanel {
if self.has_unstaged_conflicts() {
(false, "You must resolve conflicts before committing")
} else if !self.has_staged_changes() && !self.has_tracked_changes() {
(
false,
"You must have either staged changes or tracked files to commit",
)
(false, "No changes to commit")
} else if self.pending_commit.is_some() {
(false, "Commit in progress")
} else if self.custom_or_suggested_commit_message(cx).is_none() {
@ -3579,6 +3573,7 @@ impl RenderOnce for PanelRepoFooter {
.h(px(36.))
.items_center()
.justify_between()
.gap_1()
.child(
h_flex()
.flex_1()