git_ui: Show copy-SHA button on commit header hover (#45478)

Release Notes:

- git: Added the ability to copy a commit's SHA in the commit view.

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
Xiaobo Liu
2025-12-24 01:11:56 +08:00
committed by GitHub
parent d43cc46288
commit 9f90c1a1b7

View File

@@ -8,9 +8,9 @@ use git::{
parse_git_remote_url,
};
use gpui::{
AnyElement, App, AppContext as _, AsyncApp, AsyncWindowContext, Context, Element, Entity,
EventEmitter, FocusHandle, Focusable, InteractiveElement, IntoElement, ParentElement,
PromptLevel, Render, Styled, Task, WeakEntity, Window, actions,
AnyElement, App, AppContext as _, AsyncApp, AsyncWindowContext, ClipboardItem, Context,
Element, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement, IntoElement,
ParentElement, PromptLevel, Render, Styled, Task, WeakEntity, Window, actions,
};
use language::{
Anchor, Buffer, Capability, DiskState, File, LanguageRegistry, LineEnding, OffsetRangeExt as _,
@@ -24,7 +24,7 @@ use std::{
sync::Arc,
};
use theme::ActiveTheme;
use ui::{DiffStat, Tooltip, prelude::*};
use ui::{ButtonLike, DiffStat, Tooltip, prelude::*};
use util::{ResultExt, paths::PathStyle, rel_path::RelPath, truncate_and_trailoff};
use workspace::item::TabTooltipContent;
use workspace::{
@@ -383,6 +383,7 @@ impl CommitView {
fn render_header(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let commit = &self.commit;
let author_name = commit.author_name.clone();
let commit_sha = commit.sha.clone();
let commit_date = time::OffsetDateTime::from_unix_timestamp(commit.commit_timestamp)
.unwrap_or_else(|_| time::OffsetDateTime::now_utc());
let local_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC);
@@ -429,6 +430,19 @@ impl CommitView {
.full_width()
});
let clipboard_has_link = cx
.read_from_clipboard()
.and_then(|entry| entry.text())
.map_or(false, |clipboard_text| {
clipboard_text.trim() == commit_sha.as_ref()
});
let (copy_icon, copy_icon_color) = if clipboard_has_link {
(IconName::Check, Color::Success)
} else {
(IconName::Copy, Color::Muted)
};
h_flex()
.border_b_1()
.border_color(cx.theme().colors().border_variant)
@@ -454,13 +468,47 @@ impl CommitView {
h_flex()
.gap_1()
.child(Label::new(author_name).color(Color::Default))
.child(
Label::new(format!("Commit:{}", commit.sha))
.color(Color::Muted)
.size(LabelSize::Small)
.truncate()
.buffer_font(cx),
),
.child({
ButtonLike::new("sha")
.child(
h_flex()
.group("sha_btn")
.size_full()
.max_w_32()
.gap_0p5()
.child(
Label::new(commit_sha.clone())
.color(Color::Muted)
.size(LabelSize::Small)
.truncate()
.buffer_font(cx),
)
.child(
div().visible_on_hover("sha_btn").child(
Icon::new(copy_icon)
.color(copy_icon_color)
.size(IconSize::Small),
),
),
)
.tooltip({
let commit_sha = commit_sha.clone();
move |_, cx| {
Tooltip::with_meta(
"Copy Commit SHA",
None,
commit_sha.clone(),
cx,
)
}
})
.on_click(move |_, _, cx| {
cx.stop_propagation();
cx.write_to_clipboard(ClipboardItem::new_string(
commit_sha.to_string(),
));
})
}),
)
.child(
h_flex()