The previous fix used split('.').next() to get the meta stem from the
snapshot path, which only takes the first dot-segment. This broke names
containing dots (e.g. "Name.new" → "Name.new.luau" would produce
"Name.meta.json" instead of "Name.new.meta.json").
Strip the full middleware extension (e.g. ".server.luau", ".txt") from
the snapshot path filename instead. This correctly handles all cases:
Name.new.luau → Name.new → Name.new.meta.json
_Init.server.luau → _Init → _Init.meta.json
Name.new.txt → Name.new → Name.new.meta.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a script/txt/csv child is renamed by name_for_inst (e.g. "Init" →
"_Init.luau"), the adjacent meta file must follow the same name. All
three callers were using the Roblox instance name to construct the meta
path, producing "Init.meta.json" instead of "_Init.meta.json" — which
collides with the parent directory's "init.meta.json" on
case-insensitive file systems.
Fix by deriving the meta stem from the first dot-segment of the
snapshot path file name, which already holds the resolved name.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a child instance has a Roblox name that would produce a filesystem
name of "init" (case-insensitive), syncback now automatically prefixes
it with '_' (e.g. "Init" → "_Init.luau") instead of erroring. The
corresponding meta.json writes the original name via the `name` property
so Rojo can restore it on the next snapshot.
The sibling dedup check is updated to use actual on-disk names for
existing children and the resolved (init-prefixed) name for new ones,
so genuine collisions still error while false positives from the `name`
property are avoided.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The VFS only sets up file watches via read() and read_dir(), not
metadata(). When git filtering caused snapshot_from_vfs to return
early for $path directories, read_dir was never called, so no file
watch was established. This meant file modifications never generated
VFS events and were silently ignored until the server was restarted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a CLI flag that forces syncback to use JSON representations
instead of binary .rbxm files. Instances with children become
directories with init.meta.json; leaf instances become .model.json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two issues prevented --git-since from working correctly during live sync:
1. Server: File changes weren't detected because git-filtered project nodes
had empty relevant_paths, so the change processor couldn't map VFS events
back to tree instances. Fixed by registering $path directories and the
project folder in relevant_paths even when filtered.
2. Plugin: When a previously-filtered file was first acknowledged, it appeared
as an ADD patch. The plugin created a new instance instead of adopting the
existing one in Studio, causing duplicates. Fixed by checking for untracked
children with matching Name+ClassName before calling Instance.new.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add new GitFilter struct for tracking files changed since a Git reference
- Only sync changed (added/deleted/modified) files to Roblox Studio
- Files remain acknowledged once synced, even if content is reverted
- Add enhanced logging for debugging sync issues
- Force acknowledge project structure to prevent 'Cannot sync a model as a place' errors