From d5fd531743680c568e64faa75e1059f20b215453 Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 28 Sep 2022 11:43:33 -0400 Subject: [PATCH] Move git related things into specialized git crate Co-Authored-By: Mikayla Maki --- Cargo.lock | 22 +++++++- crates/editor/Cargo.toml | 1 + crates/editor/src/element.rs | 2 +- crates/editor/src/multi_buffer.rs | 8 +-- crates/git/Cargo.toml | 22 ++++++++ .../{language/src/git.rs => git/src/diff.rs} | 6 +-- crates/git/src/git.rs | 12 +++++ .../src/repository.rs} | 20 +++---- crates/language/Cargo.toml | 2 +- crates/language/src/buffer.rs | 33 ++++++------ crates/language/src/language.rs | 1 - crates/project/Cargo.toml | 3 +- crates/project/src/fs.rs | 4 -- crates/project/src/project.rs | 45 ++++++++++------ crates/project/src/worktree.rs | 54 +++++++++++-------- crates/util/src/lib.rs | 7 --- crates/util/src/test.rs | 9 ++-- 17 files changed, 151 insertions(+), 100 deletions(-) create mode 100644 crates/git/Cargo.toml rename crates/{language/src/git.rs => git/src/diff.rs} (98%) create mode 100644 crates/git/src/git.rs rename crates/{project/src/git_repository.rs => git/src/repository.rs} (80%) diff --git a/Cargo.lock b/Cargo.lock index 8157327cf2..c8918158be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1697,6 +1697,7 @@ dependencies = [ "env_logger", "futures", "fuzzy", + "git", "gpui", "indoc", "itertools", @@ -2224,6 +2225,23 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "git" +version = "0.1.0" +dependencies = [ + "anyhow", + "clock", + "git2", + "lazy_static", + "log", + "parking_lot 0.11.2", + "smol", + "sum_tree", + "text", + "unindent", + "util", +] + [[package]] name = "git2" version = "0.15.0" @@ -2853,7 +2871,7 @@ dependencies = [ "env_logger", "futures", "fuzzy", - "git2", + "git", "gpui", "lazy_static", "log", @@ -3996,7 +4014,7 @@ dependencies = [ "fsevent", "futures", "fuzzy", - "git2", + "git", "gpui", "ignore", "language", diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index dfd4938742..2ea7473b59 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -25,6 +25,7 @@ clock = { path = "../clock" } collections = { path = "../collections" } context_menu = { path = "../context_menu" } fuzzy = { path = "../fuzzy" } +git = { path = "../git" } gpui = { path = "../gpui" } language = { path = "../language" } lsp = { path = "../lsp" } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 2e767d72e6..4bc9f9a10b 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -16,6 +16,7 @@ use crate::{ }; use clock::ReplicaId; use collections::{BTreeMap, HashMap}; +use git::diff::{DiffHunk, DiffHunkStatus}; use gpui::{ color::Color, elements::*, @@ -34,7 +35,6 @@ use gpui::{ WeakViewHandle, }; use json::json; -use language::git::{DiffHunk, DiffHunkStatus}; use language::{Bias, DiagnosticSeverity, OffsetUtf16, Selection}; use project::ProjectPath; use settings::Settings; diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 76093e0496..b4e302e3c3 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -4,13 +4,13 @@ pub use anchor::{Anchor, AnchorRangeExt}; use anyhow::Result; use clock::ReplicaId; use collections::{BTreeMap, Bound, HashMap, HashSet}; +use git::diff::DiffHunk; use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task}; pub use language::Completion; use language::{ - char_kind, git::DiffHunk, AutoindentMode, Buffer, BufferChunks, BufferSnapshot, CharKind, - Chunk, DiagnosticEntry, Event, File, IndentSize, Language, OffsetRangeExt, Outline, - OutlineItem, Selection, ToOffset as _, ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, - TransactionId, + char_kind, AutoindentMode, Buffer, BufferChunks, BufferSnapshot, CharKind, Chunk, + DiagnosticEntry, Event, File, IndentSize, Language, OffsetRangeExt, Outline, OutlineItem, + Selection, ToOffset as _, ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId, }; use smallvec::SmallVec; use std::{ diff --git a/crates/git/Cargo.toml b/crates/git/Cargo.toml new file mode 100644 index 0000000000..79ac56d098 --- /dev/null +++ b/crates/git/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "git" +version = "0.1.0" +edition = "2021" + +[lib] +path = "src/git.rs" + +[dependencies] +anyhow = "1.0.38" +clock = { path = "../clock" } +git2 = { version = "0.15", default-features = false } +lazy_static = "1.4.0" +sum_tree = { path = "../sum_tree" } +text = { path = "../text" } +util = { path = "../util" } +log = { version = "0.4.16", features = ["kv_unstable_serde"] } +smol = "1.2" +parking_lot = "0.11.1" + +[dev-dependencies] +unindent = "0.1.7" diff --git a/crates/language/src/git.rs b/crates/git/src/diff.rs similarity index 98% rename from crates/language/src/git.rs rename to crates/git/src/diff.rs index d713dcbc14..ddaddb7289 100644 --- a/crates/language/src/git.rs +++ b/crates/git/src/diff.rs @@ -259,7 +259,7 @@ mod tests { use text::Buffer; use unindent::Unindent as _; - #[gpui::test] + #[test] fn test_buffer_diff_simple() { let head_text = " one @@ -308,8 +308,4 @@ mod tests { ); } } - - // use rand::rngs::StdRng; - // #[gpui::test(iterations = 100)] - // fn test_buffer_diff_random(mut rng: StdRng) {} } diff --git a/crates/git/src/git.rs b/crates/git/src/git.rs new file mode 100644 index 0000000000..36f54e706a --- /dev/null +++ b/crates/git/src/git.rs @@ -0,0 +1,12 @@ +use std::ffi::OsStr; + +pub use git2 as libgit; +pub use lazy_static::lazy_static; + +pub mod diff; +pub mod repository; + +lazy_static! { + pub static ref DOT_GIT: &'static OsStr = OsStr::new(".git"); + pub static ref GITIGNORE: &'static OsStr = OsStr::new(".gitignore"); +} diff --git a/crates/project/src/git_repository.rs b/crates/git/src/repository.rs similarity index 80% rename from crates/project/src/git_repository.rs rename to crates/git/src/repository.rs index 4b46b18391..a38d13ef0d 100644 --- a/crates/project/src/git_repository.rs +++ b/crates/git/src/repository.rs @@ -1,7 +1,7 @@ use anyhow::Result; -use git2::{Repository as LibGitRepository, RepositoryOpenFlags as LibGitRepositoryOpenFlags}; +use git2::Repository as LibGitRepository; use parking_lot::Mutex; -use std::{ffi::OsStr, path::Path, sync::Arc}; +use std::{path::Path, sync::Arc}; use util::ResultExt; #[derive(Clone)] @@ -53,21 +53,17 @@ impl GitRepository { self.scan_id } - pub(super) fn set_scan_id(&mut self, scan_id: usize) { + pub fn set_scan_id(&mut self, scan_id: usize) { + println!("setting scan id"); self.scan_id = scan_id; } - pub fn with_repo(&mut self, f: F) { - let mut git2 = self.libgit_repository.lock(); - f(&mut git2) - } - - pub async fn load_head_text(&self, file_path: &Path) -> Option { - fn logic(repo: &LibGitRepository, file_path: &Path) -> Result> { + pub async fn load_head_text(&self, relative_file_path: &Path) -> Option { + fn logic(repo: &LibGitRepository, relative_file_path: &Path) -> Result> { let object = repo .head()? .peel_to_tree()? - .get_path(file_path)? + .get_path(relative_file_path)? .to_object(&repo)?; let content = match object.as_blob() { @@ -79,7 +75,7 @@ impl GitRepository { Ok(Some(head_text)) } - match logic(&self.libgit_repository.lock(), file_path) { + match logic(&self.libgit_repository.as_ref().lock(), relative_file_path) { Ok(value) => return value, Err(err) => log::error!("Error loading head text: {:?}", err), } diff --git a/crates/language/Cargo.toml b/crates/language/Cargo.toml index 034b10e89c..7a218acc8e 100644 --- a/crates/language/Cargo.toml +++ b/crates/language/Cargo.toml @@ -25,6 +25,7 @@ client = { path = "../client" } clock = { path = "../clock" } collections = { path = "../collections" } fuzzy = { path = "../fuzzy" } +git = { path = "../git" } gpui = { path = "../gpui" } lsp = { path = "../lsp" } rpc = { path = "../rpc" } @@ -51,7 +52,6 @@ smol = "1.2" tree-sitter = "0.20" tree-sitter-rust = { version = "*", optional = true } tree-sitter-typescript = { version = "*", optional = true } -git2 = { version = "0.15", default-features = false } [dev-dependencies] client = { path = "../client", features = ["test-support"] } diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 9d386c14ad..13fe6daed5 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -1,4 +1,3 @@ -use crate::git; pub use crate::{ diagnostic_set::DiagnosticSet, highlight_map::{HighlightId, HighlightMap}, @@ -47,14 +46,14 @@ pub use {tree_sitter_rust, tree_sitter_typescript}; pub use lsp::DiagnosticSeverity; struct GitDiffStatus { - diff: git::BufferDiff, + diff: git::diff::BufferDiff, update_in_progress: bool, update_requested: bool, } pub struct Buffer { text: TextBuffer, - head_text: Option>, + head_text: Option, git_diff_status: GitDiffStatus, file: Option>, saved_version: clock::Global, @@ -83,7 +82,7 @@ pub struct Buffer { pub struct BufferSnapshot { text: text::BufferSnapshot, - pub git_diff: git::BufferDiff, + pub git_diff: git::diff::BufferDiff, pub(crate) syntax: SyntaxSnapshot, file: Option>, diagnostics: DiagnosticSet, @@ -353,7 +352,7 @@ impl Buffer { ) -> Self { Self::build( TextBuffer::new(replica_id, cx.model_id() as u64, base_text.into()), - head_text.map(|h| Arc::new(h.into())), + head_text.map(|h| h.into().into_boxed_str().into()), Some(file), ) } @@ -364,7 +363,11 @@ impl Buffer { file: Option>, ) -> Result { let buffer = TextBuffer::new(replica_id, message.id, message.base_text); - let mut this = Self::build(buffer, message.head_text.map(|text| Arc::new(text)), file); + let mut this = Self::build( + buffer, + message.head_text.map(|text| text.into_boxed_str().into()), + file, + ); this.text.set_line_ending(proto::deserialize_line_ending( proto::LineEnding::from_i32(message.line_ending) .ok_or_else(|| anyhow!("missing line_ending"))?, @@ -420,11 +423,7 @@ impl Buffer { self } - fn build( - buffer: TextBuffer, - head_text: Option>, - file: Option>, - ) -> Self { + fn build(buffer: TextBuffer, head_text: Option, file: Option>) -> Self { let saved_mtime = if let Some(file) = file.as_ref() { file.mtime() } else { @@ -440,7 +439,7 @@ impl Buffer { text: buffer, head_text, git_diff_status: GitDiffStatus { - diff: git::BufferDiff::new(), + diff: git::diff::BufferDiff::new(), update_in_progress: false, update_requested: false, }, @@ -613,7 +612,7 @@ impl Buffer { cx, ); } - self.update_git(cx); + self.git_diff_recalc(cx); cx.emit(Event::Reloaded); cx.notify(); } @@ -663,9 +662,8 @@ impl Buffer { task } - pub fn update_git(&mut self, cx: &mut ModelContext) { - //Grab head text - + pub fn update_head_text(&mut self, head_text: Option, cx: &mut ModelContext) { + self.head_text = head_text; self.git_diff_recalc(cx); } @@ -674,6 +672,7 @@ impl Buffer { } pub fn git_diff_recalc(&mut self, cx: &mut ModelContext) { + println!("recalc"); if self.git_diff_status.update_in_progress { self.git_diff_status.update_requested = true; return; @@ -2221,7 +2220,7 @@ impl BufferSnapshot { pub fn git_diff_hunks_in_range<'a>( &'a self, query_row_range: Range, - ) -> impl 'a + Iterator> { + ) -> impl 'a + Iterator> { self.git_diff.hunks_in_range(query_row_range, self) } diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 8e2fe601e7..780f6e75b5 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -1,6 +1,5 @@ mod buffer; mod diagnostic_set; -pub mod git; mod highlight_map; mod outline; pub mod proto; diff --git a/crates/project/Cargo.toml b/crates/project/Cargo.toml index 8ca01eac2c..1e45e3c6ed 100644 --- a/crates/project/Cargo.toml +++ b/crates/project/Cargo.toml @@ -24,6 +24,7 @@ collections = { path = "../collections" } db = { path = "../db" } fsevent = { path = "../fsevent" } fuzzy = { path = "../fuzzy" } +git = { path = "../git" } gpui = { path = "../gpui" } language = { path = "../language" } lsp = { path = "../lsp" } @@ -52,8 +53,6 @@ smol = "1.2.5" thiserror = "1.0.29" toml = "0.5" rocksdb = "0.18" -git2 = { version = "0.15", default-features = false } - [dev-dependencies] client = { path = "../client", features = ["test-support"] } diff --git a/crates/project/src/fs.rs b/crates/project/src/fs.rs index 8542030cb7..6a496910a0 100644 --- a/crates/project/src/fs.rs +++ b/crates/project/src/fs.rs @@ -1,11 +1,9 @@ use anyhow::{anyhow, Result}; use fsevent::EventStream; use futures::{future::BoxFuture, Stream, StreamExt}; -use language::git::libgit::{Repository, RepositoryOpenFlags}; use language::LineEnding; use smol::io::{AsyncReadExt, AsyncWriteExt}; use std::{ - ffi::OsStr, io, os::unix::fs::MetadataExt, path::{Component, Path, PathBuf}, @@ -22,8 +20,6 @@ use futures::lock::Mutex; #[cfg(any(test, feature = "test-support"))] use std::sync::{Arc, Weak}; -use crate::git_repository::GitRepository; - #[async_trait::async_trait] pub trait Fs: Send + Sync { async fn create_dir(&self, path: &Path) -> Result<()>; diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 4aa3a89d86..57af588c68 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1,5 +1,4 @@ pub mod fs; -mod git_repository; mod ignore; mod lsp_command; pub mod search; @@ -13,7 +12,7 @@ use client::{proto, Client, PeerId, TypedEnvelope, User, UserStore}; use clock::ReplicaId; use collections::{hash_map, BTreeMap, HashMap, HashSet}; use futures::{future::Shared, AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt}; -use git_repository::GitRepository; +use git::repository::GitRepository; use gpui::{ AnyModelHandle, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task, UpgradeModelHandle, WeakModelHandle, @@ -4538,6 +4537,7 @@ impl Project { cx.subscribe(worktree, |this, worktree, event, cx| match event { worktree::Event::UpdatedEntries => this.update_local_worktree_buffers(worktree, cx), worktree::Event::UpdatedGitRepositories(updated_repos) => { + println!("{updated_repos:#?}"); this.update_local_worktree_buffers_git_repos(updated_repos, cx) } }) @@ -4649,24 +4649,35 @@ impl Project { fn update_local_worktree_buffers_git_repos( &mut self, - updated_repos: &[GitRepository], + repos: &[GitRepository], cx: &mut ModelContext, ) { - for (buffer_id, buffer) in &self.opened_buffers { - if let Some(buffer) = buffer.upgrade(cx) { - buffer.update(cx, |buffer, cx| { - let updated = updated_repos.iter().any(|repo| { - buffer - .file() - .and_then(|file| file.as_local()) - .map(|file| repo.manages(&file.abs_path(cx))) - .unwrap_or(false) - }); + //TODO: Produce protos - if updated { - buffer.update_git(cx); - } - }); + for (_, buffer) in &self.opened_buffers { + if let Some(buffer) = buffer.upgrade(cx) { + let file = match buffer.read(cx).file().and_then(|file| file.as_local()) { + Some(file) => file, + None => return, + }; + let path = file.path().clone(); + let abs_path = file.abs_path(cx); + println!("got file"); + + let repo = match repos.iter().find(|repo| repo.manages(&abs_path)) { + Some(repo) => repo.clone(), + None => return, + }; + println!("got repo"); + + cx.spawn(|_, mut cx| async move { + let head_text = repo.load_head_text(&path).await; + buffer.update(&mut cx, |buffer, cx| { + println!("got calling update"); + buffer.update_head_text(head_text, cx); + }); + }) + .detach(); } } } diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 4885ce104a..7fd37dc016 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -1,10 +1,9 @@ -use crate::{copy_recursive, git_repository::GitRepository, ProjectEntryId, RemoveOptions}; - use super::{ fs::{self, Fs}, ignore::IgnoreStack, DiagnosticSummary, }; +use crate::{copy_recursive, ProjectEntryId, RemoveOptions}; use ::ignore::gitignore::{Gitignore, GitignoreBuilder}; use anyhow::{anyhow, Context, Result}; use client::{proto, Client}; @@ -18,6 +17,8 @@ use futures::{ Stream, StreamExt, }; use fuzzy::CharBag; +use git::repository::GitRepository; +use git::{DOT_GIT, GITIGNORE}; use gpui::{ executor, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task, @@ -48,7 +49,7 @@ use std::{ time::{Duration, SystemTime}, }; use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap, TreeSet}; -use util::{ResultExt, TryFutureExt, DOT_GIT, GITIGNORE}; +use util::{ResultExt, TryFutureExt}; #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)] pub struct WorktreeId(usize); @@ -523,7 +524,10 @@ impl LocalWorktree { match self.scan_state() { ScanState::Idle => { let new_snapshot = self.background_snapshot.lock().clone(); - let updated_repos = self.list_updated_repos(&new_snapshot); + let updated_repos = Self::list_updated_repos( + &self.snapshot.git_repositories, + &new_snapshot.git_repositories, + ); self.snapshot = new_snapshot; if let Some(share) = self.share.as_mut() { @@ -541,7 +545,10 @@ impl LocalWorktree { let is_fake_fs = self.fs.is_fake(); let new_snapshot = self.background_snapshot.lock().clone(); - let updated_repos = self.list_updated_repos(&new_snapshot); + let updated_repos = Self::list_updated_repos( + &self.snapshot.git_repositories, + &new_snapshot.git_repositories, + ); self.snapshot = new_snapshot; self.poll_task = Some(cx.spawn_weak(|this, mut cx| async move { @@ -573,16 +580,20 @@ impl LocalWorktree { cx.notify(); } - fn list_updated_repos(&self, new_snapshot: &LocalSnapshot) -> Vec { - let old_snapshot = &self.snapshot; + fn list_updated_repos( + old_repos: &[GitRepository], + new_repos: &[GitRepository], + ) -> Vec { + println!("old repos: {:#?}", old_repos); + println!("new repos: {:#?}", new_repos); fn diff<'a>( - a: &'a LocalSnapshot, - b: &'a LocalSnapshot, + a: &'a [GitRepository], + b: &'a [GitRepository], updated: &mut HashMap<&'a Path, GitRepository>, ) { - for a_repo in &a.git_repositories { - let matched = b.git_repositories.iter().find(|b_repo| { + for a_repo in a { + let matched = b.iter().find(|b_repo| { a_repo.git_dir_path() == b_repo.git_dir_path() && a_repo.scan_id() == b_repo.scan_id() }); @@ -595,10 +606,10 @@ impl LocalWorktree { let mut updated = HashMap::<&Path, GitRepository>::default(); - diff(old_snapshot, new_snapshot, &mut updated); - diff(new_snapshot, old_snapshot, &mut updated); + diff(old_repos, new_repos, &mut updated); + diff(new_repos, old_repos, &mut updated); - updated.into_values().collect() + dbg!(updated.into_values().collect()) } pub fn scan_complete(&self) -> impl Future { @@ -653,7 +664,7 @@ impl LocalWorktree { settings::GitFilesIncluded::All | settings::GitFilesIncluded::OnlyTracked ) { let results = if let Some(repo) = snapshot.repo_for(&abs_path) { - repo.load_head_text(&abs_path).await + repo.load_head_text(&path).await } else { None }; @@ -1362,6 +1373,7 @@ impl LocalSnapshot { } pub(crate) fn in_dot_git(&mut self, path: &Path) -> Option<&mut GitRepository> { + println!("chechking {path:?}"); self.git_repositories .iter_mut() .rev() //git_repository is ordered lexicographically @@ -1510,7 +1522,6 @@ impl LocalSnapshot { parent_path: Arc, entries: impl IntoIterator, ignore: Option>, - fs: &dyn Fs, ) { let mut parent_entry = if let Some(parent_entry) = self.entries_by_path.get(&PathKey(parent_path.clone()), &()) @@ -2391,12 +2402,9 @@ impl BackgroundScanner { new_entries.push(child_entry); } - self.snapshot.lock().populate_dir( - job.path.clone(), - new_entries, - new_ignore, - self.fs.as_ref(), - ); + self.snapshot + .lock() + .populate_dir(job.path.clone(), new_entries, new_ignore); for new_job in new_jobs { job.scan_queue.send(new_job).await.unwrap(); } @@ -2595,7 +2603,7 @@ impl BackgroundScanner { .git_repositories .iter() .cloned() - .filter(|repo| git2::Repository::open(repo.git_dir_path()).is_ok()) + .filter(|repo| git::libgit::Repository::open(repo.git_dir_path()).is_ok()) .collect(); snapshot.git_repositories = new_repos; diff --git a/crates/util/src/lib.rs b/crates/util/src/lib.rs index 52bf70e3a7..97f409f410 100644 --- a/crates/util/src/lib.rs +++ b/crates/util/src/lib.rs @@ -2,20 +2,13 @@ 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, diff --git a/crates/util/src/test.rs b/crates/util/src/test.rs index 4e4716434e..96d13f4c81 100644 --- a/crates/util/src/test.rs +++ b/crates/util/src/test.rs @@ -2,14 +2,15 @@ mod assertions; mod marked_text; use git2; -use std::path::{Path, PathBuf}; +use std::{ + ffi::OsStr, + 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); @@ -28,7 +29,7 @@ fn write_tree(path: &Path, tree: serde_json::Value) { Value::Object(_) => { fs::create_dir(&path).unwrap(); - if path.file_name() == Some(&DOT_GIT) { + if path.file_name() == Some(&OsStr::new(".git")) { git2::Repository::init(&path.parent().unwrap()).unwrap(); }