Compare commits
7 Commits
acp-rewind
...
remove-rep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d43ee72e3 | ||
|
|
f80bccbf7d | ||
|
|
8d2f39f108 | ||
|
|
05490eb1ea | ||
|
|
63a3b1037f | ||
|
|
ecc7d82202 | ||
|
|
71645aedb6 |
@@ -1949,13 +1949,12 @@ impl Thread {
|
||||
.update(cx, |git_store, cx| {
|
||||
git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.find(|repo| {
|
||||
repo.read(cx)
|
||||
.abs_path_to_repo_path(&worktree.read(cx).abs_path())
|
||||
.is_some()
|
||||
})
|
||||
.cloned()
|
||||
})
|
||||
.ok()
|
||||
.flatten()
|
||||
|
||||
@@ -2892,7 +2892,10 @@ async fn test_git_branch_name(
|
||||
#[track_caller]
|
||||
fn assert_branch(branch_name: Option<impl Into<String>>, project: &Project, cx: &App) {
|
||||
let branch_name = branch_name.map(Into::into);
|
||||
let repositories = project.repositories(cx).values().collect::<Vec<_>>();
|
||||
let repositories = project
|
||||
.repositories(cx)
|
||||
.map(|(_, repo)| repo)
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(repositories.len(), 1);
|
||||
let repository = repositories[0].clone();
|
||||
assert_eq!(
|
||||
@@ -3026,8 +3029,7 @@ async fn test_git_status_sync(
|
||||
let file = file.as_ref();
|
||||
let repos = project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.cloned()
|
||||
.map(|(_, repository)| repository)
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(repos.len(), 1);
|
||||
let repo = repos.into_iter().next().unwrap();
|
||||
@@ -6882,7 +6884,7 @@ async fn test_remote_git_branches(
|
||||
project_a.update(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
@@ -6920,7 +6922,7 @@ async fn test_remote_git_branches(
|
||||
project_a.update(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
|
||||
@@ -314,7 +314,7 @@ async fn test_ssh_collaboration_git_branches(
|
||||
headless_project.git_store.update(cx, |git_store, cx| {
|
||||
git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
@@ -354,7 +354,7 @@ async fn test_ssh_collaboration_git_branches(
|
||||
headless_project.git_store.update(cx, |git_store, cx| {
|
||||
git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
|
||||
@@ -100,7 +100,7 @@ impl BlameRenderer for GitBlameRenderer {
|
||||
CommitTooltip::blame_entry(
|
||||
&blame_entry,
|
||||
details.clone(),
|
||||
repository.clone(),
|
||||
repository.downgrade(),
|
||||
workspace.clone(),
|
||||
cx,
|
||||
)
|
||||
@@ -149,7 +149,7 @@ impl BlameRenderer for GitBlameRenderer {
|
||||
CommitTooltip::blame_entry(
|
||||
&blame_entry,
|
||||
details.clone(),
|
||||
repository.clone(),
|
||||
repository.downgrade(),
|
||||
workspace.clone(),
|
||||
cx,
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ use git::repository::Branch;
|
||||
use gpui::{
|
||||
App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement,
|
||||
IntoElement, Modifiers, ModifiersChangedEvent, ParentElement, Render, SharedString, Styled,
|
||||
Subscription, Task, Window, rems,
|
||||
Subscription, Task, WeakEntity, Window, rems,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate, PickerEditorPosition};
|
||||
use project::git_store::Repository;
|
||||
@@ -47,7 +47,11 @@ pub fn open(
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
let repository = workspace.project().read(cx).active_repository(cx).clone();
|
||||
let repository = workspace
|
||||
.project()
|
||||
.read(cx)
|
||||
.active_repository(cx)
|
||||
.map(|repo| repo.downgrade());
|
||||
let style = BranchListStyle::Modal;
|
||||
workspace.toggle_modal(window, cx, |window, cx| {
|
||||
BranchList::new(repository, style, rems(34.), window, cx)
|
||||
@@ -55,7 +59,7 @@ pub fn open(
|
||||
}
|
||||
|
||||
pub fn popover(
|
||||
repository: Option<Entity<Repository>>,
|
||||
repository: Option<WeakEntity<Repository>>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Entity<BranchList> {
|
||||
@@ -80,7 +84,7 @@ pub struct BranchList {
|
||||
|
||||
impl BranchList {
|
||||
fn new(
|
||||
repository: Option<Entity<Repository>>,
|
||||
repository: Option<WeakEntity<Repository>>,
|
||||
style: BranchListStyle,
|
||||
width: Rems,
|
||||
window: &mut Window,
|
||||
@@ -88,6 +92,7 @@ impl BranchList {
|
||||
) -> Self {
|
||||
let all_branches_request = repository
|
||||
.clone()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
.map(|repository| repository.update(cx, |repository, _| repository.branches()));
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
@@ -172,7 +177,7 @@ struct BranchEntry {
|
||||
pub struct BranchListDelegate {
|
||||
matches: Vec<BranchEntry>,
|
||||
all_branches: Option<Vec<Branch>>,
|
||||
repo: Option<Entity<Repository>>,
|
||||
repo: Option<WeakEntity<Repository>>,
|
||||
style: BranchListStyle,
|
||||
selected_index: usize,
|
||||
last_query: String,
|
||||
@@ -180,7 +185,7 @@ pub struct BranchListDelegate {
|
||||
}
|
||||
|
||||
impl BranchListDelegate {
|
||||
fn new(repo: Option<Entity<Repository>>, style: BranchListStyle) -> Self {
|
||||
fn new(repo: Option<WeakEntity<Repository>>, style: BranchListStyle) -> Self {
|
||||
Self {
|
||||
matches: vec![],
|
||||
repo,
|
||||
@@ -339,10 +344,11 @@ impl PickerDelegate for BranchListDelegate {
|
||||
return;
|
||||
}
|
||||
|
||||
let current_branch = self.repo.as_ref().map(|repo| {
|
||||
let current_branch = self.repo.as_ref().and_then(|repo| {
|
||||
repo.update(cx, |repo, _| {
|
||||
repo.branch.as_ref().map(|branch| branch.name.clone())
|
||||
})
|
||||
.ok()
|
||||
});
|
||||
|
||||
if current_branch
|
||||
@@ -470,7 +476,11 @@ 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.upgrade()?
|
||||
.read(cx)
|
||||
.branch
|
||||
.as_ref()
|
||||
.map(|b| b.name.clone())
|
||||
})
|
||||
{
|
||||
format!("based off {}", current_branch)
|
||||
|
||||
@@ -320,7 +320,7 @@ impl CommitModal {
|
||||
|
||||
let branch = active_repo
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.read(cx).branch.as_ref())
|
||||
.and_then(|repo| repo.upgrade()?.read(cx).branch.as_ref())
|
||||
.map(|b| b.name.clone())
|
||||
.unwrap_or_else(|| "<no branch>".into());
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ pub struct CommitTooltip {
|
||||
commit: CommitDetails,
|
||||
scroll_handle: ScrollHandle,
|
||||
markdown: Entity<Markdown>,
|
||||
repository: Entity<Repository>,
|
||||
repository: WeakEntity<Repository>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ impl CommitTooltip {
|
||||
pub fn blame_entry(
|
||||
blame: &BlameEntry,
|
||||
details: Option<ParsedCommitMessage>,
|
||||
repository: Entity<Repository>,
|
||||
repository: WeakEntity<Repository>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
@@ -145,7 +145,7 @@ impl CommitTooltip {
|
||||
|
||||
pub fn new(
|
||||
commit: CommitDetails,
|
||||
repository: Entity<Repository>,
|
||||
repository: WeakEntity<Repository>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
@@ -314,7 +314,7 @@ impl Render for CommitTooltip {
|
||||
move |_, window, cx| {
|
||||
CommitView::open(
|
||||
commit_summary.clone(),
|
||||
repo.downgrade(),
|
||||
repo.clone(),
|
||||
workspace.clone(),
|
||||
window,
|
||||
cx,
|
||||
|
||||
@@ -321,7 +321,7 @@ impl ScrollbarProperties {
|
||||
}
|
||||
|
||||
pub struct GitPanel {
|
||||
pub(crate) active_repository: Option<Entity<Repository>>,
|
||||
pub(crate) active_repository: Option<WeakEntity<Repository>>,
|
||||
pub(crate) commit_editor: Entity<Editor>,
|
||||
conflicted_count: usize,
|
||||
conflicted_staged_count: usize,
|
||||
@@ -397,7 +397,10 @@ impl GitPanel {
|
||||
) -> Self {
|
||||
let fs = app_state.fs.clone();
|
||||
let git_store = project.read(cx).git_store().clone();
|
||||
let active_repository = project.read(cx).active_repository(cx);
|
||||
let active_repository = project
|
||||
.read(cx)
|
||||
.active_repository(cx)
|
||||
.map(|repo| repo.downgrade());
|
||||
let workspace = workspace.downgrade();
|
||||
|
||||
let focus_handle = cx.focus_handle();
|
||||
@@ -425,7 +428,10 @@ impl GitPanel {
|
||||
window,
|
||||
move |this, git_store, event, window, cx| match event {
|
||||
GitStoreEvent::ActiveRepositoryChanged(_) => {
|
||||
this.active_repository = git_store.read(cx).active_repository();
|
||||
this.active_repository = git_store
|
||||
.read(cx)
|
||||
.active_repository()
|
||||
.map(|repo| repo.downgrade());
|
||||
this.schedule_update(true, window, cx);
|
||||
}
|
||||
GitStoreEvent::RepositoryUpdated(
|
||||
@@ -644,7 +650,11 @@ impl GitPanel {
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(git_repo) = self.active_repository.as_ref() else {
|
||||
let Some(git_repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(repo_path) = git_repo.read(cx).project_path_to_repo_path(&path, cx) else {
|
||||
@@ -813,6 +823,7 @@ impl GitPanel {
|
||||
let have_entries = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
.map_or(false, |active_repository| {
|
||||
active_repository.read(cx).status_summary().count > 0
|
||||
});
|
||||
@@ -843,7 +854,10 @@ impl GitPanel {
|
||||
maybe!({
|
||||
let entry = self.entries.get(self.selected_entry?)?.status_entry()?;
|
||||
let workspace = self.workspace.upgrade()?;
|
||||
let git_repo = self.active_repository.as_ref()?;
|
||||
let git_repo = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())?;
|
||||
|
||||
if let Some(project_diff) = workspace.read(cx).active_item_as::<ProjectDiff>(cx) {
|
||||
if let Some(project_path) = project_diff.read(cx).active_path(cx) {
|
||||
@@ -879,7 +893,10 @@ impl GitPanel {
|
||||
) {
|
||||
maybe!({
|
||||
let entry = self.entries.get(self.selected_entry?)?.status_entry()?;
|
||||
let active_repo = self.active_repository.as_ref()?;
|
||||
let active_repo = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())?;
|
||||
let path = active_repo
|
||||
.read(cx)
|
||||
.repo_path_to_project_path(&entry.repo_path, cx)?;
|
||||
@@ -955,7 +972,10 @@ impl GitPanel {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
maybe!({
|
||||
let active_repo = self.active_repository.clone()?;
|
||||
let active_repo = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())?;
|
||||
let path = active_repo
|
||||
.read(cx)
|
||||
.repo_path_to_project_path(&entry.repo_path, cx)?;
|
||||
@@ -998,7 +1018,11 @@ impl GitPanel {
|
||||
|
||||
fn perform_checkout(&mut self, entries: Vec<GitStatusEntry>, cx: &mut Context<Self>) {
|
||||
let workspace = self.workspace.clone();
|
||||
let Some(active_repository) = self.active_repository.clone() else {
|
||||
let Some(active_repository) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -1137,7 +1161,11 @@ impl GitPanel {
|
||||
|
||||
fn clean_all(&mut self, _: &TrashUntrackedFiles, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let workspace = self.workspace.clone();
|
||||
let Some(active_repo) = self.active_repository.clone() else {
|
||||
let Some(active_repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let to_delete = self
|
||||
@@ -1233,7 +1261,11 @@ impl GitPanel {
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(active_repository) = self.active_repository.as_ref() else {
|
||||
let Some(active_repository) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let (stage, repo_paths) = match entry {
|
||||
@@ -1270,7 +1302,11 @@ impl GitPanel {
|
||||
entries: Vec<GitStatusEntry>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(active_repository) = self.active_repository.clone() else {
|
||||
let Some(active_repository) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let op_id = self.pending.iter().map(|p| p.op_id).max().unwrap_or(0) + 1;
|
||||
@@ -1430,7 +1466,11 @@ impl GitPanel {
|
||||
if !self.commit_editor.read(cx).is_empty(cx) {
|
||||
return;
|
||||
}
|
||||
let Some(active_repository) = self.active_repository.as_ref() else {
|
||||
let Some(active_repository) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(recent_sha) = active_repository
|
||||
@@ -1480,7 +1520,11 @@ impl GitPanel {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(active_repository) = self.active_repository.clone() else {
|
||||
let Some(active_repository) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let error_spawn = |message, window: &mut Window, cx: &mut App| {
|
||||
@@ -1702,7 +1746,11 @@ impl GitPanel {
|
||||
None => return,
|
||||
};
|
||||
|
||||
let Some(repo) = self.active_repository.as_ref() else {
|
||||
let Some(repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -1905,7 +1953,11 @@ impl GitPanel {
|
||||
if !self.can_push_and_pull(cx) {
|
||||
return;
|
||||
}
|
||||
let Some(repo) = self.active_repository.clone() else {
|
||||
let Some(repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(branch) = repo.read(cx).branch.as_ref() else {
|
||||
@@ -1957,7 +2009,11 @@ impl GitPanel {
|
||||
if !self.can_push_and_pull(cx) {
|
||||
return;
|
||||
}
|
||||
let Some(repo) = self.active_repository.clone() else {
|
||||
let Some(repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(branch) = repo.read(cx).branch.as_ref() else {
|
||||
@@ -2237,7 +2293,11 @@ impl GitPanel {
|
||||
}
|
||||
|
||||
fn reopen_commit_buffer(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let Some(active_repo) = self.active_repository.as_ref() else {
|
||||
let Some(active_repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let load_buffer = active_repo.update(cx, |active_repo, cx| {
|
||||
@@ -2300,7 +2360,11 @@ impl GitPanel {
|
||||
let mut staged_count = 0;
|
||||
let mut max_width_item: Option<(RepoPath, usize)> = None;
|
||||
|
||||
let Some(repo) = self.active_repository.as_ref() else {
|
||||
let Some(repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
// Just clear entries if no repository is active.
|
||||
cx.notify();
|
||||
return;
|
||||
@@ -2906,7 +2970,13 @@ impl GitPanel {
|
||||
}
|
||||
|
||||
pub(crate) fn render_remote_button(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
|
||||
let branch = self.active_repository.as_ref()?.read(cx).branch.clone();
|
||||
let branch = self
|
||||
.active_repository
|
||||
.as_ref()?
|
||||
.upgrade()?
|
||||
.read(cx)
|
||||
.branch
|
||||
.clone();
|
||||
if !self.can_push_and_pull(cx) {
|
||||
return None;
|
||||
}
|
||||
@@ -2933,7 +3003,10 @@ impl GitPanel {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<impl IntoElement> {
|
||||
let active_repository = self.active_repository.clone()?;
|
||||
let active_repository = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())?;
|
||||
let (can_commit, tooltip) = self.configure_commit_button(cx);
|
||||
let panel_editor_style = panel_editor_style(true, window, cx);
|
||||
|
||||
@@ -3248,7 +3321,10 @@ impl GitPanel {
|
||||
}
|
||||
|
||||
fn render_previous_commit(&self, cx: &mut Context<Self>) -> Option<impl IntoElement> {
|
||||
let active_repository = self.active_repository.as_ref()?;
|
||||
let active_repository = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|weak| weak.upgrade())?;
|
||||
let branch = active_repository.read(cx).branch.as_ref()?;
|
||||
let commit = branch.most_recent_commit.as_ref()?.clone();
|
||||
let workspace = self.workspace.clone();
|
||||
@@ -3293,7 +3369,7 @@ impl GitPanel {
|
||||
GitPanelMessageTooltip::new(
|
||||
this.clone(),
|
||||
commit.sha.clone(),
|
||||
repo.clone(),
|
||||
repo.downgrade(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
@@ -3328,6 +3404,10 @@ impl GitPanel {
|
||||
}
|
||||
|
||||
fn render_empty_state(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let active_repository = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade());
|
||||
h_flex()
|
||||
.h_full()
|
||||
.flex_grow()
|
||||
@@ -3337,29 +3417,50 @@ impl GitPanel {
|
||||
v_flex()
|
||||
.gap_2()
|
||||
.child(h_flex().w_full().justify_around().child(
|
||||
if self.active_repository.is_some() {
|
||||
if active_repository.is_some() {
|
||||
"No changes to commit"
|
||||
} else {
|
||||
"No Git repositories"
|
||||
"No active repository"
|
||||
},
|
||||
))
|
||||
.children({
|
||||
let repo_count = self.project.read(cx).repositories(cx).count();
|
||||
let worktree_count = self.project.read(cx).visible_worktrees(cx).count();
|
||||
(worktree_count > 0 && self.active_repository.is_none()).then(|| {
|
||||
h_flex().w_full().justify_around().child(
|
||||
panel_filled_button("Initialize Repository")
|
||||
.tooltip(Tooltip::for_action_title_in(
|
||||
"git init",
|
||||
&git::Init,
|
||||
&self.focus_handle,
|
||||
))
|
||||
.on_click(move |_, _, cx| {
|
||||
cx.defer(move |cx| {
|
||||
cx.dispatch_action(&git::Init);
|
||||
})
|
||||
}),
|
||||
if active_repository.is_none() && repo_count > 0 {
|
||||
Some(
|
||||
h_flex().w_full().justify_around().child(
|
||||
panel_filled_button("Choose Repository")
|
||||
.tooltip(Tooltip::for_action_title_in(
|
||||
"Choose Repository",
|
||||
&zed_actions::git::SelectRepo,
|
||||
&self.focus_handle,
|
||||
))
|
||||
.on_click(move |_, _, cx| {
|
||||
cx.defer(move |cx| {
|
||||
cx.dispatch_action(&zed_actions::git::SelectRepo);
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
})
|
||||
} else if active_repository.is_none() && worktree_count > 0 {
|
||||
Some(
|
||||
h_flex().w_full().justify_around().child(
|
||||
panel_filled_button("Initialize Repository")
|
||||
.tooltip(Tooltip::for_action_title_in(
|
||||
"git init",
|
||||
&git::Init,
|
||||
&self.focus_handle,
|
||||
))
|
||||
.on_click(move |_, _, cx| {
|
||||
cx.defer(move |cx| {
|
||||
cx.dispatch_action(&git::Init);
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.text_ui_sm(cx)
|
||||
.mx_auto()
|
||||
@@ -3478,7 +3579,7 @@ impl GitPanel {
|
||||
_: &Window,
|
||||
cx: &App,
|
||||
) -> Option<AnyElement> {
|
||||
let repo = self.active_repository.as_ref()?.read(cx);
|
||||
let repo = self.active_repository.as_ref()?.upgrade()?.read(cx);
|
||||
let project_path = (file.worktree_id(cx), file.path()).into();
|
||||
let repo_path = repo.project_path_to_repo_path(&project_path, cx)?;
|
||||
let ix = self.entry_by_path(&repo_path)?;
|
||||
@@ -3715,7 +3816,11 @@ impl GitPanel {
|
||||
sha: String,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<anyhow::Result<CommitDetails>> {
|
||||
let Some(repo) = self.active_repository.clone() else {
|
||||
let Some(repo) = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.upgrade())
|
||||
else {
|
||||
return Task::ready(Err(anyhow::anyhow!("no active repo")));
|
||||
};
|
||||
repo.update(cx, |repo, cx| {
|
||||
@@ -4242,7 +4347,7 @@ impl GitPanelMessageTooltip {
|
||||
fn new(
|
||||
git_panel: Entity<GitPanel>,
|
||||
sha: SharedString,
|
||||
repository: Entity<Repository>,
|
||||
repository: WeakEntity<Repository>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Entity<Self> {
|
||||
@@ -4344,7 +4449,7 @@ impl RenderOnce for PanelRepoFooter {
|
||||
|
||||
let single_repo = project
|
||||
.as_ref()
|
||||
.map(|project| project.read(cx).git_store().read(cx).repositories().len() == 1)
|
||||
.map(|project| project.read(cx).git_store().read(cx).repositories().count() == 1)
|
||||
.unwrap_or(true);
|
||||
|
||||
const MAX_BRANCH_LEN: usize = 16;
|
||||
|
||||
@@ -40,8 +40,7 @@ impl RepositorySelector {
|
||||
let repository_entries = git_store.update(cx, |git_store, _cx| {
|
||||
git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.cloned()
|
||||
.map(|(_, repository)| repository)
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let filtered_repositories = repository_entries.clone();
|
||||
|
||||
@@ -46,6 +46,7 @@ use rpc::{
|
||||
proto::{self, FromProto, SSH_PROJECT_ID, ToProto, git_reset, split_repository_update},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use settings::WorktreeId;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{BTreeSet, VecDeque},
|
||||
@@ -71,7 +72,9 @@ pub struct GitStore {
|
||||
state: GitStoreState,
|
||||
buffer_store: Entity<BufferStore>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
repositories: HashMap<RepositoryId, Entity<Repository>>,
|
||||
repositories: HashMap<RepositoryId, WeakEntity<Repository>>,
|
||||
repositories_for_worktree: HashMap<WorktreeId, Vec<Entity<Repository>>>,
|
||||
shared_repositories: HashMap<RepositoryId, Entity<Repository>>,
|
||||
active_repo_id: Option<RepositoryId>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
loading_diffs:
|
||||
@@ -403,12 +406,14 @@ impl GitStore {
|
||||
state,
|
||||
buffer_store,
|
||||
worktree_store,
|
||||
shared_repositories: HashMap::default(),
|
||||
repositories: HashMap::default(),
|
||||
active_repo_id: None,
|
||||
_subscriptions,
|
||||
loading_diffs: HashMap::default(),
|
||||
shared_diffs: HashMap::default(),
|
||||
diffs: HashMap::default(),
|
||||
repositories_for_worktree: HashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,7 +457,7 @@ impl GitStore {
|
||||
downstream: downstream_client,
|
||||
..
|
||||
} => {
|
||||
for repo in self.repositories.values() {
|
||||
for repo in self.repositories.values().filter_map(|repo| repo.upgrade()) {
|
||||
let update = repo.read(cx).snapshot.initial_update(project_id);
|
||||
for update in split_repository_update(update) {
|
||||
client.send(update).log_err();
|
||||
@@ -467,6 +472,9 @@ impl GitStore {
|
||||
let mut snapshots = HashMap::default();
|
||||
let (updates_tx, mut updates_rx) = mpsc::unbounded();
|
||||
for repo in self.repositories.values() {
|
||||
let Some(repo) = repo.upgrade() else {
|
||||
continue;
|
||||
};
|
||||
updates_tx
|
||||
.unbounded_send(DownstreamUpdate::UpdateRepository(
|
||||
repo.read(cx).snapshot.clone(),
|
||||
@@ -558,7 +566,7 @@ impl GitStore {
|
||||
pub fn active_repository(&self) -> Option<Entity<Repository>> {
|
||||
self.active_repo_id
|
||||
.as_ref()
|
||||
.map(|id| self.repositories[&id].clone())
|
||||
.and_then(|id| self.repositories[&id].upgrade())
|
||||
}
|
||||
|
||||
pub fn open_unstaged_diff(
|
||||
@@ -821,7 +829,7 @@ impl GitStore {
|
||||
pub fn checkpoint(&self, cx: &mut App) -> Task<Result<GitStoreCheckpoint>> {
|
||||
let mut work_directory_abs_paths = Vec::new();
|
||||
let mut checkpoints = Vec::new();
|
||||
for repository in self.repositories.values() {
|
||||
for (_, repository) in self.repositories() {
|
||||
repository.update(cx, |repository, _| {
|
||||
work_directory_abs_paths.push(repository.snapshot.work_directory_abs_path.clone());
|
||||
checkpoints.push(repository.checkpoint().map(|checkpoint| checkpoint?));
|
||||
@@ -844,15 +852,14 @@ impl GitStore {
|
||||
checkpoint: GitStoreCheckpoint,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<()>> {
|
||||
let repositories_by_work_dir_abs_path = self
|
||||
.repositories
|
||||
.values()
|
||||
.map(|repo| (repo.read(cx).snapshot.work_directory_abs_path.clone(), repo))
|
||||
.collect::<HashMap<_, _>>();
|
||||
let repositories_by_work_directory_abs_path =
|
||||
self.repositories_by_work_directory_abs_path(cx);
|
||||
|
||||
let mut tasks = Vec::new();
|
||||
for (work_dir_abs_path, checkpoint) in checkpoint.checkpoints_by_work_dir_abs_path {
|
||||
if let Some(repository) = repositories_by_work_dir_abs_path.get(&work_dir_abs_path) {
|
||||
if let Some(repository) =
|
||||
repositories_by_work_directory_abs_path.get(&work_dir_abs_path)
|
||||
{
|
||||
let restore = repository.update(cx, |repository, _| {
|
||||
repository.restore_checkpoint(checkpoint)
|
||||
});
|
||||
@@ -872,11 +879,7 @@ impl GitStore {
|
||||
mut right: GitStoreCheckpoint,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<bool>> {
|
||||
let repositories_by_work_dir_abs_path = self
|
||||
.repositories
|
||||
.values()
|
||||
.map(|repo| (repo.read(cx).snapshot.work_directory_abs_path.clone(), repo))
|
||||
.collect::<HashMap<_, _>>();
|
||||
let repositories_by_work_dir_abs_path = self.repositories_by_work_directory_abs_path(cx);
|
||||
|
||||
let mut tasks = Vec::new();
|
||||
for (work_dir_abs_path, left_checkpoint) in left.checkpoints_by_work_dir_abs_path {
|
||||
@@ -1129,6 +1132,7 @@ impl GitStore {
|
||||
return;
|
||||
}
|
||||
self.update_repositories_from_worktree(
|
||||
*worktree_id,
|
||||
project_environment.clone(),
|
||||
next_repository_id.clone(),
|
||||
downstream
|
||||
@@ -1140,6 +1144,25 @@ impl GitStore {
|
||||
);
|
||||
self.local_worktree_git_repos_changed(worktree, changed_repos, cx);
|
||||
}
|
||||
WorktreeStoreEvent::WorktreeRemoved(_, worktree_id) => {
|
||||
for repo in self
|
||||
.repositories_for_worktree
|
||||
.remove(worktree_id)
|
||||
.unwrap_or_default()
|
||||
{
|
||||
let id = repo.read(cx).id;
|
||||
if self.active_repo_id == Some(id) {
|
||||
if !self
|
||||
.repositories_for_worktree
|
||||
.values()
|
||||
.any(|repos| repos.iter().any(|repo| repo.read(cx).id == id))
|
||||
{
|
||||
self.repositories.remove(&id);
|
||||
self.reset_active_repository(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -1194,6 +1217,7 @@ impl GitStore {
|
||||
/// Update our list of repositories and schedule git scans in response to a notification from a worktree,
|
||||
fn update_repositories_from_worktree(
|
||||
&mut self,
|
||||
worktree_id: WorktreeId,
|
||||
project_environment: Entity<ProjectEnvironment>,
|
||||
next_repository_id: Arc<AtomicU64>,
|
||||
updates_tx: Option<mpsc::UnboundedSender<DownstreamUpdate>>,
|
||||
@@ -1202,8 +1226,9 @@ impl GitStore {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let mut removed_ids = Vec::new();
|
||||
self.repositories.retain(|_, weak| weak.is_upgradable());
|
||||
for update in updated_git_repositories.iter() {
|
||||
if let Some((id, existing)) = self.repositories.iter().find(|(_, repo)| {
|
||||
if let Some((id, existing)) = self.repositories().find(|(_, repo)| {
|
||||
let existing_work_directory_abs_path =
|
||||
repo.read(cx).work_directory_abs_path.clone();
|
||||
Some(&existing_work_directory_abs_path)
|
||||
@@ -1219,7 +1244,7 @@ impl GitStore {
|
||||
existing.schedule_scan(updates_tx.clone(), cx);
|
||||
});
|
||||
} else {
|
||||
removed_ids.push(*id);
|
||||
removed_ids.push(id);
|
||||
}
|
||||
} else if let UpdatedGitRepository {
|
||||
new_work_directory_abs_path: Some(work_directory_abs_path),
|
||||
@@ -1250,21 +1275,32 @@ impl GitStore {
|
||||
.push(cx.subscribe(&repo, Self::on_repository_event));
|
||||
self._subscriptions
|
||||
.push(cx.subscribe(&repo, Self::on_jobs_updated));
|
||||
self.repositories.insert(id, repo);
|
||||
self.repositories.insert(id, repo.downgrade());
|
||||
self.repositories_for_worktree
|
||||
.entry(worktree_id)
|
||||
.or_default()
|
||||
.push(repo);
|
||||
|
||||
cx.emit(GitStoreEvent::RepositoryAdded(id));
|
||||
self.active_repo_id.get_or_insert_with(|| {
|
||||
cx.emit(GitStoreEvent::ActiveRepositoryChanged(Some(id)));
|
||||
id
|
||||
});
|
||||
if self.active_repo_id.is_none() {
|
||||
self.reset_active_repository(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for id in removed_ids {
|
||||
if self.active_repo_id == Some(id) {
|
||||
self.active_repo_id = None;
|
||||
cx.emit(GitStoreEvent::ActiveRepositoryChanged(None));
|
||||
}
|
||||
// Remove all references to the repository, even if it's referenced by other worktrees,
|
||||
// since they all point to the same FS state.
|
||||
self.repositories.remove(&id);
|
||||
self.repositories_for_worktree
|
||||
.values_mut()
|
||||
.for_each(|repos| {
|
||||
repos.retain(|repo| repo.read(cx).id != id);
|
||||
});
|
||||
if self.active_repo_id == Some(id) {
|
||||
self.reset_active_repository(cx);
|
||||
}
|
||||
|
||||
if let Some(updates_tx) = updates_tx.as_ref() {
|
||||
updates_tx
|
||||
.unbounded_send(DownstreamUpdate::RemoveRepository(id))
|
||||
@@ -1384,7 +1420,7 @@ impl GitStore {
|
||||
log::debug!("local worktree repos changed");
|
||||
debug_assert!(worktree.read(cx).is_local());
|
||||
|
||||
for repository in self.repositories.values() {
|
||||
for (_, repository) in self.repositories() {
|
||||
repository.update(cx, |repository, cx| {
|
||||
let repo_abs_path = &repository.work_directory_abs_path;
|
||||
if changed_repos.iter().any(|update| {
|
||||
@@ -1397,8 +1433,10 @@ impl GitStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn repositories(&self) -> &HashMap<RepositoryId, Entity<Repository>> {
|
||||
&self.repositories
|
||||
pub fn repositories(&self) -> impl Iterator<Item = (RepositoryId, Entity<Repository>)> {
|
||||
self.repositories
|
||||
.iter()
|
||||
.filter_map(|(id, weak_repository)| Some((*id, weak_repository.upgrade()?)))
|
||||
}
|
||||
|
||||
pub fn status_for_buffer_id(&self, buffer_id: BufferId, cx: &App) -> Option<FileStatus> {
|
||||
@@ -1426,6 +1464,7 @@ impl GitStore {
|
||||
self.repositories
|
||||
.values()
|
||||
.filter_map(|repo| {
|
||||
let repo = repo.upgrade()?;
|
||||
let repo_path = repo.read(cx).abs_path_to_repo_path(&abs_path)?;
|
||||
Some((repo.clone(), repo_path))
|
||||
})
|
||||
@@ -1485,7 +1524,7 @@ impl GitStore {
|
||||
.clone();
|
||||
|
||||
let mut is_new = false;
|
||||
let repo = this.repositories.entry(id).or_insert_with(|| {
|
||||
let repo = this.shared_repositories.entry(id).or_insert_with(|| {
|
||||
is_new = true;
|
||||
let git_store = cx.weak_entity();
|
||||
cx.new(|cx| {
|
||||
@@ -1499,6 +1538,10 @@ impl GitStore {
|
||||
)
|
||||
})
|
||||
});
|
||||
this.repositories
|
||||
.entry(id)
|
||||
.or_insert_with(|| repo.downgrade());
|
||||
|
||||
if is_new {
|
||||
this._subscriptions
|
||||
.push(cx.subscribe(&repo, Self::on_repository_event))
|
||||
@@ -1509,10 +1552,9 @@ impl GitStore {
|
||||
|repo, cx| repo.apply_remote_update(update, cx)
|
||||
})?;
|
||||
|
||||
this.active_repo_id.get_or_insert_with(|| {
|
||||
cx.emit(GitStoreEvent::ActiveRepositoryChanged(Some(id)));
|
||||
id
|
||||
});
|
||||
if this.active_repo_id.is_none() {
|
||||
this.reset_active_repository(cx);
|
||||
}
|
||||
|
||||
if let Some((client, project_id)) = this.downstream_client() {
|
||||
update.project_id = project_id.to_proto();
|
||||
@@ -1531,13 +1573,13 @@ impl GitStore {
|
||||
let mut update = envelope.payload;
|
||||
let id = RepositoryId::from_proto(update.id);
|
||||
this.repositories.remove(&id);
|
||||
this.shared_repositories.remove(&id);
|
||||
if let Some((client, project_id)) = this.downstream_client() {
|
||||
update.project_id = project_id.to_proto();
|
||||
client.send(update).log_err();
|
||||
}
|
||||
if this.active_repo_id == Some(id) {
|
||||
this.active_repo_id = None;
|
||||
cx.emit(GitStoreEvent::ActiveRepositoryChanged(None));
|
||||
this.reset_active_repository(cx);
|
||||
}
|
||||
cx.emit(GitStoreEvent::RepositoryRemoved(id));
|
||||
})
|
||||
@@ -2190,15 +2232,23 @@ impl GitStore {
|
||||
.get(&id)
|
||||
.context("missing repository handle")
|
||||
.cloned()
|
||||
})?
|
||||
})??
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("Repository was released"))
|
||||
}
|
||||
|
||||
pub fn repo_snapshots(&self, cx: &App) -> HashMap<RepositoryId, RepositorySnapshot> {
|
||||
self.repositories
|
||||
.iter()
|
||||
.map(|(id, repo)| (*id, repo.read(cx).snapshot.clone()))
|
||||
.filter_map(|(id, repo)| Some((*id, repo.upgrade()?.read(cx).snapshot.clone())))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn reset_active_repository(&mut self, cx: &mut Context<Self>) {
|
||||
let id = self.repositories().map(|(id, _)| id).next();
|
||||
self.active_repo_id = id;
|
||||
cx.emit(GitStoreEvent::ActiveRepositoryChanged(id))
|
||||
}
|
||||
}
|
||||
|
||||
impl BufferGitState {
|
||||
|
||||
@@ -4835,7 +4835,10 @@ impl Project {
|
||||
join_all(scans_complete).await;
|
||||
let barriers = this
|
||||
.update(cx, |this, cx| {
|
||||
let repos = this.repositories(cx).values().cloned().collect::<Vec<_>>();
|
||||
let repos: Vec<Entity<Repository>> = this
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.collect::<Vec<_>>();
|
||||
repos
|
||||
.into_iter()
|
||||
.map(|repo| repo.update(cx, |repo, _| repo.barrier()))
|
||||
@@ -4850,7 +4853,10 @@ impl Project {
|
||||
self.git_store.read(cx).active_repository()
|
||||
}
|
||||
|
||||
pub fn repositories<'a>(&self, cx: &'a App) -> &'a HashMap<RepositoryId, Entity<Repository>> {
|
||||
pub fn repositories(
|
||||
&self,
|
||||
cx: &App,
|
||||
) -> impl Iterator<Item = (RepositoryId, Entity<Repository>)> {
|
||||
self.git_store.read(cx).repositories()
|
||||
}
|
||||
|
||||
|
||||
@@ -7446,7 +7446,12 @@ async fn test_git_repository_status(cx: &mut gpui::TestAppContext) {
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project.repositories(cx).values().next().unwrap().clone()
|
||||
project
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
|
||||
// Check that the right git state is observed on startup
|
||||
@@ -7571,7 +7576,7 @@ async fn test_git_status_postprocessing(cx: &mut gpui::TestAppContext) {
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.find(|repo| repo.read(cx).work_directory_abs_path.ends_with("project"))
|
||||
.unwrap()
|
||||
.clone()
|
||||
@@ -7644,7 +7649,12 @@ async fn test_repository_subfolder_git_status(
|
||||
cx.run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project.repositories(cx).values().next().unwrap().clone()
|
||||
project
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
|
||||
// Ensure that the git status is loaded correctly
|
||||
@@ -7786,7 +7796,12 @@ async fn test_update_gitignore(cx: &mut gpui::TestAppContext) {
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project.repositories(cx).values().next().unwrap().clone()
|
||||
project
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
|
||||
// One file is unmodified, the other is ignored.
|
||||
@@ -7856,7 +7871,12 @@ async fn test_rename_work_directory(cx: &mut gpui::TestAppContext) {
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project.repositories(cx).values().next().unwrap().clone()
|
||||
project
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
|
||||
repository.read_with(cx, |repository, _| {
|
||||
@@ -7956,7 +7976,12 @@ async fn test_file_status(cx: &mut gpui::TestAppContext) {
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project.repositories(cx).values().next().unwrap().clone()
|
||||
project
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
|
||||
// Check that the right git state is observed on startup
|
||||
@@ -8123,7 +8148,7 @@ async fn test_repos_in_invisible_worktrees(
|
||||
let repos = project.read_with(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.map(|repo| repo.read(cx).work_directory_abs_path.clone())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
@@ -8144,7 +8169,7 @@ async fn test_repos_in_invisible_worktrees(
|
||||
let repos = project.read_with(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.map(|repo| repo.read(cx).work_directory_abs_path.clone())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
@@ -8197,7 +8222,12 @@ async fn test_rescan_with_gitignore(cx: &mut gpui::TestAppContext) {
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project.repositories(cx).values().next().unwrap().clone()
|
||||
project
|
||||
.repositories(cx)
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.clone()
|
||||
});
|
||||
|
||||
tree.read_with(cx, |tree, _| {
|
||||
@@ -8345,7 +8375,7 @@ async fn test_git_worktrees_and_submodules(cx: &mut gpui::TestAppContext) {
|
||||
let mut repositories = project.update(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.map(|repo| repo.read(cx).work_directory_abs_path.clone())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
@@ -8481,7 +8511,7 @@ async fn test_repository_deduplication(cx: &mut gpui::TestAppContext) {
|
||||
let repos = project.read_with(cx, |project, cx| {
|
||||
project
|
||||
.repositories(cx)
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.map(|repo| repo.read(cx).work_directory_abs_path.clone())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
@@ -1493,7 +1493,7 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
|
||||
headless_project.git_store.update(cx, |git_store, cx| {
|
||||
git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
@@ -1533,7 +1533,7 @@ async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestA
|
||||
headless_project.git_store.update(cx, |git_store, cx| {
|
||||
git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.map(|(_, repository)| repository)
|
||||
.next()
|
||||
.unwrap()
|
||||
.read(cx)
|
||||
|
||||
Reference in New Issue
Block a user