Quick answer: Project Settings → Editor → Asset Serialization Mode = Force Text. Configure Unity SmartMerge as the merge driver for *.prefab and *.unity files in ~/.gitconfig. Don’t rename children that hold overrides — renames break the file ID linkage.
Designer adds an override on a variant. Programmer adds an override on the same variant. Merge resolves cleanly — the diff looks fine. Variant opens with one designer’s override missing. Unity prefabs aren’t plain text and naive merges silently lose data.
The Symptom
Variant overrides (modified field values, added components, removed components) are missing after a merge. Diff shows clean conflict resolution, no warnings. Apply All to base does nothing; the override simply isn’t there anymore.
What Causes This
Prefab variants store overrides as YAML records that reference the source prefab’s GameObjects/components by file ID. Two parallel branches each adding a record produces two new records that are textually adjacent; a line-based merge tool may keep only one set. SmartMerge knows the structure and merges record-by-record.
The Fix
Step 1: Force text serialization. Project Settings → Editor → Asset Serialization Mode → Force Text. Commit the ProjectSettings/EditorSettings.asset change.
Step 2: Configure SmartMerge globally. Locate Unity’s smart merge tool. On Mac:
/Applications/Unity/Hub/Editor/<version>/Unity.app/Contents/Tools/UnityYAMLMerge
# Add to ~/.gitconfig
[merge "unityyamlmerge"]
name = Unity SmartMerge
driver = "/Applications/Unity/Hub/Editor/<version>/Unity.app/Contents/Tools/UnityYAMLMerge merge -p %O %B %A %A"
recursive = binary
Step 3: Per-repo .gitattributes.
# .gitattributes
*.prefab merge=unityyamlmerge eol=lf
*.unity merge=unityyamlmerge eol=lf
*.asset merge=unityyamlmerge eol=lf
*.mat merge=unityyamlmerge eol=lf
Now git merge on these file types invokes SmartMerge instead of the default merge driver.
Avoid Override Breakers
Some changes break the file ID linkage and lose overrides regardless of tool:
- Renaming or moving a child GameObject in the source prefab.
- Removing a component on the source that the variant was overriding.
- Re-saving with a different Unity version that re-IDs the YAML.
For high-traffic prefabs, designate one owner (or use a coordination channel) so renames don’t happen across an active branch.
Recovering Lost Overrides
If a merge already lost overrides:
git log --follow path/to/Variant.prefabto see history.git show <commit>:path/to/Variant.prefab > backup.prefabfor a known-good revision.- Open both in Unity and use Overrides → Apply Selected to manually re-apply lost values.
Verifying
Open the variant after merge. Inspector overrides should appear in bold (the standard override styling). If a previously-overridden field shows the source value un-bolded, the override was dropped — revisit the merge.
“Force Text. SmartMerge driver. .gitattributes. Don’t rename children mid-branch. Overrides survive.”
Related Issues
For prefab apply not saving, see prefab apply. For asmdef circular refs, see asmdef circular.
SmartMerge. Force Text. .gitattributes. Overrides hold.