Rework shared commit editors (#24274)
Rework of https://github.com/zed-industries/zed/pull/24130
Uses
1033c0b57e
`COMMIT_EDITMSG` language-related definitions (thanks @d1y )
Instead of using real `.git/COMMIT_EDITMSG` file, create a buffer
without FS representation, stored in the `Repository` and shared the
regular way via the `BufferStore`.
Adds a knowledge of what `Git Commit` language is, and uses it in the
buffers which are rendered in the git panel.
Release Notes:
- N/A
---------
Co-authored-by: Conrad Irwin <conrad@zed.dev>
Co-authored-by: d1y <chenhonzhou@gmail.com>
Co-authored-by: Smit <smit@zed.dev>
This commit is contained in:
parent
da4bad3a55
commit
868e3f75b2
17 changed files with 428 additions and 372 deletions
|
@ -22,7 +22,7 @@ mod project_tests;
|
|||
mod direnv;
|
||||
mod environment;
|
||||
pub use environment::EnvironmentErrorMessage;
|
||||
use git::RepositoryHandle;
|
||||
use git::Repository;
|
||||
pub mod search_history;
|
||||
mod yarn;
|
||||
|
||||
|
@ -48,7 +48,6 @@ use ::git::{
|
|||
blame::Blame,
|
||||
repository::{Branch, GitRepository, RepoPath},
|
||||
status::FileStatus,
|
||||
COMMIT_MESSAGE,
|
||||
};
|
||||
use gpui::{
|
||||
AnyEntity, App, AppContext as _, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter,
|
||||
|
@ -1998,12 +1997,15 @@ impl Project {
|
|||
project_id,
|
||||
id: id.into(),
|
||||
});
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
cx.spawn(move |project, mut cx| async move {
|
||||
let buffer_id = BufferId::new(request.await?.buffer_id)?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await
|
||||
project
|
||||
.update(&mut cx, |project, cx| {
|
||||
project.buffer_store.update(cx, |buffer_store, cx| {
|
||||
buffer_store.wait_for_remote_buffer(buffer_id, cx)
|
||||
})
|
||||
})?
|
||||
.await
|
||||
})
|
||||
} else {
|
||||
Task::ready(Err(anyhow!("cannot open buffer while disconnected")))
|
||||
|
@ -2846,16 +2848,21 @@ impl Project {
|
|||
|
||||
let proto_client = ssh_client.read(cx).proto_client();
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
cx.spawn(|project, mut cx| async move {
|
||||
let buffer = proto_client
|
||||
.request(proto::OpenServerSettings {
|
||||
project_id: SSH_PROJECT_ID,
|
||||
})
|
||||
.await?;
|
||||
|
||||
let buffer = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
anyhow::Ok(this.wait_for_remote_buffer(BufferId::new(buffer.buffer_id)?, cx))
|
||||
let buffer = project
|
||||
.update(&mut cx, |project, cx| {
|
||||
project.buffer_store.update(cx, |buffer_store, cx| {
|
||||
anyhow::Ok(
|
||||
buffer_store
|
||||
.wait_for_remote_buffer(BufferId::new(buffer.buffer_id)?, cx),
|
||||
)
|
||||
})
|
||||
})??
|
||||
.await;
|
||||
|
||||
|
@ -3186,13 +3193,15 @@ impl Project {
|
|||
});
|
||||
let guard = self.retain_remotely_created_models(cx);
|
||||
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
cx.spawn(move |project, mut cx| async move {
|
||||
let response = request.await?;
|
||||
for buffer_id in response.buffer_ids {
|
||||
let buffer_id = BufferId::new(buffer_id)?;
|
||||
let buffer = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
let buffer = project
|
||||
.update(&mut cx, |project, cx| {
|
||||
project.buffer_store.update(cx, |buffer_store, cx| {
|
||||
buffer_store.wait_for_remote_buffer(buffer_id, cx)
|
||||
})
|
||||
})?
|
||||
.await?;
|
||||
let _ = tx.send(buffer).await;
|
||||
|
@ -3998,7 +4007,11 @@ impl Project {
|
|||
.map(RepoPath::new)
|
||||
.collect();
|
||||
|
||||
repository_handle.stage_entries(entries).await?;
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.stage_entries(entries)
|
||||
})?
|
||||
.await??;
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
|
||||
|
@ -4020,7 +4033,11 @@ impl Project {
|
|||
.map(RepoPath::new)
|
||||
.collect();
|
||||
|
||||
repository_handle.unstage_entries(entries).await?;
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.unstage_entries(entries)
|
||||
})?
|
||||
.await??;
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
|
||||
|
@ -4034,9 +4051,14 @@ impl Project {
|
|||
let repository_handle =
|
||||
Self::repository_for_request(&this, worktree_id, work_directory_id, &mut cx)?;
|
||||
|
||||
let message = SharedString::from(envelope.payload.message);
|
||||
let name = envelope.payload.name.map(SharedString::from);
|
||||
let email = envelope.payload.email.map(SharedString::from);
|
||||
repository_handle.commit(name.zip(email)).await?;
|
||||
repository_handle
|
||||
.update(&mut cx, |repository_handle, _| {
|
||||
repository_handle.commit(message, name.zip(email))
|
||||
})?
|
||||
.await??;
|
||||
Ok(proto::Ack {})
|
||||
}
|
||||
|
||||
|
@ -4049,55 +4071,12 @@ impl Project {
|
|||
let work_directory_id = ProjectEntryId::from_proto(envelope.payload.work_directory_id);
|
||||
let repository_handle =
|
||||
Self::repository_for_request(&this, worktree_id, work_directory_id, &mut cx)?;
|
||||
let git_repository = match &repository_handle.git_repo {
|
||||
git::GitRepo::Local(git_repository) => git_repository.clone(),
|
||||
git::GitRepo::Remote { .. } => {
|
||||
anyhow::bail!("Cannot handle open commit message buffer for remote git repo")
|
||||
}
|
||||
};
|
||||
let commit_message_file = git_repository.dot_git_dir().join(*COMMIT_MESSAGE);
|
||||
let fs = this.update(&mut cx, |project, _| project.fs().clone())?;
|
||||
fs.create_file(
|
||||
&commit_message_file,
|
||||
CreateOptions {
|
||||
overwrite: false,
|
||||
ignore_if_exists: true,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.with_context(|| format!("creating commit message file {commit_message_file:?}"))?;
|
||||
|
||||
let (worktree, relative_path) = this
|
||||
.update(&mut cx, |headless_project, cx| {
|
||||
headless_project
|
||||
.worktree_store
|
||||
.update(cx, |worktree_store, cx| {
|
||||
worktree_store.find_or_create_worktree(&commit_message_file, false, cx)
|
||||
})
|
||||
})?
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!("deriving worktree for commit message file {commit_message_file:?}")
|
||||
})?;
|
||||
|
||||
let buffer = this
|
||||
.update(&mut cx, |headless_project, cx| {
|
||||
headless_project
|
||||
.buffer_store
|
||||
.update(cx, |buffer_store, cx| {
|
||||
buffer_store.open_buffer(
|
||||
ProjectPath {
|
||||
worktree_id: worktree.read(cx).id(),
|
||||
path: Arc::from(relative_path),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
})
|
||||
})
|
||||
.with_context(|| {
|
||||
format!("opening buffer for commit message file {commit_message_file:?}")
|
||||
let buffer = repository_handle
|
||||
.update(&mut cx, |repository_handle, cx| {
|
||||
repository_handle.open_commit_buffer(None, this.read(cx).buffer_store.clone(), cx)
|
||||
})?
|
||||
.await?;
|
||||
|
||||
let peer_id = envelope.original_sender_id()?;
|
||||
Project::respond_to_open_buffer_request(this, buffer, peer_id, &mut cx)
|
||||
}
|
||||
|
@ -4107,7 +4086,7 @@ impl Project {
|
|||
worktree_id: WorktreeId,
|
||||
work_directory_id: ProjectEntryId,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<RepositoryHandle> {
|
||||
) -> Result<Entity<Repository>> {
|
||||
this.update(cx, |project, cx| {
|
||||
let repository_handle = project
|
||||
.git_state()
|
||||
|
@ -4115,6 +4094,7 @@ impl Project {
|
|||
.all_repositories()
|
||||
.into_iter()
|
||||
.find(|repository_handle| {
|
||||
let repository_handle = repository_handle.read(cx);
|
||||
repository_handle.worktree_id == worktree_id
|
||||
&& repository_handle.repository_entry.work_directory_id()
|
||||
== work_directory_id
|
||||
|
@ -4160,16 +4140,6 @@ impl Project {
|
|||
buffer.read(cx).remote_id()
|
||||
}
|
||||
|
||||
pub fn wait_for_remote_buffer(
|
||||
&mut self,
|
||||
id: BufferId,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Entity<Buffer>>> {
|
||||
self.buffer_store.update(cx, |buffer_store, cx| {
|
||||
buffer_store.wait_for_remote_buffer(id, cx)
|
||||
})
|
||||
}
|
||||
|
||||
fn synchronize_remote_buffers(&mut self, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
let project_id = match self.client_state {
|
||||
ProjectClientState::Remote {
|
||||
|
@ -4329,11 +4299,11 @@ impl Project {
|
|||
&self.git_state
|
||||
}
|
||||
|
||||
pub fn active_repository(&self, cx: &App) -> Option<RepositoryHandle> {
|
||||
pub fn active_repository(&self, cx: &App) -> Option<Entity<Repository>> {
|
||||
self.git_state.read(cx).active_repository()
|
||||
}
|
||||
|
||||
pub fn all_repositories(&self, cx: &App) -> Vec<RepositoryHandle> {
|
||||
pub fn all_repositories(&self, cx: &App) -> Vec<Entity<Repository>> {
|
||||
self.git_state.read(cx).all_repositories()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue