Git on main thread (#26573)
This moves spawning of the git subprocess to the main thread. We're not yet sure why, but when we spawn a process using GCD's background queues, sub-processes like git-credential-manager fail to open windows. This seems to be fixable either by using the main thread, or by using a standard background thread, but for now we use the main thread. Release Notes: - Git: Fix git-credential-manager --------- Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com> Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
parent
5268e74315
commit
7bca15704b
11 changed files with 926 additions and 713 deletions
|
@ -401,7 +401,7 @@ impl GitStore {
|
|||
if let Some((repo, path)) = this.repository_and_path_for_buffer_id(buffer_id, cx) {
|
||||
let recv = repo.update(cx, |repo, cx| {
|
||||
repo.set_index_text(
|
||||
&path,
|
||||
path,
|
||||
new_index_text.as_ref().map(|rope| rope.to_string()),
|
||||
cx,
|
||||
)
|
||||
|
@ -715,7 +715,7 @@ impl GitStore {
|
|||
repository_handle
|
||||
.update(&mut cx, |repository_handle, cx| {
|
||||
repository_handle.set_index_text(
|
||||
&RepoPath::from_str(&envelope.payload.path),
|
||||
RepoPath::from_str(&envelope.payload.path),
|
||||
envelope.payload.text,
|
||||
cx,
|
||||
)
|
||||
|
@ -808,7 +808,7 @@ impl GitStore {
|
|||
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.create_branch(&branch_name)
|
||||
repository_handle.create_branch(branch_name)
|
||||
})?
|
||||
.await??;
|
||||
|
||||
|
@ -828,7 +828,7 @@ impl GitStore {
|
|||
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.change_branch(&branch_name)
|
||||
repository_handle.change_branch(branch_name)
|
||||
})?
|
||||
.await??;
|
||||
|
||||
|
@ -847,7 +847,7 @@ impl GitStore {
|
|||
|
||||
let commit = repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.show(&envelope.payload.commit)
|
||||
repository_handle.show(envelope.payload.commit)
|
||||
})?
|
||||
.await??;
|
||||
Ok(proto::GitCommitDetails {
|
||||
|
@ -876,7 +876,7 @@ impl GitStore {
|
|||
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, cx| {
|
||||
repository_handle.reset(&envelope.payload.commit, mode, cx)
|
||||
repository_handle.reset(envelope.payload.commit, mode, cx)
|
||||
})?
|
||||
.await??;
|
||||
Ok(proto::Ack {})
|
||||
|
@ -1081,8 +1081,8 @@ impl Repository {
|
|||
|
||||
fn send_job<F, Fut, R>(&self, job: F) -> oneshot::Receiver<R>
|
||||
where
|
||||
F: FnOnce(GitRepo) -> Fut + 'static,
|
||||
Fut: Future<Output = R> + Send + 'static,
|
||||
F: FnOnce(GitRepo, AsyncApp) -> Fut + 'static,
|
||||
Fut: Future<Output = R> + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.send_keyed_job(None, job)
|
||||
|
@ -1090,8 +1090,8 @@ impl Repository {
|
|||
|
||||
fn send_keyed_job<F, Fut, R>(&self, key: Option<GitJobKey>, job: F) -> oneshot::Receiver<R>
|
||||
where
|
||||
F: FnOnce(GitRepo) -> Fut + 'static,
|
||||
Fut: Future<Output = R> + Send + 'static,
|
||||
F: FnOnce(GitRepo, AsyncApp) -> Fut + 'static,
|
||||
Fut: Future<Output = R> + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let (result_tx, result_rx) = futures::channel::oneshot::channel();
|
||||
|
@ -1100,8 +1100,8 @@ impl Repository {
|
|||
.unbounded_send(GitJob {
|
||||
key,
|
||||
job: Box::new(|cx: &mut AsyncApp| {
|
||||
let job = job(git_repo);
|
||||
cx.background_spawn(async move {
|
||||
let job = job(git_repo, cx.clone());
|
||||
cx.spawn(|_| async move {
|
||||
let result = job.await;
|
||||
result_tx.send(result).ok();
|
||||
})
|
||||
|
@ -1292,9 +1292,9 @@ impl Repository {
|
|||
let commit = commit.to_string();
|
||||
let env = self.worktree_environment(cx);
|
||||
|
||||
self.send_job(|git_repo| async move {
|
||||
self.send_job(|git_repo, _| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(repo) => repo.checkout_files(&commit, &paths, &env.await),
|
||||
GitRepo::Local(repo) => repo.checkout_files(commit, paths, env.await).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1322,17 +1322,17 @@ impl Repository {
|
|||
|
||||
pub fn reset(
|
||||
&self,
|
||||
commit: &str,
|
||||
commit: String,
|
||||
reset_mode: ResetMode,
|
||||
cx: &mut App,
|
||||
) -> oneshot::Receiver<Result<()>> {
|
||||
let commit = commit.to_string();
|
||||
let env = self.worktree_environment(cx);
|
||||
self.send_job(|git_repo| async move {
|
||||
self.send_job(|git_repo, _| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(git_repo) => {
|
||||
let env = env.await;
|
||||
git_repo.reset(&commit, reset_mode, &env)
|
||||
git_repo.reset(commit, reset_mode, env).await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
|
@ -1359,11 +1359,10 @@ impl Repository {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn show(&self, commit: &str) -> oneshot::Receiver<Result<CommitDetails>> {
|
||||
let commit = commit.to_string();
|
||||
self.send_job(|git_repo| async move {
|
||||
pub fn show(&self, commit: String) -> oneshot::Receiver<Result<CommitDetails>> {
|
||||
self.send_job(|git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(git_repository) => git_repository.show(&commit),
|
||||
GitRepo::Local(git_repository) => git_repository.show(commit, cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1433,9 +1432,9 @@ impl Repository {
|
|||
let env = env.await;
|
||||
|
||||
this.update(&mut cx, |this, _| {
|
||||
this.send_job(|git_repo| async move {
|
||||
this.send_job(|git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(repo) => repo.stage_paths(&entries, &env),
|
||||
GitRepo::Local(repo) => repo.stage_paths(entries, env, cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1504,9 +1503,9 @@ impl Repository {
|
|||
let env = env.await;
|
||||
|
||||
this.update(&mut cx, |this, _| {
|
||||
this.send_job(|git_repo| async move {
|
||||
this.send_job(|git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(repo) => repo.unstage_paths(&entries, &env),
|
||||
GitRepo::Local(repo) => repo.unstage_paths(entries, env, cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1587,17 +1586,11 @@ impl Repository {
|
|||
cx: &mut App,
|
||||
) -> oneshot::Receiver<Result<()>> {
|
||||
let env = self.worktree_environment(cx);
|
||||
self.send_job(|git_repo| async move {
|
||||
self.send_job(|git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(repo) => {
|
||||
let env = env.await;
|
||||
repo.commit(
|
||||
message.as_ref(),
|
||||
name_and_email
|
||||
.as_ref()
|
||||
.map(|(name, email)| (name.as_ref(), email.as_ref())),
|
||||
&env,
|
||||
)
|
||||
repo.commit(message, name_and_email, env, cx).await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
|
@ -1634,12 +1627,12 @@ impl Repository {
|
|||
let askpass_id = util::post_inc(&mut self.latest_askpass_id);
|
||||
let env = self.worktree_environment(cx);
|
||||
|
||||
self.send_job(move |git_repo| async move {
|
||||
self.send_job(move |git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(git_repository) => {
|
||||
let askpass = AskPassSession::new(&executor, askpass).await?;
|
||||
let env = env.await;
|
||||
git_repository.fetch(askpass, &env)
|
||||
git_repository.fetch(askpass, env, cx).await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
|
@ -1685,12 +1678,21 @@ impl Repository {
|
|||
let askpass_id = util::post_inc(&mut self.latest_askpass_id);
|
||||
let env = self.worktree_environment(cx);
|
||||
|
||||
self.send_job(move |git_repo| async move {
|
||||
self.send_job(move |git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(git_repository) => {
|
||||
let env = env.await;
|
||||
let askpass = AskPassSession::new(&executor, askpass).await?;
|
||||
git_repository.push(&branch, &remote, options, askpass, &env)
|
||||
git_repository
|
||||
.push(
|
||||
branch.to_string(),
|
||||
remote.to_string(),
|
||||
options,
|
||||
askpass,
|
||||
env,
|
||||
cx,
|
||||
)
|
||||
.await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
|
@ -1740,12 +1742,14 @@ impl Repository {
|
|||
let askpass_id = util::post_inc(&mut self.latest_askpass_id);
|
||||
let env = self.worktree_environment(cx);
|
||||
|
||||
self.send_job(move |git_repo| async move {
|
||||
self.send_job(move |git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(git_repository) => {
|
||||
let askpass = AskPassSession::new(&executor, askpass).await?;
|
||||
let env = env.await;
|
||||
git_repository.pull(&branch, &remote, askpass, &env)
|
||||
git_repository
|
||||
.pull(branch.to_string(), remote.to_string(), askpass, env, cx)
|
||||
.await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
|
@ -1781,18 +1785,17 @@ impl Repository {
|
|||
|
||||
fn set_index_text(
|
||||
&self,
|
||||
path: &RepoPath,
|
||||
path: RepoPath,
|
||||
content: Option<String>,
|
||||
cx: &mut App,
|
||||
) -> oneshot::Receiver<anyhow::Result<()>> {
|
||||
let path = path.clone();
|
||||
let env = self.worktree_environment(cx);
|
||||
|
||||
self.send_keyed_job(
|
||||
Some(GitJobKey::WriteIndex(path.clone())),
|
||||
|git_repo| async move {
|
||||
|git_repo, cx| async move {
|
||||
match git_repo {
|
||||
GitRepo::Local(repo) => repo.set_index_text(&path, content, &env.await),
|
||||
GitRepo::Local(repo) => repo.set_index_text(path, content, env.await, cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1819,11 +1822,9 @@ impl Repository {
|
|||
&self,
|
||||
branch_name: Option<String>,
|
||||
) -> oneshot::Receiver<Result<Vec<Remote>>> {
|
||||
self.send_job(|repo| async move {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => {
|
||||
git_repository.get_remotes(branch_name.as_deref())
|
||||
}
|
||||
GitRepo::Local(git_repository) => git_repository.get_remotes(branch_name, cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1854,9 +1855,13 @@ impl Repository {
|
|||
}
|
||||
|
||||
pub fn branches(&self) -> oneshot::Receiver<Result<Vec<Branch>>> {
|
||||
self.send_job(|repo| async move {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => git_repository.branches(),
|
||||
GitRepo::Local(git_repository) => {
|
||||
let git_repository = git_repository.clone();
|
||||
cx.background_spawn(async move { git_repository.branches().await })
|
||||
.await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1884,9 +1889,9 @@ impl Repository {
|
|||
}
|
||||
|
||||
pub fn diff(&self, diff_type: DiffType, _cx: &App) -> oneshot::Receiver<Result<String>> {
|
||||
self.send_job(|repo| async move {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => git_repository.diff(diff_type),
|
||||
GitRepo::Local(git_repository) => git_repository.diff(diff_type, cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1916,11 +1921,12 @@ impl Repository {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn create_branch(&self, branch_name: &str) -> oneshot::Receiver<Result<()>> {
|
||||
let branch_name = branch_name.to_owned();
|
||||
self.send_job(|repo| async move {
|
||||
pub fn create_branch(&self, branch_name: String) -> oneshot::Receiver<Result<()>> {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => git_repository.create_branch(&branch_name),
|
||||
GitRepo::Local(git_repository) => {
|
||||
git_repository.create_branch(branch_name, cx).await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1942,11 +1948,12 @@ impl Repository {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn change_branch(&self, branch_name: &str) -> oneshot::Receiver<Result<()>> {
|
||||
let branch_name = branch_name.to_owned();
|
||||
self.send_job(|repo| async move {
|
||||
pub fn change_branch(&self, branch_name: String) -> oneshot::Receiver<Result<()>> {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => git_repository.change_branch(&branch_name),
|
||||
GitRepo::Local(git_repository) => {
|
||||
git_repository.change_branch(branch_name, cx).await
|
||||
}
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
@ -1969,9 +1976,9 @@ impl Repository {
|
|||
}
|
||||
|
||||
pub fn check_for_pushed_commits(&self) -> oneshot::Receiver<Result<Vec<SharedString>>> {
|
||||
self.send_job(|repo| async move {
|
||||
self.send_job(|repo, cx| async move {
|
||||
match repo {
|
||||
GitRepo::Local(git_repository) => git_repository.check_for_pushed_commit(),
|
||||
GitRepo::Local(git_repository) => git_repository.check_for_pushed_commit(cx).await,
|
||||
GitRepo::Remote {
|
||||
project_id,
|
||||
client,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue