Free or cheap
Backup code & assets
Work offline
Easy to use
Console and GUI
=
Git / Git LFS / SourceTree / Bitbucket
Failing Faster involves failing.
Breaking things along the way.
Then doing some damage control.
Or at least version control.
Now you can break everything.
And turn back time.
As if nothing ever happened.
Content
What’s version control, Git and how does it work?
How do I install Git on my machine?
Git seems great for code. What about big binary assets?
How do I create the .gitignore file?
How do I edit the .gitattributes file?
How do I create a local Git repository?
How to share versions across several machines?
Why Bitbucket and not GitHub or Git Lab?
Why not just use Unity Collaboration?
How to push the content of your local repository to the remote repository?
What’s version control, Git and how does it work?
Version control is the practice of tracking and managing changes to software code (eg. save code and load saves as needed).
There are 2 types of version control systems: central (code and assets are on one machine) and distributed (synced copies of code and assets are on several machines).
Git is a distributed version control system.
Atlassian made the best Git tutorial I could find. Check it out to understand what version control is and how Git in particular works. Then put it aside and come back to it when you’ll actually start using Git. You’ll see. Super helpful.
How do I install Git on my machine?
Two options.
Option A: Get git. Get comfortable with Git bash and command lines. It’s probably the most efficient way of using Git. Doesn’t seems so, I know. Especially if you’re new to programming. But it’s true.
Option B: Get a nice GUI. It will help by installing everything for you and make things visual. I went for Atlassian’s SourceTree.
SourceTree is free and requires a Bitbucket account, which is what I’ll use to backup the game’s source online. More on that later.
For now, install SourceTree and tick:
- “Git”
- In “Advanced Options”: “Configure automatic line ending handling by default”*
*Different operating system handles line endings differently (eg. when you press return, an invisible character is added – called a line ending). If you collaborate with fellow game developers using different operating systems, Git might not work as expected. Good news! Tick this options and Git will handle line endings automtically .
Git seems great for code. What about big binary assets?
Versioning big files such as textures, meshes, sounds etc. is going to make your Git repository explode. Remember that “versioning” really means storing copies of each file you edit. So even if you only have one 10 Mo texture and edit it 10 times, that’s 100 Mo just for one file (!). And you’ll have many more in your game project.
The solution is Git LFS. Check out Atlassian’s Git tutorial Git LFS section.
It’s a Git extension that basically only downloads the “last” version of certain files. All you need to do is specify which types of files to version like that in a .gitattributes file. We’ll get to that in a sec.
How do I use Git with Unity?
What you need to do:
- Make sure Unity Project Settings are as follows:
– Editor tab: Asset serialization mode is set to Force text
– Version control tab: version control mode is set to Visible Meta Files - Create a .gitignore file
- Edit the .gitattributes file
To learn more about this, check out this Git with Unity GDC 2017 talk or this Complete guide to Unity and Git.
How do I create the .gitignore file?
A .gitignore file will specify a list of file types and locations that Git should not version. Things like cache or hidden OS files for example.
To generate the .gitignore file that is right for you head to gitignore.io and specify your game dev stack. Here’s mine created for Windows, Unity and Visual Studio Code:
.gitignore
# Created by https://www.toptal.com/developers/gitignore/api/windows,unity,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,unity,visualstudiocode
### Unity ###
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
# Asset meta data should only be ignored when the corresponding asset is also ignored
!/[Aa]ssets/**/*.meta
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
# Crashlytics generated file
crashlytics-build.properties
# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/windows,unity,visualstudiocode
For the .gitignore file to be taken into account, it must be placed at the root of your Unity Project folder. You can create a text file and past this text in. Then change the file’s extension* to .gitignore.
Otherwise, you can create a .gitignore file when we set up the remote repository in Bitbucket.
*You can also do this by using the Terminal where this file is located and renaming it to .gitignore using the following command:
ren NameOfYourFile.txt .gitignore
How do I edit the .gitattributes file?
Just like in the .gitignore file, every file type you specified here will be picked up by Git LFS and it will only pull the last version when requested.
.gitattributes
# 3D models
*.3dm filter=lfs diff=lfs merge=lfs -text
*.3ds filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.c4d filter=lfs diff=lfs merge=lfs -text
*.collada filter=lfs diff=lfs merge=lfs -text
*.dae filter=lfs diff=lfs merge=lfs -text
*.dxf filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.jas filter=lfs diff=lfs merge=lfs -text
*.lws filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text
*.ma filter=lfs diff=lfs merge=lfs -text
*.max filter=lfs diff=lfs merge=lfs -text
*.mb filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
*.ply filter=lfs diff=lfs merge=lfs -text
*.skp filter=lfs diff=lfs merge=lfs -text
*.stl filter=lfs diff=lfs merge=lfs -text
*.ztl filter=lfs diff=lfs merge=lfs -text
# Audio
*.aif filter=lfs diff=lfs merge=lfs -text
*.aiff filter=lfs diff=lfs merge=lfs -text
*.it filter=lfs diff=lfs merge=lfs -text
*.mod filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
*.s3m filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.xm filter=lfs diff=lfs merge=lfs -text
# Fonts
*.otf filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
# Images
*.bmp filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.hdr filter=lfs diff=lfs merge=lfs -text
*.iff filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.pict filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.tiff filter=lfs diff=lfs merge=lfs -text
How do I create a local Git repository?
On your computer, create an folder where you’ll create your Unity project.
In SourceTree, select Create and browse to find your Unity project’s folder. Git is going to detect all the files that it’s not currently managing under the “Unstaged files” window.
Click Stage All, enter a description such as “Initial commit” and click Commit.
That’s it really. Now can save and store the current state of any file. And most importantly you can break things without worry. Because you can revert to any version you want. You have control. Version Control.
How to share versions across several machines?
Git will manage a Local Repository only available on your machine.
But what happens if your hard drive explodes? You’ll cry. And have no way to recover. Unless you set up a Remote Repository. Atlassian has you covered with Bitbucket.
Create a Bitbucket account and link it to SourceTree. In Bitbucket, create a new repository.
If you haven’t created a local repository already, you can clone it on your computer. This means to make a copy of the remote repository (which is on Bitbucket) on you computer and create a linked local repository. When you’ll male local changes, you’ll be able to push them to Bitbucket to keep both copies in sync and thus always have a backup safely store online.
In Sourcetree, select Clone and browse the repositories availble on your Bitbucket account.
Why Bitbucket and not GitHub or Git Lab?
Both GitHub and GitLab are great and offer free private repositories.
However, I chose Bitbucket because it integrates perfectly with other Atlassian products I want to use such as SourceTree and later Trello or Jira Software to tracks tasks and bug. Plus, you can integrate your boards directly into Bitbucket. Neat.
Why not just use Unity Collaboration?
This is probably all you need really. It’s quite straightforward, integrated with Unity and easy to learn. The problem is most professional game developers use a full-fledged Version Control system. So better learn how to use one. And Git is a safe bet at the moment, really popular, used by 69% of developers according to a Stack Overflow survey.
How to push the content of your local repository to the remote repository?
With your local repository set up and the .gitignore file created, you are ready to save the work you’ve done and send it to Bitbucket.
The Git lingo for saving your changes locally is to commit and for sending your changes to the remote repository is to push.
Create an empty Unity project in the folder where you’ve created the git repository or juste save your changes if you’ve already started working on your project.
Open SourceTree.
Click Stage All to add all the changed files.
Click the Commit icon.
Enter a Description.
Click the Commit button.
Click the Push icon (or tick the Push changes immediately to origin/master before you commit to save this last step.)
Commit small, commit often.
This will help you make sure you don’t lose any work done and can easily revert some changes if something went wrong.
Here is what SourceTree does for you, just as you would have done if you were working with console commands:
Add all changed files to commit
Commit changed files with a description
Push the changes to the remote repository
git add .
git commit -m "Commit description"
git push origin master
Now if you bring someone on your team or if you burn your hard drive you can always pull the whole project from the remote repository.
You’re all set. Start changing things, breaking things. Creating things.