forked from rojo-rbx/rojo
Merge branch 'fix/git-since-live-sync'
This commit is contained in:
@@ -41,14 +41,41 @@ function reifyInstanceInner(unappliedPatch, deferredRefs, instanceMap, virtualIn
|
||||
invariant("Cannot reify an instance not present in virtualInstances\nID: {}", id)
|
||||
end
|
||||
|
||||
-- Instance.new can fail if we're passing in something that can't be
|
||||
-- created, like a service, something enabled with a feature flag, or
|
||||
-- something that requires higher security than we have.
|
||||
local createSuccess, instance = pcall(Instance.new, virtualInstance.ClassName)
|
||||
-- Before creating a new instance, check if the parent already has an
|
||||
-- untracked child with the same Name and ClassName. This enables "late
|
||||
-- adoption" of instances that exist in Studio but weren't in the initial
|
||||
-- Rojo tree (e.g., when using --git-since filtering). Without this,
|
||||
-- newly acknowledged files would create duplicate instances.
|
||||
local adoptedExisting = false
|
||||
local instance = nil
|
||||
|
||||
if not createSuccess then
|
||||
addAllToPatch(unappliedPatch, virtualInstances, id)
|
||||
return
|
||||
for _, child in ipairs(parentInstance:GetChildren()) do
|
||||
local accessSuccess, name, className = pcall(function()
|
||||
return child.Name, child.ClassName
|
||||
end)
|
||||
|
||||
if accessSuccess
|
||||
and name == virtualInstance.Name
|
||||
and className == virtualInstance.ClassName
|
||||
and instanceMap.fromInstances[child] == nil
|
||||
then
|
||||
instance = child
|
||||
adoptedExisting = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not adoptedExisting then
|
||||
-- Instance.new can fail if we're passing in something that can't be
|
||||
-- created, like a service, something enabled with a feature flag, or
|
||||
-- something that requires higher security than we have.
|
||||
local createSuccess
|
||||
createSuccess, instance = pcall(Instance.new, virtualInstance.ClassName)
|
||||
|
||||
if not createSuccess then
|
||||
addAllToPatch(unappliedPatch, virtualInstances, id)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: Can this fail? Previous versions of Rojo guarded against this, but
|
||||
@@ -96,7 +123,9 @@ function reifyInstanceInner(unappliedPatch, deferredRefs, instanceMap, virtualIn
|
||||
reifyInstanceInner(unappliedPatch, deferredRefs, instanceMap, virtualInstances, childId, instance)
|
||||
end
|
||||
|
||||
instance.Parent = parentInstance
|
||||
if not adoptedExisting then
|
||||
instance.Parent = parentInstance
|
||||
end
|
||||
instanceMap:insert(id, instance)
|
||||
end
|
||||
|
||||
|
||||
@@ -83,6 +83,19 @@ pub fn snapshot_project(
|
||||
// file being updated.
|
||||
snapshot.metadata.relevant_paths.push(path.to_path_buf());
|
||||
|
||||
// When git filter is active, also register the project folder as a
|
||||
// relevant path. This serves as a catch-all so that file changes
|
||||
// not under any specific $path node can still walk up the directory
|
||||
// tree and trigger a re-snapshot of the entire project.
|
||||
if context.has_git_filter() {
|
||||
if let Some(folder) = path.parent() {
|
||||
let normalized = vfs
|
||||
.canonicalize(folder)
|
||||
.unwrap_or_else(|_| folder.to_path_buf());
|
||||
snapshot.metadata.relevant_paths.push(normalized);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Some(snapshot))
|
||||
}
|
||||
None => Ok(None),
|
||||
@@ -137,6 +150,26 @@ pub fn snapshot_project_node(
|
||||
// Take the snapshot's metadata as-is, which will be mutated later
|
||||
// on.
|
||||
metadata = snapshot.metadata;
|
||||
} else if context.has_git_filter() {
|
||||
// When the git filter is active and the $path was filtered out
|
||||
// (no acknowledged files yet), we still need to register the path
|
||||
// in relevant_paths. This allows the change processor to map file
|
||||
// changes in this directory back to this project node instance,
|
||||
// triggering a re-snapshot that will pick up newly modified files.
|
||||
let normalized = vfs
|
||||
.canonicalize(full_path.as_ref())
|
||||
.unwrap_or_else(|_| full_path.to_path_buf());
|
||||
metadata.relevant_paths.push(normalized);
|
||||
|
||||
// The VFS only sets up file watches via read() and read_dir(),
|
||||
// not via metadata(). Since the git filter caused snapshot_from_vfs
|
||||
// to return early (before read_dir was called), the VFS is not
|
||||
// watching this path. We must read the directory here to ensure
|
||||
// the VFS sets up a recursive watch, otherwise file change events
|
||||
// will never fire and live sync won't detect modifications.
|
||||
if full_path.is_dir() {
|
||||
let _ = vfs.read_dir(&full_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user