Resolving Unity scene merge conflicts in Git
Two people edited the same scene. Git cannot merge it, and the conflict markers are sitting in four thousand lines of YAML. This is the order of operations that gets you out — and the checks that catch the merges which succeed on paper and fail in the Editor.
To resolve a Unity scene merge conflict in Git: keep Git's conflict state, run
UnityYAMLMerge through git mergetool, review the
remaining decisions with object context rather than as YAML hunks, verify
hierarchy, references and prefab connections in the Editor, then stage the file
only after the merged scene opens and re-saves cleanly in the project's Unity
version.
Set this up before you need it
Neither of these helps retroactively. Both take a minute.
- Force Text serialization. Project Settings → Editor → Asset Serialization → Mode: Force Text. Binary assets cannot be merged or reviewed at all.
-
Visible Meta Files.
Project Settings → Version Control → Mode: Visible Meta Files, and
commit every
.metaalongside its asset. A.metaseparated from its file is a lost GUID, and a lost GUID is every reference to that asset breaking at once.
Then register Unity's Smart Merge tool, UnityYAMLMerge, which ships
with the Editor under Editor/Data/Tools:
[merge]
tool = unityyamlmerge
[mergetool "unityyamlmerge"]
trustExitCode = false
cmd = '<path to UnityYAMLMerge>' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
The order of operations
-
Do not stage anything yet. Run
git status --shortand note every conflicted.unityand.prefab. Staging a file to make the warning go away is how scenes get silently truncated. - Keep all three inputs. Base is the common ancestor, ours is the current branch, theirs is the incoming one. Resist the urge to take one side wholesale before you know what each side did — for a shared scene, "take theirs" usually discards a day of somebody's work.
-
Run
git mergetool. Smart Merge resolves the cases where the two branches touched different objects: additions, deletions and edits that do not overlap. This is the majority of conflicts and it handles them well. - Classify what is left. What survives is what needs judgement: hierarchy moves, sibling reordering, two branches editing the same component, delete-versus-edit, and changes to prefab instance overrides.
- Review the remaining decisions with object context, not as raw YAML hunks. You are deciding between two intents, and the intent is not visible at line level.
- Verify the result before staging — see the checklist below.
A merge can complete with no conflict markers, commit cleanly, and still be wrong. Text merging guarantees a syntactically valid file. It guarantees nothing about whether an object is still under the right parent or whether a reference still points at the thing it used to. Teams usually discover this two days later, in QA.
What UnityYAMLMerge cannot do
Knowing the boundary saves you from trusting the output too far.
- Both branches edited the same object. There is no correct automatic answer, so it defers to you.
- Move versus edit. One branch reparented an object while the other changed it. Mechanically resolvable, semantically ambiguous.
- Intent. It cannot know that the two conflicting changes were halves of one design decision made in a meeting you were not in.
- Consequences. It will not tell you that the merged scene now has a light probe volume with no probes, or a spawner pointing at a deleted prefab.
Checklist before you stage
- Every added, modified, moved and removed GameObject is one you expected.
- Parent–child structure and sibling order match the intended scene.
- Changed references still point at the correct assets.
- Prefab instances are still connected and their intentional overrides survive.
- No conflict markers, no missing scripts, no unassigned references in the Console.
- The scene opens and re-saves in the project's Unity version without churn.
That last one is a cheap and underused test. If opening and saving the merged scene produces a large diff, the merge left the file in a state Unity does not consider canonical, and something is wrong.
Reducing conflicts in the first place
Resolution is a skill; avoidance is a workflow.
- Split large scenes. Additive scenes and prefabs create ownership boundaries. Two people working in one 5,000-object level scene will conflict forever.
- Keep scene branches short-lived. A branch that touches a shared scene should merge the same day. Divergence compounds.
- Announce scene work. Low-tech, and it removes more conflicts than any tool.
- Lock genuinely shared assets if your VCS supports it. Not every problem should be solved after the fact.
Frequently asked questions
How do I resolve a Unity scene merge conflict in Git?
Keep Git's conflict state, run UnityYAMLMerge through git mergetool, review the remaining decisions with object context rather than as YAML hunks, verify hierarchy, references and prefab connections, then stage the file only after the merged scene opens cleanly in the project's Unity version.
What can UnityYAMLMerge not resolve?
Cases where both branches edited the same object, move-versus-edit conflicts, and anything that depends on intent. It also cannot tell you whether the merged result is semantically correct — only that it is syntactically valid.
Why does a resolved Unity scene break later?
Because a text merge guarantees a valid file, not a valid scene. The result can preserve the wrong parent, a broken reference or a lost prefab connection, and that surfaces in QA rather than at merge time.
How do I reduce Unity scene merge conflicts?
Split large scenes into additive scenes and prefabs to create ownership boundaries, keep branches that touch shared scenes short-lived, announce scene work, and lock genuinely shared assets if your version control supports it.
For the review step — understanding what a branch changed before you merge it — Scene Diff compares scenes and prefabs by object identity rather than by line. On why line-level diffs mislead in the first place, see Why a text diff of a .prefab file lies to you.