diff --git a/plugin/src/PatchTree.spec.lua b/plugin/src/PatchTree.spec.lua index 0fdeaddc..fe3db772 100644 --- a/plugin/src/PatchTree.spec.lua +++ b/plugin/src/PatchTree.spec.lua @@ -755,7 +755,7 @@ return function() table.insert(patch.updated, { id = id1, changedName = nil, - changedProperties = { Source = "-- changed" }, + changedProperties = { Source = { String = "-- changed" } }, }) local gitMetadata = { @@ -862,7 +862,7 @@ return function() table.insert(patch.updated, { id = childId, - changedProperties = { Source = "return {}" }, + changedProperties = { Source = { String = "return {}" } }, }) local tree = PatchTree.build(patch, instanceMap, { "Property", "Current", "Incoming" }) @@ -898,6 +898,9 @@ return function() -- Use a service-level instance (direct child of DataModel) local repStorage = game:GetService("ReplicatedStorage") + local repStorageId = HttpService:GenerateGUID(false) + instanceMap:insert(repStorageId, repStorage) + local testObj = Instance.new("Folder") testObj.Name = "TopLevel" testObj.Parent = repStorage diff --git a/src/git.rs b/src/git.rs index a3280ce8..b9348a2a 100644 --- a/src/git.rs +++ b/src/git.rs @@ -190,17 +190,14 @@ fn collect_tree_index_changes( Err(_) => return, }; + let mut tree_entries: HashMap = HashMap::new(); + flatten_tree(repo, &tree, "", &mut tree_entries); + for entry in index.entries() { let path_bstr = entry.path(index); let path_str = path_bstr.to_str_lossy(); - let tree_entry_id = tree - .lookup_entry_by_path(path_str.as_ref()) - .ok() - .flatten() - .map(|e| e.object_id()); - - match tree_entry_id { + match tree_entries.remove(path_str.as_ref()) { Some(tid) if tid == entry.id => {} _ => { tracked.insert(PathBuf::from(path_str.as_ref())); @@ -208,15 +205,16 @@ fn collect_tree_index_changes( } } - collect_tree_only_paths(repo, &tree, "", index, tracked); + for path in tree_entries.into_keys() { + tracked.insert(PathBuf::from(path)); + } } -fn collect_tree_only_paths( +fn flatten_tree( repo: &gix::Repository, tree: &gix::Tree<'_>, prefix: &str, - index: &gix::index::File, - tracked: &mut HashSet, + out: &mut HashMap, ) { for entry in tree.iter() { let entry = match entry { @@ -233,14 +231,11 @@ fn collect_tree_only_paths( if entry.mode().is_tree() { if let Ok(sub_obj) = entry.id().object() { if let Ok(sub_tree) = sub_obj.peel_to_tree() { - collect_tree_only_paths(repo, &sub_tree, &full_path, index, tracked); + flatten_tree(repo, &sub_tree, &full_path, out); } } } else if entry.mode().is_blob() || entry.mode().is_executable() { - let path_as_bstr: &gix::bstr::BStr = full_path.as_bytes().as_bstr(); - if index.entry_by_path(path_as_bstr).is_none() { - tracked.insert(PathBuf::from(&full_path)); - } + out.insert(full_path, entry.id().detach()); } } } diff --git a/src/web/api.rs b/src/web/api.rs index 67a1e5e4..df9714a6 100644 --- a/src/web/api.rs +++ b/src/web/api.rs @@ -7,6 +7,7 @@ use std::{ path::{Path, PathBuf}, str::FromStr, sync::{Arc, Mutex}, + time::Instant, }; use bytes::Bytes; @@ -392,6 +393,8 @@ impl ApiService { /// Get a summary of information about the server async fn handle_api_rojo(&self) -> Response> { + let handler_start = Instant::now(); + let root_instance_id = self.serve_session.tree().get_root_id(); let ignore_hidden_services = self.serve_session.ignore_hidden_services(); @@ -408,15 +411,26 @@ impl ApiService { .serve_session .initial_head_commit() .map(|s| s.to_owned()); - tokio::task::spawn_blocking(move || { + let t = Instant::now(); + let result = tokio::task::spawn_blocking(move || { crate::git::compute_git_metadata(&tree_handle, &repo_root, initial_head.as_deref()) }) .await - .ok() + .ok(); + log::trace!( + "[TIMING] handle_api_rojo: compute_git_metadata {}ms", + t.elapsed().as_millis() + ); + result } else { None }; + log::trace!( + "[TIMING] handle_api_rojo: total {}ms", + handler_start.elapsed().as_millis() + ); + msgpack_ok(&ServerInfoResponse { server_version: SERVER_VERSION.to_owned(), protocol_version: PROTOCOL_VERSION,