Fix git stage race condition with delayed fs events (#27036)
This PR adds a failing test `test_staging_hunks_with_delayed_fs_event` and makes it pass Also skips a queued read for git diff states if another read was requested (less work) This still doesn't catch all race conditions, but the PR is getting long so I'll yield this and start another branch Release Notes: - N/A
This commit is contained in:
parent
68a572873b
commit
7f2e3fb5bd
10 changed files with 476 additions and 245 deletions
|
@ -4575,7 +4575,7 @@ mod tests {
|
|||
]
|
||||
);
|
||||
|
||||
let repo_from_single_file_worktree = project.update(cx, |project, cx| {
|
||||
project.update(cx, |project, cx| {
|
||||
let git_store = project.git_store().read(cx);
|
||||
// The repo that comes from the single-file worktree can't be selected through the UI.
|
||||
let filtered_entries = filtered_repository_entries(git_store, cx)
|
||||
|
@ -4587,18 +4587,20 @@ mod tests {
|
|||
[Path::new(path!("/root/zed/crates/gpui")).into()]
|
||||
);
|
||||
// But we can select it artificially here.
|
||||
git_store
|
||||
.all_repositories()
|
||||
.into_iter()
|
||||
let repo_from_single_file_worktree = git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.find(|repo| {
|
||||
&*repo.read(cx).worktree_abs_path
|
||||
repo.read(cx).worktree_abs_path.as_ref()
|
||||
== Path::new(path!("/root/zed/crates/util/util.rs"))
|
||||
})
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
// Paths still make sense when we somehow activate a repo that comes from a single-file worktree.
|
||||
repo_from_single_file_worktree.update(cx, |repo, cx| repo.set_as_active_repository(cx));
|
||||
});
|
||||
|
||||
// Paths still make sense when we somehow activate a repo that comes from a single-file worktree.
|
||||
repo_from_single_file_worktree.update(cx, |repo, cx| repo.activate(cx));
|
||||
let handle = cx.update_window_entity(&panel, |panel, _, _| {
|
||||
std::mem::replace(&mut panel.update_visible_entries_task, Task::ready(()))
|
||||
});
|
||||
|
|
|
@ -75,28 +75,30 @@ pub(crate) fn filtered_repository_entries(
|
|||
git_store: &GitStore,
|
||||
cx: &App,
|
||||
) -> Vec<Entity<Repository>> {
|
||||
let mut repository_entries = git_store.all_repositories();
|
||||
repository_entries.sort_by_key(|repo| {
|
||||
let repo = repo.read(cx);
|
||||
(
|
||||
repo.dot_git_abs_path.clone(),
|
||||
repo.worktree_abs_path.clone(),
|
||||
)
|
||||
});
|
||||
// Remove any entry that comes from a single file worktree and represents a repository that is also represented by a non-single-file worktree.
|
||||
repository_entries
|
||||
let repositories = git_store
|
||||
.repositories()
|
||||
.values()
|
||||
.sorted_by_key(|repo| {
|
||||
let repo = repo.read(cx);
|
||||
(
|
||||
repo.dot_git_abs_path.clone(),
|
||||
repo.worktree_abs_path.clone(),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<&Entity<Repository>>>();
|
||||
|
||||
repositories
|
||||
.chunk_by(|a, b| a.read(cx).dot_git_abs_path == b.read(cx).dot_git_abs_path)
|
||||
.flat_map(|chunk| {
|
||||
let has_non_single_file_worktree = chunk
|
||||
.iter()
|
||||
.any(|repo| !repo.read(cx).is_from_single_file_worktree);
|
||||
chunk
|
||||
.iter()
|
||||
.filter(move |repo| {
|
||||
!repo.read(cx).is_from_single_file_worktree || !has_non_single_file_worktree
|
||||
})
|
||||
.cloned()
|
||||
chunk.iter().filter(move |repo| {
|
||||
// Remove any entry that comes from a single file worktree and represents a repository that is also represented by a non-single-file worktree.
|
||||
!repo.read(cx).is_from_single_file_worktree || !has_non_single_file_worktree
|
||||
})
|
||||
})
|
||||
.map(|&repo| repo.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -195,7 +197,9 @@ impl PickerDelegate for RepositorySelectorDelegate {
|
|||
let Some(selected_repo) = self.filtered_repositories.get(self.selected_index) else {
|
||||
return;
|
||||
};
|
||||
selected_repo.update(cx, |selected_repo, cx| selected_repo.activate(cx));
|
||||
selected_repo.update(cx, |selected_repo, cx| {
|
||||
selected_repo.set_as_active_repository(cx)
|
||||
});
|
||||
self.dismissed(window, cx);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue