mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-30 06:05:19 +00:00
WIP pls amend me
Co-Authored-By: Max Brunsfeld <max@zed.dev> Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
8d2de1074b
commit
bb8798a844
4 changed files with 78 additions and 2 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3996,6 +3996,7 @@ dependencies = [
|
||||||
"fsevent",
|
"fsevent",
|
||||||
"futures",
|
"futures",
|
||||||
"fuzzy",
|
"fuzzy",
|
||||||
|
"git2",
|
||||||
"gpui",
|
"gpui",
|
||||||
"ignore",
|
"ignore",
|
||||||
"language",
|
"language",
|
||||||
|
|
|
@ -52,6 +52,7 @@ smol = "1.2.5"
|
||||||
thiserror = "1.0.29"
|
thiserror = "1.0.29"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
rocksdb = "0.18"
|
rocksdb = "0.18"
|
||||||
|
git2 = { version = "0.15", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
client = { path = "../client", features = ["test-support"] }
|
client = { path = "../client", features = ["test-support"] }
|
||||||
|
|
|
@ -27,7 +27,7 @@ use language::{
|
||||||
Buffer, DiagnosticEntry, LineEnding, PointUtf16, Rope,
|
Buffer, DiagnosticEntry, LineEnding, PointUtf16, Rope,
|
||||||
};
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::{Mutex, RwLock};
|
||||||
use postage::{
|
use postage::{
|
||||||
prelude::{Sink as _, Stream as _},
|
prelude::{Sink as _, Stream as _},
|
||||||
watch,
|
watch,
|
||||||
|
@ -105,12 +105,20 @@ pub struct Snapshot {
|
||||||
pub struct LocalSnapshot {
|
pub struct LocalSnapshot {
|
||||||
abs_path: Arc<Path>,
|
abs_path: Arc<Path>,
|
||||||
ignores_by_parent_abs_path: HashMap<Arc<Path>, (Arc<Gitignore>, usize)>,
|
ignores_by_parent_abs_path: HashMap<Arc<Path>, (Arc<Gitignore>, usize)>,
|
||||||
|
git_repositories: Vec<GitRepositoryState>,
|
||||||
removed_entry_ids: HashMap<u64, ProjectEntryId>,
|
removed_entry_ids: HashMap<u64, ProjectEntryId>,
|
||||||
next_entry_id: Arc<AtomicUsize>,
|
next_entry_id: Arc<AtomicUsize>,
|
||||||
snapshot: Snapshot,
|
snapshot: Snapshot,
|
||||||
extension_counts: HashMap<OsString, usize>,
|
extension_counts: HashMap<OsString, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct GitRepositoryState {
|
||||||
|
content_path: Arc<Path>,
|
||||||
|
git_dir_path: Arc<Path>,
|
||||||
|
repository: Arc<Mutex<git2::Repository>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for LocalSnapshot {
|
impl Deref for LocalSnapshot {
|
||||||
type Target = Snapshot;
|
type Target = Snapshot;
|
||||||
|
|
||||||
|
@ -143,6 +151,7 @@ struct ShareState {
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
UpdatedEntries,
|
UpdatedEntries,
|
||||||
|
UpdatedGitRepositories(Vec<GitRepositoryState>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Worktree {
|
impl Entity for Worktree {
|
||||||
|
@ -373,6 +382,7 @@ impl LocalWorktree {
|
||||||
let mut snapshot = LocalSnapshot {
|
let mut snapshot = LocalSnapshot {
|
||||||
abs_path,
|
abs_path,
|
||||||
ignores_by_parent_abs_path: Default::default(),
|
ignores_by_parent_abs_path: Default::default(),
|
||||||
|
git_repositories: Default::default(),
|
||||||
removed_entry_ids: Default::default(),
|
removed_entry_ids: Default::default(),
|
||||||
next_entry_id,
|
next_entry_id,
|
||||||
snapshot: Snapshot {
|
snapshot: Snapshot {
|
||||||
|
@ -504,6 +514,7 @@ impl LocalWorktree {
|
||||||
|
|
||||||
fn poll_snapshot(&mut self, force: bool, cx: &mut ModelContext<Worktree>) {
|
fn poll_snapshot(&mut self, force: bool, cx: &mut ModelContext<Worktree>) {
|
||||||
self.poll_task.take();
|
self.poll_task.take();
|
||||||
|
|
||||||
match self.scan_state() {
|
match self.scan_state() {
|
||||||
ScanState::Idle => {
|
ScanState::Idle => {
|
||||||
self.snapshot = self.background_snapshot.lock().clone();
|
self.snapshot = self.background_snapshot.lock().clone();
|
||||||
|
@ -512,6 +523,7 @@ impl LocalWorktree {
|
||||||
}
|
}
|
||||||
cx.emit(Event::UpdatedEntries);
|
cx.emit(Event::UpdatedEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanState::Initializing => {
|
ScanState::Initializing => {
|
||||||
let is_fake_fs = self.fs.is_fake();
|
let is_fake_fs = self.fs.is_fake();
|
||||||
self.snapshot = self.background_snapshot.lock().clone();
|
self.snapshot = self.background_snapshot.lock().clone();
|
||||||
|
@ -528,12 +540,14 @@ impl LocalWorktree {
|
||||||
}));
|
}));
|
||||||
cx.emit(Event::UpdatedEntries);
|
cx.emit(Event::UpdatedEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
if force {
|
if force {
|
||||||
self.snapshot = self.background_snapshot.lock().clone();
|
self.snapshot = self.background_snapshot.lock().clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1286,6 +1300,10 @@ impl LocalSnapshot {
|
||||||
&self.extension_counts
|
&self.extension_counts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn git_repository_for_file_path(&self, path: &Path) -> Option<GitRepositoryState> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn build_initial_update(&self, project_id: u64) -> proto::UpdateWorktree {
|
pub(crate) fn build_initial_update(&self, project_id: u64) -> proto::UpdateWorktree {
|
||||||
let root_name = self.root_name.clone();
|
let root_name = self.root_name.clone();
|
||||||
|
@ -3043,6 +3061,61 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_git_repository_for_path(cx: &mut TestAppContext) {
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
fs.insert_tree(
|
||||||
|
"/root",
|
||||||
|
json!({
|
||||||
|
"dir1": {
|
||||||
|
".git": {},
|
||||||
|
"deps": {
|
||||||
|
"dep1": {
|
||||||
|
".git": {},
|
||||||
|
"src": {
|
||||||
|
"a.txt": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"src": {
|
||||||
|
"b.txt": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c.txt": ""
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let http_client = FakeHttpClient::with_404_response();
|
||||||
|
let client = Client::new(http_client);
|
||||||
|
let tree = Worktree::local(
|
||||||
|
client,
|
||||||
|
Arc::from(Path::new("/root")),
|
||||||
|
true,
|
||||||
|
fs.clone(),
|
||||||
|
Default::default(),
|
||||||
|
&mut cx.to_async(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
cx.foreground().run_until_parked();
|
||||||
|
|
||||||
|
tree.read_with(cx, |tree, cx| {
|
||||||
|
let tree = tree.as_local().unwrap();
|
||||||
|
|
||||||
|
assert!(tree.git_repository_for_file_path("c.txt".as_ref()).is_none());
|
||||||
|
|
||||||
|
let repo1 = tree.git_repository_for_file_path("dir1/src/b.txt".as_ref()).unwrap().lock();
|
||||||
|
assert_eq!(repo1.content_path.as_ref(), Path::new("dir1"));
|
||||||
|
assert_eq!(repo1.git_dir_path.as_ref(), Path::new("dir1/.git"));
|
||||||
|
|
||||||
|
let repo2 = tree.git_repository_for_file_path("dir1/deps/dep1/src/a.txt".as_ref()).unwrap().lock();
|
||||||
|
assert_eq!(repo2.content_path.as_ref(), Path::new("dir1/deps/dep1"));
|
||||||
|
assert_eq!(repo2.git_dir_path.as_ref(), Path::new("dir1/deps/dep1/.git"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_write_file(cx: &mut TestAppContext) {
|
async fn test_write_file(cx: &mut TestAppContext) {
|
||||||
let dir = temp_tree(json!({
|
let dir = temp_tree(json!({
|
||||||
|
@ -3161,6 +3234,7 @@ mod tests {
|
||||||
abs_path: root_dir.path().into(),
|
abs_path: root_dir.path().into(),
|
||||||
removed_entry_ids: Default::default(),
|
removed_entry_ids: Default::default(),
|
||||||
ignores_by_parent_abs_path: Default::default(),
|
ignores_by_parent_abs_path: Default::default(),
|
||||||
|
git_repositories: Default::default(),
|
||||||
next_entry_id: next_entry_id.clone(),
|
next_entry_id: next_entry_id.clone(),
|
||||||
snapshot: Snapshot {
|
snapshot: Snapshot {
|
||||||
id: WorktreeId::from_usize(0),
|
id: WorktreeId::from_usize(0),
|
||||||
|
|
Loading…
Reference in a new issue