U
01 / 22 · 10 min
FAQ

Git for Unity: what to commit and what to ignore

the short answer

How do I use Git with a Unity project without breaking it?

Commit Assets/, ProjectSettings/ and every .meta file; ignore Library/, Temp/, obj/, Build/ and Logs/. Set Version Control to Visible Meta Files and Asset Serialization to Force Text before anyone clones, put large binaries in Git LFS from the start, and split work into prefabs so two people never merge the same scene.

Git works fine with Unity. What goes wrong is that a Unity project contains three kinds of file — your work, files Unity writes about your work, and files Unity can rebuild from scratch — and Git cannot tell them apart. Commit the wrong group and the repository turns into gigabytes of churn that conflicts on every pull. Sort the three out once, at the start, and the rest is ordinary Git.

The three kinds of file

  • Your work: everything under Assets/ — scenes, scripts, prefabs, models, textures. This is what the repository is for.

  • What Unity writes about your work: ProjectSettings/, Packages/manifest.json, and one .meta file for every asset. Small, and you must commit them.

  • What Unity rebuilds by itself: Library/, Temp/, Logs/, obj/, Build/. Gigabytes, different on every machine, and worthless to anyone else. Never commit these.

Set the project up first

  1. 1

    Open Edit▸Project Settings▸Editor. Set Version Control mode to Visible Meta Files, and Asset Serialization mode to Force Text.

  2. 2

    Force Text writes scenes and prefabs as YAML instead of binary. A binary scene is one unreadable blob to Git: you cannot see what changed and you can never merge two people's work.

  3. 3

    Commit both settings before anyone clones the project. Changing them later rewrites every scene file in one enormous commit.

The .gitignore

Put this at the root of the repository, next to the Assets folder. The trailing slash matters: it says folder, so a file that happens to be called Temp is still tracked.

.gitignore
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ogs/
[Uu]serSettings/
[Mm]emoryCaptures/

# Editor and OS noise
.vs/
.idea/
.DS_Store
*.csproj
*.sln
*.user

# Build outputs
*.apk
*.aab
*.unitypackage

# Crash reports
sysinfo.txt

If Library is already committed

terminal
git rm -r --cached Library Temp obj Build
git commit -m "Stop tracking generated folders"

--cached removes them from Git without deleting them from your disk. The history still contains them, so the repository stays large until someone rewrites it; for a young project it is usually faster to start a fresh repository than to learn git filter-repo.

Large files: textures, models, audio

Git stores a whole new copy of a binary file on every change. Re-export one 40 MB model ten times and the repository carries 400 MB forever. Git LFS stores a pointer instead and keeps the file elsewhere.

terminal
git lfs install
git lfs track "*.psd" "*.fbx" "*.blend" "*.wav" "*.mp3" "*.mp4"
git add .gitattributes

Two people, one scene

This is the part Git cannot solve for you. A scene file is one YAML document describing every object in it, so two people editing different corners of the same scene still edit the same file, and Git offers you a merge it has no way to get right.

  • Split the work into prefabs. One person owns the enemy prefab, another owns the UI prefab, and the scene only holds instances. Two prefabs are two files, and two files do not conflict.

  • Use additive scenes for big levels: one scene per area, loaded together at runtime. Each person opens their own file.

  • Say out loud who has the scene open. On a team of two or three this is faster and more reliable than any tool.

  • If a merge conflict in a .unity file does happen, take one side whole and redo the other side's work by hand. A hand-merged YAML scene opens as a corrupted file often enough that it is not worth the attempt.