Add button to copy SHA from Git blame (#14883)

Ryan Hawkins and Marshall Bowers created

The git blame dialog doesn't give the user a way to quickly copy the SHA
of the associated commit for a line. Adding an option for users to
quickly access this SHA is helpful for user's to do any more git-fu they
might need, such as viewing the full changes themselves within git,
checking the commit out, bisecting off the commit, etc.

This is also very handy for user's of self-hosted git providers.
Determining what provider a self-hosted repository is using could be
quite difficult and this presents an easy option to allow users to look
up more about a commit without having to memorize the short SHA.

Release Notes:

- Added a button to copy the SHA from a Git blame entry.

<img width="1552" alt="A screenshot showing the new copy SHA button
within the Zed editor's inline blame "
src="https://github.com/user-attachments/assets/9365950d-3a3f-4c11-b119-ab02654f5669">

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>

Change summary

crates/editor/src/blame_entry_tooltip.rs | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)

Detailed changes

crates/editor/src/blame_entry_tooltip.rs 🔗

@@ -2,19 +2,14 @@ use futures::Future;
 use git::blame::BlameEntry;
 use git::Oid;
 use gpui::{
-    Asset, Element, ParentElement, Render, ScrollHandle, StatefulInteractiveElement, WeakView,
-    WindowContext,
+    Asset, ClipboardItem, Element, ParentElement, Render, ScrollHandle, StatefulInteractiveElement,
+    WeakView, WindowContext,
 };
 use settings::Settings;
 use std::hash::Hash;
-use theme::{ActiveTheme, ThemeSettings};
+use theme::ThemeSettings;
 use time::UtcOffset;
-use ui::{
-    div, h_flex, tooltip_container, v_flex, Avatar, Button, ButtonStyle, Clickable as _, Color,
-    FluentBuilder, Icon, IconName, IconPosition, InteractiveElement as _, IntoElement,
-    SharedString, Styled as _, ViewContext,
-};
-use ui::{ButtonCommon, Disableable as _};
+use ui::{prelude::*, tooltip_container, Avatar};
 use workspace::Workspace;
 
 use crate::git::blame::{CommitDetails, GitRemote};
@@ -130,6 +125,7 @@ impl Render for BlameEntryTooltip {
         let author_email = self.blame_entry.author_mail.clone();
 
         let short_commit_id = self.blame_entry.sha.display_short();
+        let full_sha = self.blame_entry.sha.to_string().clone();
         let absolute_timestamp = blame_entry_absolute_timestamp(&self.blame_entry);
 
         let message = self
@@ -240,6 +236,16 @@ impl Render for BlameEntryTooltip {
                                                     })
                                                 },
                                             ),
+                                        )
+                                        .child(
+                                            IconButton::new("copy-sha-button", IconName::Copy)
+                                                .icon_color(Color::Muted)
+                                                .on_click(move |_, cx| {
+                                                    cx.stop_propagation();
+                                                    cx.write_to_clipboard(ClipboardItem::new(
+                                                        full_sha.clone(),
+                                                    ))
+                                                }),
                                         ),
                                 ),
                         ),