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:

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:

  1. git log --follow path/to/Variant.prefab to see history.
  2. git show <commit>:path/to/Variant.prefab > backup.prefab for a known-good revision.
  3. 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.