Use the UnityYAMLMerge tool to merge scene and prefab files in a semantically correct way. You can run the tool from the command line, and several version control tools integrate it directly.
UnityYAMLMerge merges scene (.unity), prefab (.prefab), and .meta files. For other files, and for conflicts it can’t resolve, it uses fallback merge tools listed in the mergespecfile.txt file. These fallbacks let you use UnityYAMLMerge as the main merge tool for version control systems that don’t select merge tools based on file extension. The spec file already lists the most common merge tools, and you can edit it to add tools or change options. For the location of this file, refer to Configuration file locations.
By default, UnityYAMLMerge doesn’t merge other YAML-serialized files, such as .asset, .mat, or .controller files. If your version control tool passes these files to UnityYAMLMerge, UnityYAMLMerge hands them to a fallback merge tool. To merge them with UnityYAMLMerge anyway, use the --force argument. For more information, refer to UnityYAMLMerge command-line reference.
Smart merge is useful when two people change the same scene or prefab file in parallel, and your version control system needs to combine the changes. This happens when you work on separate branches, or when your version control system doesn’t lock files on checkout.
If your team uses exclusive checkout to lock scene and prefab files, two people can’t edit the same file at the same time, and you don’t need smart merge for those files.
In most workflows, you don’t run UnityYAMLMerge yourself. After you set it up, your version control tool runs it when you resolve a merge conflict in a scene or prefab file. For example, Unity runs it when you resolve conflicts in the Editor with Perforce, and Git runs it when you run git mergetool. You can also run UnityYAMLMerge from the command line. For more information, refer to UnityYAMLMerge command-line reference.
How you set up smart merging in the Editor depends on the version control system configured in Edit > Project Settings > Version Control.
When Mode is set to Unity Version Control, the Unity Version Control client resolves merges, not Unity. The client uses the merge tools set in its own preferences.
The Revision Control Diff/Merge preference in Unity doesn’t control how the Unity Version Control client merges files. For example, selecting PlasticSCM Merge there doesn’t make the client use UnityYAMLMerge.
To use UnityYAMLMerge for scene and prefab files, add it as a merge tool in the Unity Version Control client. For more information, refer to Set up for Unity Version Control.
When you use Perforce, Unity can use UnityYAMLMerge when you resolve conflicts in scene (.unity) and prefab (.prefab) files from inside the Editor.
To set up smart merging:
Go to Edit > Project Settings > Version Control.
In Mode, select Perforce.
In Smart merge, select one of the following options:
To set up UnityYAMLMerge:
The UnityYAMLMerge tool is included with the Unity Editor.
When Unity is installed in the default Unity Hub location, the path to UnityYAMLMerge is:
On Windows:
C:\Program Files\Unity\Hub\Editor\<version>\Editor\Data\Tools\UnityYAMLMerge.exe
On macOS:
/Applications/Unity/Hub/Editor/<version>/Unity.app/Contents/Tools/UnityYAMLMerge
Tip: To access this folder from the macOS Finder, right-click Unity.app and select Show Package Contents.
On Linux:
~/Unity/Hub/Editor/<version>/Editor/Data/Tools/UnityYAMLMerge
UnityYAMLMerge reads the mergespecfile.txt and mergerules.txt configuration files from the same Tools folder that contains UnityYAMLMerge, for example <Unity installation>\Editor\Data\Tools on Windows. For more information, refer to Locate UnityYAMLMerge.
To add UnityYAMLMerge as a merge tool in the Unity Version Control client:
In the Unity Version Control desktop client, open Preferences and select Merge tools.
Select Add.
Select Custom extension and enter .unity;.prefab.
In External tool, select Unity Smart Merge. This option is available in Unity Version Control 11.0.16.10303 and later. The client fills in the command with the path to UnityYAMLMerge in one of your installed Unity Editors. If you remove that Editor version later, update the path.
To use your own command instead, select Custom and enter:
"<path to UnityYAMLMerge>" merge -p "@basefile" "@sourcefile" "@destinationfile" "@output"
For <path to UnityYAMLMerge>, refer to Locate UnityYAMLMerge.
Select Save next to the command field to load the new rule in the list.
Use the up arrow to move the new rule above the $text rule. Unity Version Control applies rules from top to bottom, and scene and prefab files are text files, so the new rule must come first.
Select Save at the bottom of the window to save your changes.
To resolve conflicts from inside the Unity Editor, refer to PerforceA version control system for file change management. More info
See in Glossary instead.
To merge scene and prefab files with UnityYAMLMerge when you resolve conflicts in P4V:
.unity.merge -p %b %1 %2 %r..prefab extension.Add the following text to your repository’s .git/config file. To use it in all your repositories, add it to your global ~/.gitconfig file instead:
[merge]
tool = unityyamlmerge
[mergetool "unityyamlmerge"]
trustExitCode = false
cmd = '<path to UnityYAMLMerge>' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
For <path to UnityYAMLMerge>, refer to Locate UnityYAMLMerge.
Add the following text to your .hgrc file:
[merge-patterns]
**.unity = unityyamlmerge
**.prefab = unityyamlmerge
[merge-tools]
unityyamlmerge.executable = <path to UnityYAMLMerge>
unityyamlmerge.args = merge -p --force $base $other $local $output
unityyamlmerge.checkprompt = True
unityyamlmerge.premerge = False
unityyamlmerge.binary = False
For <path to UnityYAMLMerge>, refer to Locate UnityYAMLMerge.
Add the following to your ~/.subversion/config file:
[helpers]
merge-tool-cmd = <path to UnityYAMLMerge>
For <path to UnityYAMLMerge>, refer to Locate UnityYAMLMerge.
To set up TortoiseGit:
In Preferences, add an advanced merge tool.
In Extension, enter .unity.
In External Program, enter:
"<path to UnityYAMLMerge>" merge -p "%base" "%theirs" "%mine" "%merged"
For <path to UnityYAMLMerge>, refer to Locate UnityYAMLMerge.
Follow the same procedure to add the .prefab extension.
To set up SourceTree:
merge -p $BASE $REMOTE $LOCAL $MERGED.Version control tools call UnityYAMLMerge with the merge command:
UnityYAMLMerge merge [options] <base> <theirs> <mine> [<output>]
UnityYAMLMerge supports the following options:
| Option | Description |
|---|---|
-p |
Premerge the file. UnityYAMLMerge merges everything it can, then opens the fallback merge tool with premerged files that contain only the remaining conflicts. |
-l |
Resolve conflicts with the theirs version. |
-r |
Resolve conflicts with the mine version. |
-h |
Run in headless mode, with no error dialogs. |
-i <file> |
Resolve conflicts with a merge file. |
-o <file> |
Write conflicts to a file. |
--rules <file> |
Use a custom merge rules file instead of the default mergerules.txt. |
--fallback <file> |
Use a custom fallback spec file instead of the default mergespecfile.txt. Set to none to disable fallback tools. |
--force |
Merge files even if their extension isn’t .unity, .prefab, or .meta. |
--describe |
Include a description of the merge in the -o file. |
--nomappinginoneline |
Split YAML data across multiple lines whenever a line exceeds 80 characters, instead of writing inline mappings on one line. |
The --nomappinginoneline option is the command-line equivalent of the EditorSettings.serializeInlineMappingsOnOneLine API. Use the same single-line setting in both places, so that the files UnityYAMLMerge writes stay consistent with the files Unity writes.
To customize how UnityYAMLMerge merges files, edit the mergerules.txt file. For its location, refer to Configuration file locations.
The arrays configuration section tells UnityYAMLMerge to treat the specified path as an array: either as a set with a key value, or as a plain array without key values. The default for all arrays is a hybrid mode that tries to match with some known heuristics.
Each rule starts with a mode: set or plain.
Default array rules:
[arrays]
set *.GameObject.m_Component *.fileID
set *.Prefab.m_Modification.m_Modifications target.fileID target.guid propertyPath
plain *.MeshRenderer.m_Materials
plain *.Renderer.m_Materials
The exclusions configuration section indicates which paths to exclude from merging. If both sides modify the same path, UnityYAMLMerge treats the change as a conflict and prompts you to resolve it.
Each rule starts with one of the following modes: include, exclude, includeIfContains, or excludeIfContains.
Default exclusion rules:
[exclusions]
exclude *.MeshRenderer.m_Materials.*
exclude *.SpriteRenderer.m_Materials
exclude *.SpriteRenderer.m_Color
include *.ParticleSystem.InitialModule
exclude *.ParticleSystem.*
exclude *.ParticleSystem.InitialModule.*
#excludeDepend *.MonoBehaviour m_Script ^m_
excludeIfContains *.MonoBehaviour.* x y z
excludeIfContains *.MonoBehaviour.* r g b
The comparisons section lets UnityYAMLMerge ignore negligible differences between float values. When enabled, UnityYAMLMerge compares floating-point values relative to their magnitude, to account for relative error. You can configure comparison in the following ways:
float <float value to compare>: Sets epsilon to a default value close to machine epsilon.float <float value to compare> <relative comparison value and absolute cutoff>: Uses one value as both the relative comparison value and the absolute comparison cutoff.float <float value to compare> <relative comparison value> <absolute comparison cutoff>: Sets the relative comparison value and the absolute comparison cutoff separately.The relative comparison value determines epsilon and how the comparison scales with the size of the values’ relative error. The absolute comparison cutoff determines how far from zero a value must be before the comparison switches from absolute to relative.
Note: Comparison values must be between float epsilon (0.00000011921) and 1.0.
Note: Don’t indent rule or section lines. If you copy the commented example from mergerules.txt, remove the leading tab as well as the # character. Otherwise, UnityYAMLMerge reports an invalid rule format error.
Comparison examples:
[comparisons]
float *.Transform.m_LocalPosition.x 0.0000005
float *.Transform.m_LocalPosition.y 0.0000005
float *.Transform.m_LocalPosition.z 0.0000005
float *.Transform.m_LocalRotation.x 0.00005 0.001
float *.Transform.m_LocalRotation.y
float *.Transform.m_LocalRotation.z 0.00005 0.001
float *.Transform.m_LocalRotation.w