From 671c3e723eeb42a6303d61cacd7070c3303533f2 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:51:35 -0300 Subject: [PATCH] git_ui: Add button for the `branch diff` action (#49298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a button in the Git Panel to open the `git: branch diff` view. The button only shows if the staging area is clean/no changes and if the branch is not main/master. I've been using this action so much these days and we should expose it on the UI so it's more discoverable. Screenshot 2026-02-16 at 6  30@2x Release Notes: - N/A --- crates/git_ui/src/git_panel.rs | 99 ++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 33 deletions(-) diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index d50f9088211425518f5f97366aa3a1419821581f..9e4b125c3766af11894ec952808ffa48078d2362 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -2,7 +2,7 @@ use crate::askpass_modal::AskPassModal; use crate::commit_modal::CommitModal; use crate::commit_tooltip::CommitTooltip; use crate::commit_view::CommitView; -use crate::project_diff::{self, Diff, ProjectDiff}; +use crate::project_diff::{self, BranchDiff, Diff, ProjectDiff}; use crate::remote_output::{self, RemoteAction, SuccessMessage}; use crate::{branch_picker, picker_prompt, render_remote_button}; use crate::{ @@ -4566,38 +4566,71 @@ impl GitPanel { } fn render_empty_state(&self, cx: &mut Context) -> impl IntoElement { - h_flex().h_full().flex_grow().justify_center().child( - v_flex() - .gap_2() - .child(h_flex().w_full().justify_around().child( - if self.active_repository.is_some() { - "No changes to commit" - } else { - "No Git repositories" - }, - )) - .children({ - let worktree_count = self.project.read(cx).visible_worktrees(cx).count(); - (worktree_count > 0 && self.active_repository.is_none()).then(|| { - h_flex().w_full().justify_around().child( - panel_filled_button("Initialize Repository") - .tooltip(Tooltip::for_action_title_in( - "git init", - &git::Init, - &self.focus_handle, - )) - .on_click(move |_, _, cx| { - cx.defer(move |cx| { - cx.dispatch_action(&git::Init); - }) - }), - ) - }) - }) - .text_ui_sm(cx) - .mx_auto() - .text_color(Color::Placeholder.color(cx)), - ) + let has_repo = self.active_repository.is_some(); + let has_no_repo = self.active_repository.is_none(); + let worktree_count = self.project.read(cx).visible_worktrees(cx).count(); + + let should_show_branch_diff = + has_repo && self.changes_count == 0 && !self.is_on_main_branch(cx); + + let label = if has_repo { + "No changes to commit" + } else { + "No Git repositories" + }; + + v_flex() + .gap_1p5() + .flex_1() + .items_center() + .justify_center() + .child(Label::new(label).size(LabelSize::Small).color(Color::Muted)) + .when(has_no_repo && worktree_count > 0, |this| { + this.child( + panel_filled_button("Initialize Repository") + .tooltip(Tooltip::for_action_title_in( + "git init", + &git::Init, + &self.focus_handle, + )) + .on_click(move |_, _, cx| { + cx.defer(move |cx| { + cx.dispatch_action(&git::Init); + }) + }), + ) + }) + .when(should_show_branch_diff, |this| { + this.child( + panel_filled_button("View Branch Diff") + .tooltip(move |_, cx| { + Tooltip::with_meta( + "Branch Diff", + Some(&BranchDiff), + "Show diff between working directory and default branch", + cx, + ) + }) + .on_click(move |_, _, cx| { + cx.defer(move |cx| { + cx.dispatch_action(&BranchDiff); + }) + }), + ) + }) + } + + fn is_on_main_branch(&self, cx: &Context) -> bool { + let Some(repo) = self.active_repository.as_ref() else { + return false; + }; + + let Some(branch) = repo.read(cx).branch.as_ref() else { + return false; + }; + + let branch_name = branch.name(); + matches!(branch_name, "main" | "master") } fn render_buffer_header_controls(