Improve handling of remote-tracking branches in the picker (#29744)
Release Notes: - Changed the git branch picker to make remote-tracking branches less prominent --------- Co-authored-by: Anthony Eid <hello@anthonyeid.me>
This commit is contained in:
parent
92b9ecd7d2
commit
e1e3f2e423
13 changed files with 150 additions and 124 deletions
|
@ -1,6 +1,7 @@
|
|||
use anyhow::{Context as _, anyhow};
|
||||
use fuzzy::StringMatchCandidate;
|
||||
|
||||
use collections::HashSet;
|
||||
use git::repository::Branch;
|
||||
use gpui::{
|
||||
App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
|
||||
|
@ -95,12 +96,28 @@ impl BranchList {
|
|||
.context("No active repository")?
|
||||
.await??;
|
||||
|
||||
all_branches.sort_by_key(|branch| {
|
||||
branch
|
||||
.most_recent_commit
|
||||
.as_ref()
|
||||
.map(|commit| 0 - commit.commit_timestamp)
|
||||
});
|
||||
let all_branches = cx
|
||||
.background_spawn(async move {
|
||||
let upstreams: HashSet<_> = all_branches
|
||||
.iter()
|
||||
.filter_map(|branch| {
|
||||
let upstream = branch.upstream.as_ref()?;
|
||||
Some(upstream.ref_name.clone())
|
||||
})
|
||||
.collect();
|
||||
|
||||
all_branches.retain(|branch| !upstreams.contains(&branch.ref_name));
|
||||
|
||||
all_branches.sort_by_key(|branch| {
|
||||
branch
|
||||
.most_recent_commit
|
||||
.as_ref()
|
||||
.map(|commit| 0 - commit.commit_timestamp)
|
||||
});
|
||||
|
||||
all_branches
|
||||
})
|
||||
.await;
|
||||
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
this.picker.update(cx, |picker, cx| {
|
||||
|
@ -266,6 +283,7 @@ impl PickerDelegate for BranchListDelegate {
|
|||
let mut matches: Vec<BranchEntry> = if query.is_empty() {
|
||||
all_branches
|
||||
.into_iter()
|
||||
.filter(|branch| !branch.is_remote())
|
||||
.take(RECENT_BRANCHES_COUNT)
|
||||
.map(|branch| BranchEntry {
|
||||
branch,
|
||||
|
@ -277,7 +295,7 @@ impl PickerDelegate for BranchListDelegate {
|
|||
let candidates = all_branches
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(ix, command)| StringMatchCandidate::new(ix, &command.name.clone()))
|
||||
.map(|(ix, branch)| StringMatchCandidate::new(ix, branch.name()))
|
||||
.collect::<Vec<StringMatchCandidate>>();
|
||||
fuzzy::match_strings(
|
||||
&candidates,
|
||||
|
@ -303,11 +321,11 @@ impl PickerDelegate for BranchListDelegate {
|
|||
if !query.is_empty()
|
||||
&& !matches
|
||||
.first()
|
||||
.is_some_and(|entry| entry.branch.name == query)
|
||||
.is_some_and(|entry| entry.branch.name() == query)
|
||||
{
|
||||
matches.push(BranchEntry {
|
||||
branch: Branch {
|
||||
name: query.clone().into(),
|
||||
ref_name: format!("refs/heads/{query}").into(),
|
||||
is_head: false,
|
||||
upstream: None,
|
||||
most_recent_commit: None,
|
||||
|
@ -335,19 +353,19 @@ impl PickerDelegate for BranchListDelegate {
|
|||
return;
|
||||
};
|
||||
if entry.is_new {
|
||||
self.create_branch(entry.branch.name.clone(), window, cx);
|
||||
self.create_branch(entry.branch.name().to_owned().into(), window, cx);
|
||||
return;
|
||||
}
|
||||
|
||||
let current_branch = self.repo.as_ref().map(|repo| {
|
||||
repo.update(cx, |repo, _| {
|
||||
repo.branch.as_ref().map(|branch| branch.name.clone())
|
||||
repo.branch.as_ref().map(|branch| branch.ref_name.clone())
|
||||
})
|
||||
});
|
||||
|
||||
if current_branch
|
||||
.flatten()
|
||||
.is_some_and(|current_branch| current_branch == entry.branch.name)
|
||||
.is_some_and(|current_branch| current_branch == entry.branch.ref_name)
|
||||
{
|
||||
cx.emit(DismissEvent);
|
||||
return;
|
||||
|
@ -368,7 +386,7 @@ impl PickerDelegate for BranchListDelegate {
|
|||
|
||||
anyhow::Ok(async move {
|
||||
repo.update(&mut cx, |repo, _| {
|
||||
repo.change_branch(branch.name.to_string())
|
||||
repo.change_branch(branch.name().to_string())
|
||||
})?
|
||||
.await?
|
||||
})
|
||||
|
@ -443,13 +461,13 @@ impl PickerDelegate for BranchListDelegate {
|
|||
if entry.is_new {
|
||||
Label::new(format!(
|
||||
"Create branch \"{}\"…",
|
||||
entry.branch.name
|
||||
entry.branch.name()
|
||||
))
|
||||
.single_line()
|
||||
.into_any_element()
|
||||
} else {
|
||||
HighlightedLabel::new(
|
||||
entry.branch.name.clone(),
|
||||
entry.branch.name().to_owned(),
|
||||
entry.positions.clone(),
|
||||
)
|
||||
.truncate()
|
||||
|
@ -470,7 +488,7 @@ impl PickerDelegate for BranchListDelegate {
|
|||
let message = if entry.is_new {
|
||||
if let Some(current_branch) =
|
||||
self.repo.as_ref().and_then(|repo| {
|
||||
repo.read(cx).branch.as_ref().map(|b| b.name.clone())
|
||||
repo.read(cx).branch.as_ref().map(|b| b.name())
|
||||
})
|
||||
{
|
||||
format!("based off {}", current_branch)
|
||||
|
|
|
@ -321,8 +321,8 @@ impl CommitModal {
|
|||
let branch = active_repo
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.read(cx).branch.as_ref())
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_else(|| "<no branch>".into());
|
||||
.map(|b| b.name().to_owned())
|
||||
.unwrap_or_else(|| "<no branch>".to_owned());
|
||||
|
||||
let branch_picker_button = panel_button(branch)
|
||||
.icon(IconName::GitBranch)
|
||||
|
|
|
@ -1953,7 +1953,12 @@ impl GitPanel {
|
|||
})?;
|
||||
|
||||
let pull = repo.update(cx, |repo, cx| {
|
||||
repo.pull(branch.name.clone(), remote.name.clone(), askpass, cx)
|
||||
repo.pull(
|
||||
branch.name().to_owned().into(),
|
||||
remote.name.clone(),
|
||||
askpass,
|
||||
cx,
|
||||
)
|
||||
})?;
|
||||
|
||||
let remote_message = pull.await?;
|
||||
|
@ -2020,7 +2025,7 @@ impl GitPanel {
|
|||
|
||||
let push = repo.update(cx, |repo, cx| {
|
||||
repo.push(
|
||||
branch.name.clone(),
|
||||
branch.name().to_owned().into(),
|
||||
remote.name.clone(),
|
||||
options,
|
||||
askpass_delegate,
|
||||
|
@ -2030,7 +2035,7 @@ impl GitPanel {
|
|||
|
||||
let remote_output = push.await?;
|
||||
|
||||
let action = RemoteAction::Push(branch.name, remote);
|
||||
let action = RemoteAction::Push(branch.name().to_owned().into(), remote);
|
||||
this.update(cx, |this, cx| match remote_output {
|
||||
Ok(remote_message) => this.show_remote_output(action, remote_message, cx),
|
||||
Err(e) => {
|
||||
|
@ -2092,7 +2097,7 @@ impl GitPanel {
|
|||
return Err(anyhow::anyhow!("No active branch"));
|
||||
};
|
||||
|
||||
Ok(repo.get_remotes(Some(current_branch.name.to_string())))
|
||||
Ok(repo.get_remotes(Some(current_branch.name().to_string())))
|
||||
})??
|
||||
.await??;
|
||||
|
||||
|
@ -4363,19 +4368,17 @@ impl RenderOnce for PanelRepoFooter {
|
|||
let branch_name = self
|
||||
.branch
|
||||
.as_ref()
|
||||
.map(|branch| branch.name.clone())
|
||||
.map(|branch| branch.name().to_owned())
|
||||
.or_else(|| {
|
||||
self.head_commit.as_ref().map(|commit| {
|
||||
SharedString::from(
|
||||
commit
|
||||
.sha
|
||||
.chars()
|
||||
.take(MAX_SHORT_SHA_LEN)
|
||||
.collect::<String>(),
|
||||
)
|
||||
commit
|
||||
.sha
|
||||
.chars()
|
||||
.take(MAX_SHORT_SHA_LEN)
|
||||
.collect::<String>()
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| SharedString::from(" (no branch)"));
|
||||
.unwrap_or_else(|| " (no branch)".to_owned());
|
||||
let show_separator = self.branch.is_some() || self.head_commit.is_some();
|
||||
|
||||
let active_repo_name = self.active_repository.clone();
|
||||
|
@ -4542,7 +4545,7 @@ impl Component for PanelRepoFooter {
|
|||
fn branch(upstream: Option<UpstreamTracking>) -> Branch {
|
||||
Branch {
|
||||
is_head: true,
|
||||
name: "some-branch".into(),
|
||||
ref_name: "some-branch".into(),
|
||||
upstream: upstream.map(|tracking| Upstream {
|
||||
ref_name: "origin/some-branch".into(),
|
||||
tracking,
|
||||
|
@ -4559,7 +4562,7 @@ impl Component for PanelRepoFooter {
|
|||
fn custom(branch_name: &str, upstream: Option<UpstreamTracking>) -> Branch {
|
||||
Branch {
|
||||
is_head: true,
|
||||
name: branch_name.to_string().into(),
|
||||
ref_name: branch_name.to_string().into(),
|
||||
upstream: upstream.map(|tracking| Upstream {
|
||||
ref_name: format!("zed/{}", branch_name).into(),
|
||||
tracking,
|
||||
|
|
|
@ -1099,7 +1099,7 @@ impl RenderOnce for ProjectDiffEmptyState {
|
|||
v_flex()
|
||||
.child(Headline::new(ahead_string).size(HeadlineSize::Small))
|
||||
.child(
|
||||
Label::new(format!("Push your changes to {}", branch.name))
|
||||
Label::new(format!("Push your changes to {}", branch.name()))
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
|
@ -1113,7 +1113,7 @@ impl RenderOnce for ProjectDiffEmptyState {
|
|||
v_flex()
|
||||
.child(Headline::new("Publish Branch").size(HeadlineSize::Small))
|
||||
.child(
|
||||
Label::new(format!("Create {} on remote", branch.name))
|
||||
Label::new(format!("Create {} on remote", branch.name()))
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
|
@ -1183,7 +1183,7 @@ mod preview {
|
|||
fn branch(upstream: Option<UpstreamTracking>) -> Branch {
|
||||
Branch {
|
||||
is_head: true,
|
||||
name: "some-branch".into(),
|
||||
ref_name: "some-branch".into(),
|
||||
upstream: upstream.map(|tracking| Upstream {
|
||||
ref_name: "origin/some-branch".into(),
|
||||
tracking,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue