2

I looked everywhere for documentation on this matter with little to no success. Unity's own documentation is very much incomplete when it comes to this dynamic. I am here to provide you with the only way I've been able to get it to work. Of course I would appreciate feedback on how this could be done better, but as it stands now nearly all Google searches on this topic are 2 years old or older.

The Unity docs say to add the following to the .git/config:

[merge]
    tool = unityyamlmerge

[mergetool "unityyamlmerge"]
    trustExitCode = false
    cmd = '<path to UnityYAMLMerge>' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"

The vast majority of the community agrees with that, and also tell you to add either one of these to .gitattributes:

*.unity binary
*.prefab binary
*.asset binary

or

* text=auto

# Unity files
*.meta -text merge=unityyamlmerge diff
*.unity -text merge=unityyamlmerge diff
*.asset -text merge=unityyamlmerge diff
*.prefab -text merge=unityyamlmerge diff

Neither of which work. I found many different alternatives to the blocks of code above. I looked for days, wasted a whole weekend even. Nothing will work and I can't find any current information on the matter.

1 Answer 1

5

On Windows 10 using Unity 2019.3+ and a current version of Git, this was the only way I could get it to work.

mergespecfile.txt

First, add the following entries into the mergespecfile.txt to allow Unity's Smart Merge to use the diff tool of your choice. I'm using Meld here. Note that --auto-merge is optional. The way I understand it is that it will skip prompting you for a merge.

File Location - Windows: C:\Program Files\Unity\Hub\Editor\<unity version>\Editor\Data\Tools

File Location - Mac: /Applications/Unity/Hub/Editor/<unity version>/Unity.app/Contents/Tools

unity use "%programs%\Meld\meld.exe" "%l" "%r" "%b" "%d"
prefab use "%programs%\Meld\meld.exe" "%l" "%r" "%b" "%d"
* use "%programs%\Meld\meld.exe" "%l" "%r" "%b" "%d"

.gitattributes

Next add this to the .gitattributes of your repo. Any file type you specify here will be run through Unity's Smart Merge. Anything NOT listed here will default to Git's auto-merge in where you can run git mergetool to invoke our chosen diff tool for the merge.

# Macro for Unity YAML-based asset files.
[attr]unityyaml -text merge=unityyamlmerge diff

# Unity files
*.meta unityyaml
*.unity unityyaml
*.asset unityyaml
*.prefab unityyaml

.git/config

Lastly, and this was the worst part to figure out, add the following to your .git/config. This file is very picky about how syntax is used. And contrary to the majority of the documentation, it seems like using a merge driver is the only way to get this to trigger.

Make sure to change the filepath's to match your version/operating system, and change the merge/diff tool to whichever one you prefer.

[merge "unityyamlmerge"]
    driver = 'C:/Program Files/Unity/Hub/Editor/2019.3.14f1/Editor/Data/Tools/UnityYAMLMerge.exe' merge -p \"$BASE\" \"$REMOTE\" \"$LOCAL\" \"$MERGED\"
    name = Unity SmartMerge (UnityYamlMerge)
    recursive = binary
[diff]
    tool = meld
[difftool "meld"]
    path = C:/Program Files (x86)/Meld/meld.exe
[merge]
    tool = meld
[mergetool "meld"]
    path = C:/Program Files (x86)/Meld/meld.exe
    prompt = false

UPDATE - 9/23/2021

As of Unity 2021.1.21f1 and these settings continue to work as expected.

3
  • 1
    I doubt if the custom merge driver unityyamlmerge takes effect at all. According to docs on git-scm, the merge.*.driver expects a command template with this syntax: executable %O %A %B %L %P, not this: executable $BASE $LOCAL $REMOTE $MERGED, and it insists to read the exit code where 0 means clean merge. Guess an ill-formed value like one that evals to literally UnityYAMLMerge.exe merge -p "$BASE"... will always get exit code 1 and effectively just propagates the merge candidates to the next merge driver.
    – Oasin
    Commented Jan 8 at 9:49
  • Good find! So does that mean the custom driver should be defined like: driver = 'C:/Program Files/Unity/Hub/Editor/2019.3.14f1/Editor/Data/Tools/UnityYAMLMerge.exe' merge -p \"%0" \"%A\" \"%B\" \"%L\" \"%P\"? I moved to Plastic SCM a while back so I can't test this myself. Commented Jan 10 at 15:19
  • 1
    As the %As have their respective meanings, it may be translated to like driver = \".../UnityYAMLMerge.exe\" merge -p \"%O\" \"%B\" \"%A\" \"%A\" according to the doc: "The merge driver is expected to leave the result of the merge in the file named with %A by overwriting it" (so $MERGED = %A here). But there's still problem: Unity says we cannot trustExitCode of the tool but git expects the opposite.
    – Oasin
    Commented Jan 10 at 15:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.