git: Unify commit popups (#38749)

Closes #26424
Supersedes #35328

Originally, `git::blame` uses its own `ParsedCommitMessage` as the
source for the commit information, including the PR section. This
changes unifies this with `git::repository` and `git_ui::git_panel` by
moving this and some other commit-related structs to `git::commit`
instead, and making both `git_ui::blame_ui` and `git_ui::git_panel` pull
their information from these structs.

Release notes :

- (Let's Git Together) Fixed the commit tooltip in the git panel not
showing information like avatars.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2025-12-17 17:31:12 -05:00
1 parent 302a4bbdd0
commit 623e13761b
9 files changed
+87 -99

No files matched your search

+47 -2
View File
@@ -1,7 +1,52 @@
use crate::{Oid, status::StatusCode};
use crate::{
BuildCommitPermalinkParams, GitHostingProviderRegistry, GitRemote, Oid, parse_git_remote_url,
status::StatusCode,
};
use anyhow::{Context as _, Result};
use collections::HashMap;
use std::path::Path;
use gpui::SharedString;
use std::{path::Path, sync::Arc};
#[derive(Clone, Debug, Default)]
pub struct ParsedCommitMessage {
pub message: SharedString,
pub permalink: Option<url::Url>,
pub pull_request: Option<crate::hosting_provider::PullRequest>,
pub remote: Option<GitRemote>,
}
impl ParsedCommitMessage {
pub fn parse(
sha: String,
message: String,
remote_url: Option<&str>,
provider_registry: Option<Arc<GitHostingProviderRegistry>>,
) -> Self {
if let Some((hosting_provider, remote)) = provider_registry
.and_then(|reg| remote_url.and_then(|url| parse_git_remote_url(reg, url)))
{
let pull_request = hosting_provider.extract_pull_request(&remote, &message);
Self {
message: message.into(),
permalink: Some(
hosting_provider
.build_commit_permalink(&remote, BuildCommitPermalinkParams { sha: &sha }),
),
pull_request,
remote: Some(GitRemote {
host: hosting_provider,
owner: remote.owner.into(),
repo: remote.repo.into(),
}),
}
} else {
Self {
message: message.into(),
..Default::default()
}
}
}
}
pub async fn get_messages(working_directory: &Path, shas: &[Oid]) -> Result<HashMap<Oid, String>> {
if shas.is_empty() {