git: Intercept signing prompt from GPG when committing (#34096)

Closes #30111 

- [x] basic implementation
- [x] implementation for remote projects
- [x] surface error output from GPG if signing fails
- [ ] ~~Windows~~

Release Notes:

- git: Passphrase prompts from GPG to unlock commit signing keys are now
shown in Zed.
This commit is contained in:
Cole Miller 2025-07-10 20:38:51 -04:00 committed by GitHub
parent 87362c602f
commit 842ac984d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 193 additions and 51 deletions

View file

@ -1574,10 +1574,15 @@ impl GitPanel {
let task = if self.has_staged_changes() {
// Repository serializes all git operations, so we can just send a commit immediately
let commit_task = active_repository.update(cx, |repo, cx| {
repo.commit(message.into(), None, options, cx)
});
cx.background_spawn(async move { commit_task.await? })
cx.spawn_in(window, async move |this, cx| {
let askpass_delegate = this.update_in(cx, |this, window, cx| {
this.askpass_delegate("git commit", window, cx)
})?;
let commit_task = active_repository.update(cx, |repo, cx| {
repo.commit(message.into(), None, options, askpass_delegate, cx)
})?;
commit_task.await?
})
} else {
let changed_files = self
.entries
@ -1594,10 +1599,13 @@ impl GitPanel {
let stage_task =
active_repository.update(cx, |repo, cx| repo.stage_entries(changed_files, cx));
cx.spawn(async move |_, cx| {
cx.spawn_in(window, async move |this, cx| {
stage_task.await?;
let askpass_delegate = this.update_in(cx, |this, window, cx| {
this.askpass_delegate("git commit".to_string(), window, cx)
})?;
let commit_task = active_repository.update(cx, |repo, cx| {
repo.commit(message.into(), None, options, cx)
repo.commit(message.into(), None, options, askpass_delegate, cx)
})?;
commit_task.await?
})