gitunity-game-enginegit-mergemeld

Setting up Unity Smart Merge with Git and Meld for Unity 2019.3+


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.


Solution

  • 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.