git: Suppress blame errors outside Git repositories (#56348)
Resolves https://github.com/zed-industries/zed/issues/55552 Git blame can be initialized for buffers that are not backed by any Git repository. Previously, that path still called into `Project::blame_buffer`, which returned an error because there was no repository for the buffer. When blame was user-triggered, that error was surfaced as a toast even though this is an expected “not applicable” state rather than a failed Git operation. This diff checks whether the buffer belongs to a repository before requesting blame data. Buffers outside Git repositories now produce no blame entries without emitting an error, while real blame failures inside repositories continue to use the existing error notification path. Release Notes: - Improved Git blame to quietly ignore files that are not part of a Git repository. Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
1 parent
7f826e82c7
commit
5b948e5aab
1 file changed
+83
-5
@@ -522,14 +522,25 @@ impl GitBlame {
|
||||
let id = buffer.read(cx).remote_id();
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
let buffer_edits = buffer.update(cx, |buffer, _| buffer.subscribe());
|
||||
let remote_url = project
|
||||
|
||||
let repository = project
|
||||
.read(cx)
|
||||
.git_store()
|
||||
.read(cx)
|
||||
.repository_and_path_for_buffer_id(buffer.read(cx).remote_id(), cx)
|
||||
.repository_and_path_for_buffer_id(id, cx);
|
||||
|
||||
let remote_url = repository
|
||||
.as_ref()
|
||||
.and_then(|(repo, _)| repo.read(cx).default_remote_url());
|
||||
let blame_buffer = project
|
||||
.update(cx, |project, cx| project.blame_buffer(&buffer, None, cx));
|
||||
|
||||
let blame_buffer = if repository.is_some() {
|
||||
project.update(cx, |project, cx| {
|
||||
project.blame_buffer(&buffer, None, cx)
|
||||
})
|
||||
} else {
|
||||
Task::ready(Ok(None))
|
||||
};
|
||||
|
||||
Ok(async move {
|
||||
(id, snapshot, buffer_edits, blame_buffer.await, remote_url)
|
||||
})
|
||||
@@ -696,7 +707,7 @@ mod tests {
|
||||
use rand::prelude::*;
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use std::{cmp, env, ops::Range, path::Path};
|
||||
use std::{cmp, env, ops::Range, path::Path, sync::Mutex};
|
||||
use text::BufferId;
|
||||
use unindent::Unindent as _;
|
||||
use util::{RandomCharIter, path};
|
||||
@@ -811,6 +822,73 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_blame_ignores_buffers_outside_git_repositories(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
fs.insert_tree(
|
||||
"/not-a-repo",
|
||||
json!({
|
||||
"foo": "bar",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/not-a-repo".as_ref()], cx).await;
|
||||
|
||||
let buffer = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer("/not-a-repo/foo", cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let buffer_id = buffer.read_with(cx, |buffer, _| buffer.remote_id());
|
||||
|
||||
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
|
||||
let events = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let _subscription = project.update(cx, |_, cx| {
|
||||
cx.subscribe(&project, {
|
||||
let events = events.clone();
|
||||
|
||||
move |_, _, event: &project::Event, _| {
|
||||
events
|
||||
.lock()
|
||||
.expect("events mutex poisoned")
|
||||
.push(event.clone());
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let blame = cx.new(|cx| GitBlame::new(buffer.clone(), project.clone(), true, true, cx));
|
||||
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
assert!(events.lock().expect("events mutex poisoned").is_empty());
|
||||
|
||||
blame.update(cx, |blame, cx| {
|
||||
assert_eq!(
|
||||
blame
|
||||
.blame_for_rows(
|
||||
&(0..1)
|
||||
.map(|row| RowInfo {
|
||||
buffer_row: Some(row),
|
||||
buffer_id: Some(buffer_id),
|
||||
..Default::default()
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
cx
|
||||
)
|
||||
.collect::<Vec<_>>(),
|
||||
vec![None]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_blame_for_rows(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
Reference in new issue
Block a user