Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show branch information #25359

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
82 changes: 74 additions & 8 deletions crates/git_ui/src/branch_picker.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use anyhow::{anyhow, Context as _, Result};
use fuzzy::{StringMatch, StringMatchCandidate};

use git::repository::Branch;
use editor::commit_tooltip::CommitTooltip;
use git::repository::{Branch, GitRepository};
use gpui::{
rems, App, AsyncApp, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Subscription,
Task, WeakEntity, Window,
rems, AnyView, App, AsyncApp, Context, DismissEvent, Entity, EventEmitter, FocusHandle,
Focusable, InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled,
Subscription, Task, WeakEntity, Window,
};
use picker::{Picker, PickerDelegate};
use project::git::GitRepo;
use project::ProjectPath;
use std::sync::Arc;
use time::OffsetDateTime;
use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing};
use util::ResultExt;
use workspace::notifications::DetachAndPromptErr;
Expand Down Expand Up @@ -149,6 +152,24 @@ impl BranchListDelegate {
.filter(|item| matches!(item, BranchEntry::Branch(_)))
.count()
}

pub fn get_last_commit_info(
repo: &dyn GitRepository,
branch_name: &str,
) -> anyhow::Result<editor::commit_tooltip::CommitDetails> {
let last_commit = repo.show(branch_name)?;
Ok(editor::commit_tooltip::CommitDetails {
sha: last_commit.sha.clone(),
committer_name: last_commit.committer_name.clone(),
committer_email: last_commit.committer_email.clone(),
commit_time: OffsetDateTime::from_unix_timestamp(last_commit.commit_timestamp)
.map_err(|_| anyhow::anyhow!("Invalid commit timestamp"))?,
message: Some(editor::commit_tooltip::ParsedCommitMessage {
message: last_commit.message.clone(),
..Default::default()
}),
})
}
}

impl PickerDelegate for BranchListDelegate {
Expand Down Expand Up @@ -318,22 +339,67 @@ impl PickerDelegate for BranchListDelegate {
ix: usize,
selected: bool,
_window: &mut Window,
_cx: &mut Context<Picker<Self>>,
cx: &mut Context<Picker<Self>>,
) -> Option<Self::ListItem> {
let hit = &self.matches[ix];
let shortened_branch_name =
util::truncate_and_trailoff(&hit.name(), self.branch_name_trailoff_after);

let repo = self.workspace.upgrade().and_then(|workspace| {
let project_entity = workspace.read(cx).project();
project_entity.read(cx).active_repository(cx)
});

let branch_name = match hit {
BranchEntry::Branch(branch) => Some(branch.string.as_str()),
BranchEntry::History(branch) => Some(branch.as_str()),
BranchEntry::NewBranch { name } => Some(name.as_str()),
};

let commit_details = repo.as_ref().and_then(|repo_entity| {
let repo = repo_entity.read(cx);
let git_repo = match &repo.git_repo {
GitRepo::Local(git_repo) => git_repo.as_ref(),
_ => return None,
};
let branch_name = branch_name?;
Self::get_last_commit_info(git_repo, branch_name).ok()
});

Some(
ListItem::new(SharedString::from(format!("vcs-menu-{ix}")))
.inset(true)
.spacing(ListItemSpacing::Sparse)
.toggle_state(selected)
.when(matches!(hit, BranchEntry::History(_)), |el| {
el.end_slot(
Icon::new(IconName::HistoryRerun)
.color(Color::Muted)
.size(IconSize::Small),
div()
.child(
Icon::new(IconName::HistoryRerun)
.color(Color::Muted)
.size(IconSize::Small),
)
.id("commit-msg-hover")
.hoverable_tooltip(move |window, cx| {
let commit_details = commit_details.clone().unwrap_or(
editor::commit_tooltip::CommitDetails {
sha: "N/A".into(),
committer_name: "Unknown".into(),
committer_email: "[email protected]".into(),
commit_time: OffsetDateTime::from_unix_timestamp(0)
.unwrap(),
message: Some(
editor::commit_tooltip::ParsedCommitMessage {
message: "No commit details available".into(),
..Default::default()
},
),
},
);
let tooltip =
cx.new(|cx| CommitTooltip::new(commit_details, window, cx));
AnyView::from(tooltip)
}),
)
})
.map(|el| match hit {
Expand Down
Loading