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:
Kirill Bulatov 2025-02-05 17:36:24 +02:00 committed by GitHub
parent da4bad3a55
commit 868e3f75b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 428 additions and 372 deletions

View file

@ -163,6 +163,7 @@ impl ProjectDiff {
};
let Some(path) = git_repo
.read(cx)
.repo_path_to_project_path(&entry.repo_path)
.and_then(|project_path| self.project.read(cx).absolute_path(&project_path, cx))
else {
@ -234,43 +235,45 @@ impl ProjectDiff {
let mut previous_paths = self.multibuffer.read(cx).paths().collect::<HashSet<_>>();
let mut result = vec![];
for entry in repo.status() {
if !entry.status.has_changes() {
continue;
repo.update(cx, |repo, cx| {
for entry in repo.status() {
if !entry.status.has_changes() {
continue;
}
let Some(project_path) = repo.repo_path_to_project_path(&entry.repo_path) else {
continue;
};
let Some(abs_path) = self.project.read(cx).absolute_path(&project_path, cx) else {
continue;
};
// Craft some artificial paths so that created entries will appear last.
let path_key = if entry.status.is_created() {
PathKey::namespaced(ADDED_NAMESPACE, &abs_path)
} else {
PathKey::namespaced(CHANGED_NAMESPACE, &abs_path)
};
previous_paths.remove(&path_key);
let load_buffer = self
.project
.update(cx, |project, cx| project.open_buffer(project_path, cx));
let project = self.project.clone();
result.push(cx.spawn(|_, mut cx| async move {
let buffer = load_buffer.await?;
let changes = project
.update(&mut cx, |project, cx| {
project.open_uncommitted_changes(buffer.clone(), cx)
})?
.await?;
Ok(DiffBuffer {
path_key,
buffer,
change_set: changes,
})
}));
}
let Some(project_path) = repo.repo_path_to_project_path(&entry.repo_path) else {
continue;
};
let Some(abs_path) = self.project.read(cx).absolute_path(&project_path, cx) else {
continue;
};
// Craft some artificial paths so that created entries will appear last.
let path_key = if entry.status.is_created() {
PathKey::namespaced(ADDED_NAMESPACE, &abs_path)
} else {
PathKey::namespaced(CHANGED_NAMESPACE, &abs_path)
};
previous_paths.remove(&path_key);
let load_buffer = self
.project
.update(cx, |project, cx| project.open_buffer(project_path, cx));
let project = self.project.clone();
result.push(cx.spawn(|_, mut cx| async move {
let buffer = load_buffer.await?;
let changes = project
.update(&mut cx, |project, cx| {
project.open_uncommitted_changes(buffer.clone(), cx)
})?
.await?;
Ok(DiffBuffer {
path_key,
buffer,
change_set: changes,
})
}));
}
});
self.multibuffer.update(cx, |multibuffer, cx| {
for path in previous_paths {
multibuffer.remove_excerpts_for_path(path, cx);