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)
|
invariant("Cannot reify an instance not present in virtualInstances\nID: {}", id)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Instance.new can fail if we're passing in something that can't be
|
-- Before creating a new instance, check if the parent already has an
|
||||||
-- created, like a service, something enabled with a feature flag, or
|
-- untracked child with the same Name and ClassName. This enables "late
|
||||||
-- something that requires higher security than we have.
|
-- adoption" of instances that exist in Studio but weren't in the initial
|
||||||
local createSuccess, instance = pcall(Instance.new, virtualInstance.ClassName)
|
-- 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
|
for _, child in ipairs(parentInstance:GetChildren()) do
|
||||||
addAllToPatch(unappliedPatch, virtualInstances, id)
|
local accessSuccess, name, className = pcall(function()
|
||||||
return
|
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
|
end
|
||||||
|
|
||||||
-- TODO: Can this fail? Previous versions of Rojo guarded against this, but
|
-- 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)
|
reifyInstanceInner(unappliedPatch, deferredRefs, instanceMap, virtualInstances, childId, instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
instance.Parent = parentInstance
|
if not adoptedExisting then
|
||||||
|
instance.Parent = parentInstance
|
||||||
|
end
|
||||||
instanceMap:insert(id, instance)
|
instanceMap:insert(id, instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,19 @@ pub fn snapshot_project(
|
|||||||
// file being updated.
|
// file being updated.
|
||||||
snapshot.metadata.relevant_paths.push(path.to_path_buf());
|
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))
|
Ok(Some(snapshot))
|
||||||
}
|
}
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
@@ -137,6 +150,26 @@ pub fn snapshot_project_node(
|
|||||||
// Take the snapshot's metadata as-is, which will be mutated later
|
// Take the snapshot's metadata as-is, which will be mutated later
|
||||||
// on.
|
// on.
|
||||||
metadata = snapshot.metadata;
|
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