Cargo.lock 🔗
@@ -6359,6 +6359,8 @@ version = "0.1.0"
dependencies = [
"anyhow",
"futures",
+ "git2",
+ "lazy_static",
"log",
"rand 0.8.5",
"serde_json",
Mikayla Maki created
Cargo.lock | 2
crates/project/Cargo.toml | 1
crates/project/src/git_repository.rs | 10 ++++
crates/project/src/worktree.rs | 68 +++++++++++++++--------------
crates/util/Cargo.toml | 6 ++
crates/util/src/lib.rs | 7 +++
crates/util/src/test.rs | 8 +++
7 files changed, 68 insertions(+), 34 deletions(-)
@@ -6359,6 +6359,8 @@ version = "0.1.0"
dependencies = [
"anyhow",
"futures",
+ "git2",
+ "lazy_static",
"log",
"rand 0.8.5",
"serde_json",
@@ -54,6 +54,7 @@ toml = "0.5"
rocksdb = "0.18"
git2 = { version = "0.15", default-features = false }
+
[dev-dependencies]
client = { path = "../client", features = ["test-support"] }
collections = { path = "../collections", features = ["test-support"] }
@@ -11,6 +11,7 @@ pub trait GitRepository: Send + Sync {
fn git_dir_path(&self) -> &Path;
fn last_scan_id(&self) -> usize;
fn set_scan_id(&mut self, scan_id: usize);
+ fn with_repo(&mut self, f: Box<dyn FnOnce(&mut git2::Repository)>);
}
#[derive(Clone)]
@@ -70,6 +71,11 @@ impl GitRepository for RealGitRepository {
fn set_scan_id(&mut self, scan_id: usize) {
self.last_scan_id = scan_id;
}
+
+ fn with_repo(&mut self, f: Box<dyn FnOnce(&mut git2::Repository)>) {
+ let mut git2 = self.libgit_repository.lock();
+ f(&mut git2)
+ }
}
impl PartialEq for &Box<dyn GitRepository> {
@@ -129,4 +135,8 @@ impl GitRepository for FakeGitRepository {
fn set_scan_id(&mut self, scan_id: usize) {
self.last_scan_id = scan_id;
}
+
+ fn with_repo(&mut self, _: Box<dyn FnOnce(&mut git2::Repository)>) {
+ unimplemented!();
+ }
}
@@ -26,7 +26,6 @@ use language::{
proto::{deserialize_version, serialize_line_ending, serialize_version},
Buffer, DiagnosticEntry, LineEnding, PointUtf16, Rope,
};
-use lazy_static::lazy_static;
use parking_lot::Mutex;
use postage::{
prelude::{Sink as _, Stream as _},
@@ -50,12 +49,7 @@ use std::{
time::{Duration, SystemTime},
};
use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap, TreeSet};
-use util::{ResultExt, TryFutureExt};
-
-lazy_static! {
- static ref DOT_GIT: &'static OsStr = OsStr::new(".git");
- static ref GITIGNORE: &'static OsStr = OsStr::new(".gitignore");
-}
+use util::{ResultExt, TryFutureExt, DOT_GIT, GITIGNORE};
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
pub struct WorktreeId(usize);
@@ -1317,6 +1311,13 @@ impl LocalSnapshot {
&self,
path: &Path,
) -> Option<Box<dyn GitRepository>> {
+ let repos = self
+ .git_repositories
+ .iter()
+ .map(|repo| repo.content_path().to_str().unwrap().to_string())
+ .collect::<Vec<String>>();
+ dbg!(repos);
+
self.git_repositories
.iter()
.rev() //git_repository is ordered lexicographically
@@ -1437,6 +1438,7 @@ impl LocalSnapshot {
}
fn insert_entry(&mut self, mut entry: Entry, fs: &dyn Fs) -> Entry {
+ dbg!(&entry.path);
if entry.is_file() && entry.path.file_name() == Some(&GITIGNORE) {
let abs_path = self.abs_path.join(&entry.path);
match smol::block_on(build_gitignore(&abs_path, fs)) {
@@ -1455,6 +1457,8 @@ impl LocalSnapshot {
}
}
} else if entry.path.file_name() == Some(&DOT_GIT) {
+ dbg!(&entry.path);
+
let abs_path = self.abs_path.join(&entry.path);
let content_path: Arc<Path> = entry.path.parent().unwrap().into();
if let Err(ix) = self
@@ -2223,6 +2227,7 @@ impl BackgroundScanner {
if ignore_stack.is_all() {
if let Some(mut root_entry) = snapshot.root_entry().cloned() {
root_entry.is_ignored = true;
+ dbg!("scan dirs entry");
snapshot.insert_entry(root_entry, self.fs.as_ref());
}
}
@@ -2445,6 +2450,7 @@ impl BackgroundScanner {
snapshot.root_char_bag,
);
fs_entry.is_ignored = ignore_stack.is_all();
+ dbg!("process_events entry");
snapshot.insert_entry(fs_entry, self.fs.as_ref());
let mut ancestor_inodes = snapshot.ancestor_inodes_for_path(&path);
@@ -3145,50 +3151,46 @@ 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": {
- "HEAD": "abc"
- },
- "deps": {
- "dep1": {
- ".git": {},
- "src": {
- "a.txt": ""
- }
+ let root = temp_tree(json!({
+ "dir1": {
+ ".git": {},
+ "deps": {
+ "dep1": {
+ ".git": {},
+ "src": {
+ "a.txt": ""
}
- },
- "src": {
- "b.txt": ""
}
},
- "c.txt": ""
- }),
- )
- .await;
+ "src": {
+ "b.txt": ""
+ }
+ },
+ "c.txt": ""
+ }));
let http_client = FakeHttpClient::with_404_response();
let client = Client::new(http_client);
let tree = Worktree::local(
client,
- Arc::from(Path::new("/root")),
+ root.path(),
true,
- fs.clone(),
+ Arc::new(RealFs),
Default::default(),
&mut cx.to_async(),
)
.await
.unwrap();
- cx.foreground().run_until_parked();
+ cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
+ .await;
+ tree.flush_fs_events(cx).await;
- tree.read_with(cx, |tree, cx| {
+ tree.read_with(cx, |tree, _cx| {
let tree = tree.as_local().unwrap();
+ dbg!(tree);
+
assert!(tree
.git_repository_for_file_path("c.txt".as_ref())
.is_none());
@@ -7,17 +7,21 @@ edition = "2021"
doctest = false
[features]
-test-support = ["rand", "serde_json", "tempdir"]
+test-support = ["rand", "serde_json", "tempdir", "git2"]
[dependencies]
anyhow = "1.0.38"
futures = "0.3"
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
+lazy_static = "1.4.0"
rand = { version = "0.8", optional = true }
tempdir = { version = "0.3.7", optional = true }
serde_json = { version = "1.0", features = ["preserve_order"], optional = true }
+git2 = { version = "0.15", default-features = false, optional = true }
+
[dev-dependencies]
rand = { version = "0.8" }
tempdir = { version = "0.3.7" }
serde_json = { version = "1.0", features = ["preserve_order"] }
+git2 = { version = "0.15", default-features = false }
@@ -2,13 +2,20 @@
pub mod test;
use futures::Future;
+use lazy_static::lazy_static;
use std::{
cmp::Ordering,
+ ffi::OsStr,
ops::AddAssign,
pin::Pin,
task::{Context, Poll},
};
+lazy_static! {
+ pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git");
+ pub static ref GITIGNORE: &'static OsStr = OsStr::new(".gitignore");
+}
+
pub fn truncate(s: &str, max_chars: usize) -> &str {
match s.char_indices().nth(max_chars) {
None => s,
@@ -1,12 +1,15 @@
mod assertions;
mod marked_text;
+use git2;
use std::path::{Path, PathBuf};
use tempdir::TempDir;
pub use assertions::*;
pub use marked_text::*;
+use crate::DOT_GIT;
+
pub fn temp_tree(tree: serde_json::Value) -> TempDir {
let dir = TempDir::new("").unwrap();
write_tree(dir.path(), tree);
@@ -24,6 +27,11 @@ fn write_tree(path: &Path, tree: serde_json::Value) {
match contents {
Value::Object(_) => {
fs::create_dir(&path).unwrap();
+
+ if path.file_name() == Some(&DOT_GIT) {
+ git2::Repository::init(&path.parent().unwrap()).unwrap();
+ }
+
write_tree(&path, contents);
}
Value::Null => {