GregOrigin - SyncShield: Dynamic Safety Net, Sentinel & Validator for Git & Plastic SCM

Watch it in action.

Read the manual.

A functional OSS version is available on GitHub: https://github.com/gregorik/SyncShield-Core, please file Issues if appropriate. Fab hosts the fully featured & supported Pro version.

SyncShield is a lightweight, battle-tested UE5 plugin designed to eliminate source control friction and protect your team from lost work and locked-file conflicts. It natively integrates with Unreal's Editor to warn you before you make changes, and safely catches you if you try to overwrite someone else's work. This is a major upgrade and more ambitious refactoring of the earlier SafeSave plugin which remains fully functional in its own narrower scope.

Core Features:

🚫 Strict File Locking Protection

SyncShield natively intercepts your "Save All" commands. Before any data is written, it rapidly probes your source control provider (Git, Plastic SCM, Perforce) for checkout status. If any package is locked by a teammate (IsCheckedOutOther), SyncShield blocks the save for those specific files with an explicit warning, while automatically issuing checkouts and safely saving the rest.

πŸ”” Preemptive "Dropbox-Style" Alerts

Don't wait until you save to find out a file is locked. SyncShield hooks directly into the Unreal Asset Editor. The moment you open a Blueprint, Material, or Data Asset that is locked by another developer, you instantly get a prominent Toast Notification warning you not to edit it.

πŸ› οΈ Streamlined Editor Toolbar

Stop fumbling with external CLI windows or hidden context menus. SyncShield adds a dedicated, dynamic status widget right to the Level Editor Toolbar.

*Live Status Updates: See your Branch, pending changes, and unsaved asset counts at a glance.

*One-Click Actions: Save All, Submit Content, or Refresh Status.

*Native Git Integration: Auto-Fetch (configurable interval), Pull (Rebase), and Push directly from the toolbar.

*Native Plastic SCM Integration: One-click Workspace Update.

βš”οΈ Conflict Sentinel: Stop merge conflicts before they happen. SyncShield quietly tracks your locally dirty assets and runs background checks against your remote Git branch. If a teammate pushes a change to a file you are currently editing, you get an instant toast warning you of the impending collision.

🌿 Safe Branch Shifter: Switch Git branches without playing Russian Roulette with the Unreal Editor. SyncShield's "Safe Switch" pipeline protects your unsaved data, forcefully closes vulnerable asset editors, performs a clean checkout, and lets the Asset Registry hot-reload safely without crashing.

βͺ Local Save History & Time Travel: SyncShield quietly takes lightweight, localized snapshots of your assets every time you save. Broke a Blueprint? Click "Restore Latest Snapshot" to instantly revert the active asset to its last known good stateβ€”without needing to pull from remote source control.

πŸ›‘ Pre-Save Data Validation: Automatically run custom or engine-level validation checks before assets are committed to disk. Prevent broken references, bad naming conventions, or uncompiled Blueprints from ever reaching your repository.

πŸ“‚ Advanced Save Profiles: Stop saving everything just to be safe. Use precision save commands:

Save Blueprints Only

Save Current Level Only

Save Recently Touched (Time-windowed)

0.6 update added:

Added

Services Architecture

  • Added Local Save History Service (FSyncShieldHistoryService): automatic pre-save snapshots captured to a per-project history directory. Snapshots are deduplicated by SHA-256 hash so only genuine content changes are stored. Configurable via Max Snapshots Per Asset (default 10); excess snapshots are pruned oldest-first.
  • Added Pre-Save Validation Service (FSyncShieldValidationService): runs on every save and validates asset naming against a configurable regex pattern (AssetNamingPattern, default ^[A-Z][A-Za-z0-9_]*$), checks texture dimensions against Max Recommended Texture Dimension (default 8192), and optionally runs the engine's UObject::IsDataValid(). Issues are surfaced as editor message log entries. When Block SyncShield Save Actions On Errors is enabled, SyncShield's own save profiles refuse to save packages with blocking validation errors.
  • Added Save Profile Service (FSyncShieldSaveProfileService): provides four scoped save profiles β€” Save All, Save Blueprints, Save Current Level, and Save Recently Touched β€” each of which runs pre-save validation before writing. The "Recently Touched" profile uses a configurable time window (RecentlyTouchedSaveWindowMinutes, default 15) to save only packages the user has recently modified.
  • Added Restore Latest Snapshot: toolbar menu action to revert a dirty package to its most recent local history snapshot, with confirmation dialog and success/failure toast.

Git LFS Lock Management

  • Added Auto-unlock after Push: after a successful git push, SyncShield automatically queries git lfs locks --local and releases all locally-held file locks.
  • Added Auto-unlock after Submit Content: the "Submit Content" check-in action now releases LFS locks after a successful commit.
  • Added Unlock LFS Files menu action: manually release all locally-held Git LFS file locks via a toolbar dropdown entry, with a confirmation dialog listing locked files.
  • Added lockable attribute to .gitattributes for *.uasset and *.umap, enabling the full Git LFS lock/unlock workflow where tracked files are read-only until explicitly locked.

Conflict Sentinel and Branch Shifter

  • Added Conflict Sentinel: detects files that are modified locally but also changed on the remote, raising preemptive conflict warnings before a pull.
  • Added Safe Branch Shifter: a toolbar submenu that lists local and remote branches, stashes unsaved work, switches branches, and pops the stash on arrival. Includes guardrails for dirty working trees and diverged states.

Editor Automation Showcase Commands

  • Added SyncShield.Demo.ShowcaseConflictSentinel console command: creates a synthetic conflicting state and demonstrates the Conflict Sentinel alert.
  • Added SyncShield.Demo.ShowcaseBranchShifter console command: creates temporary branches and walks through a Safe Branch Shift cycle.
  • Added SyncShield.Demo.ShowcaseAllCommands console command: sequentially runs all showcase demonstrations.

Toolbar Enhancements

  • Added Quick Commit action: stage all changes and commit from a single dialog. Warning text now clearly states "This will stage ALL changes (including untracked files) and commit."
  • Added Git Stash and Git Stash Pop actions.
  • Added Git Merge Abort and Git Rebase Abort conflict resolution actions.
  • Added Save Blueprints, Save Current Level, and Save Recently Touched as separate save profile menu entries.
  • Added Validate Dirty Assets menu action to manually trigger pre-save validation on all currently dirty packages.
  • Added LFS lock count (Locked N) and locked-file list in toolbar tooltip when Git LFS locks are detected.
  • Added bGitattributesConfigured status field tracking whether the repository .gitattributes has the lockable attribute.

Settings

  • Added bEnableLocalSaveHistory (default true) β€” master toggle for the local save history service.
  • Added MaxLocalHistorySnapshotsPerAsset (default 10) β€” cap on retained snapshots per asset.
  • Added bEnablePreSaveValidation (default true) β€” master toggle for the pre-save validation service.
  • Added bRunObjectDataValidation (default false) β€” opt-in to run UObject::IsDataValid() during validation.
  • Added bBlockSyncShieldActionsOnValidationErrors (default true) β€” prevent SyncShield save profiles from writing packages that have blocking validation errors.
  • Added AssetNamingPattern (default ^[A-Z][A-Za-z0-9_]*$) β€” regex pattern for asset name validation.
  • Added MaxRecommendedTextureDimension (default 8192) β€” texture size warning threshold.
  • Added RecentlyTouchedSaveWindowMinutes (default 15) β€” time window for the "Recently Touched" save profile.

Automation Tests

  • Added SyncShield.Editor.Services.ValidationNamingPattern β€” tests default naming regex against valid/invalid names and custom patterns.
  • Added SyncShield.Editor.Services.ValidationSettings β€” verifies all default setting values match expected defaults.
  • Added SyncShield.Editor.Services.HistoryPrune β€” creates 25 fake snapshots, prunes to MaxSnapshots, verifies newest survive.
  • Added SyncShield.Editor.Services.RecentlyTouchedWindow β€” tests the recently-touched time-window comparison logic.
  • Added SyncShield.Editor.Services.LfsUnlockGating β€” tests LFS tooltip display with/without locks and LFS detection.
  • Full suite now at 12 tests, all passing on UE 5.7 and UE 5.6.

Changed

  • Reworked ExecuteGitPush() from a one-liner RunGitCommandAsync("push") to a multi-step async flow that checks for LFS locks before push and auto-unlocks after success.
  • Reworked ExecuteCheckIn() to release LFS locks after a successful source control check-in when locks were held beforehand.
  • Separated stdout/stderr handling in RunCommandWithTimeout(): stderr is now only populated when the exit code is non-zero, matching FMonitoredProcess behavior where stdout and stderr are merged.
  • Updated .uplugin description to be more descriptive for Fab listing.
  • Updated .uplugin URLs to use bare domain format (www.gregorigin.com) for Fab compatibility.
  • Updated FilterPlugin.ini with detailed documentation comments explaining each included path and why Binaries/ and Intermediate/ are excluded.

Fixed

  • Fixed persistent LFS lock icons: locks acquired during SyncShield's save workflow are now released after push and check-in rather than persisting indefinitely.
  • Fixed the "Check Out Assets" dialog appearing with a greyed-out "Check Out Selected" button when using Git without LFS locking. SyncShield now detects when the source control provider does not support checkout, clears the read-only flag on affected files, and bypasses the checkout prompt entirely.