Some Git and some Unity (and a little Redmine too)….(Uno)

March 21, 2012 by · 4 Comments 

Quite often on this blog, I talk about the tools that I use, those tools being Redmine, Git, and Unity 3D. I do mention how I use them together, but never in detail. Today, I’m going to talk a bit more about some of these things. With each of these areas, it’s quite easy to get lost in a world of features, so I’ll going to be a bit broader in this post. Maybe, in the future, I’ll go into more detail about a specific aspect.

Disclaimer: I am not a pro at Git, Redmine or Unity. I just like them all a lot.

So, one of the first things that I should probably mention is how cool version control really is. Regardless of whether you are working with a team, or on your own, version control is something worth looking into. Bundled with the fact that a lot of these are freely available, there really shouldn’t be too much of an excuse as to why you aren’t using version control (in my opinion, of course). My choice for a vcs is Git. I learned how to use Git from my day job, and I’m glad I did. I don’t know too much about the other options, so I’m not going to say anything like “Git is better than ‘X’ for reasons 1, 2, etc”. I’ll leave that job to sites like this one.

Previous version of Unity did not allow users of the free version of Unity to use external version control. However, that changed with the latest release of Unity 3.5. This was a positive for me, as I had a few projects that I just decided to stick entirely in version control. Now, nothing major went wrong, since I was working along, and I was able to do some funky things (like downgrade a project!), but since 3.5 allows non-pro users access to an external vcs, a lot of weight has been lifted off of my shoulders. And I’ve been talking more with others about working with a team, as we would be able to share files without odd hacks.

If you want to grab Git, you can do here. Again, I’m not planning to go into too much detail with how to use Git. Which is super easy to use, and strikingly fast. For a quick, but useful crash course on Git, check out Git Immersion. For more details about Git, and some of the crazy things you can do with it, I’d recommend Pro Git. As a side note, I’m also going to do things on the command line.

Let’s set up a local repository. I made a new Unity project, which only has one example script, and a blank scene. What we want to do is initialize the repository. So, let’s change directories, and do just that.

shawn@SHAWN-PC ~
 $ cd Desktop/TestProject/
shawn@SHAWN-PC ~/Desktop/TestProject
 $ git init
 Initialized empty Git repository in c:/Users/shawn/Desktop/TestProject/.git/
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

Cool, we now have a repo! Time go branch, merge, cherry-pick, stash, log, etc, right? Unfortunately, no. Let’s take a look at what’s in this current repo.

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 #
 # Initial commit
 #
 # Untracked files:
 #   (use "git add <file>..." to include in what will be committed)
 #
 #       Assets/
 #       Library/
 #       ProjectSettings/
 #       Temp/
 nothing added to commit but untracked files present (use "git add" to track)
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

Git status’ will show me the current state of my working directory. Let’s also change the directory, and take a look under the Assets Folder.

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ cd Assets/
shawn@SHAWN-PC ~/Desktop/TestProject/Assets (master)
 $ ls
 Example.cs  ExampleScene.unity
shawn@SHAWN-PC ~/Desktop/TestProject/Assets (master)
 $

I have a couple of files that are currently untracked, waiting to be put into version control. However, we don’t want to commit anything just yet. If you’re going to use Git (or any external vcs for that matter), and Unity, you’ll want to do is to enable external version control. To do this, we want to go to Edit –> Project Settings –> Editor. The inspector tab will reveal a few options. Change the first option to “Meta Files”. Once you do this, your project will automatically generate the proper .meta files that need to be ‘versioned’.

Enable Meta Files

Now, let’s take a look again at the files under the Assets Folder.

shawn@SHAWN-PC ~/Desktop/TestProject/Assets (master)
 $ ls
 Example.cs  Example.cs.meta  ExampleScene.unity  ExampleScene.unity.meta
shawn@SHAWN-PC ~/Desktop/TestProject/Assets (master)
 $

We can see now that we have a few new files, ending with .meta. These files are important, and will definitely be stuck into the version control system. Basically, when you add/create a new file in Unity (and have external version control enabled), Unity will generate the corresponding .meta file.

Okay, so we’re almost there. Let’s commit our files. We only want to commit two sets of things. Everything under the folder ProjectSettings, and everything under the Assets Folder (unless your workflow demands otherwise). Everything else, we can ignore. There are a few ways to go about this. The first would be to move everything to the staging area. To do this, we would run ‘git add .‘. The ‘ . ‘ specifies that we want to add everything. So, doing this (after changing back to the main project folder) would result in:

shawn@SHAWN-PC ~/Desktop/TestProject/Assets (master)
 $ cd ..
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git add .
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 #
 # Initial commit
 #
 # Changes to be committed:
 #   (use "git rm --cached <file>..." to unstage)
 #
 #       new file:   Assets/Example.cs
 #       new file:   Assets/Example.cs.meta
 #       new file:   Assets/ExampleScene.unity
 #       new file:   Assets/ExampleScene.unity.meta
 #       new file:   Library/AnnotationManager
 #       new file:   Library/AssetImportState
 #       new file:   Library/AssetServerCacheV3
 #       new file:   Library/AssetVersioning.db
 #       new file:   Library/BuildPlayer.prefs
 #       new file:   Library/BuildSettings.asset
 #       new file:   Library/EditorUserBuildSettings.asset
 #       new file:   Library/EditorUserSettings.asset
 #       new file:   Library/FailedAssetImports.txt
 ..........

All of these files are now ready to be committed to the project. But this isn’t want we want to commit. We only want everything under the Assets Folder and the ProjectSettings folder. So, let’s reset this. If you already had a commit in your history, you’d be able to run ‘git reset’, and be done. But since I haven’t commit anything yet, I’m going to need to run git rm -r –cached *‘  to reset the staging area. After running this, everything will be set to as it was before we ran git add . ‘.

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git rm -r --cached *
 rm 'Assets/Example.cs'
 rm 'Assets/Example.cs.meta'
 rm 'Assets/ExampleScene.unity'
 rm 'Assets/ExampleScene.unity.meta'
 rm 'Library/AnnotationManager'
 rm 'Library/AssetImportState'
 rm 'Library/AssetServerCacheV3'
 rm 'Library/AssetVersioning.db'
 ..................
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 #
 # Initial commit
 #
 # Untracked files:
 #   (use "git add <file>..." to include in what will be committed)
 #
 #       Assets/
 #       Library/
 #       ProjectSettings/
 nothing added to commit but untracked files present (use "git add" to track)

Okay, now let’s just add those specific folders, and files within them. We could stage things individually, like so:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git add Assets/Example.cs

or, we can add the entire folder:

shawn@SHAWN-PC ~/Desktop/TestProject (master) $ git add Assets/Example.cs

Now, if we run git status, we can see that we have a bunch of files ready to be committed:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
$ git st
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   Assets/Example.cs
#       new file:   Assets/Example.cs.meta
#       new file:   Assets/ExampleScene.unity
#       new file:   Assets/ExampleScene.unity.meta
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       Library/
#       ProjectSettings/

shawn@SHAWN-PC ~/Desktop/TestProject (master)
$

We can do the same thing for the ProjectSetting Folder. After we stage everything we want to stage, we’ll commit our files. We can run ‘git commit -m’, and after the -m part, include our commit message within quotation marks. So….:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git commit -m "Initial commit"
 [master (root-commit) e143bb3] Initial commit
 15 files changed, 24 insertions(+), 0 deletions(-)
 create mode 100644 Assets/Example.cs
 create mode 100644 Assets/Example.cs.meta
 create mode 100644 Assets/ExampleScene.unity
 create mode 100644 Assets/ExampleScene.unity.meta
 create mode 100644 ProjectSettings/AudioManager.asset
 create mode 100644 ProjectSettings/DynamicsManager.asset
 create mode 100644 ProjectSettings/EditorBuildSettings.asset
 create mode 100644 ProjectSettings/EditorSettings.asset
 create mode 100644 ProjectSettings/InputManager.asset
 create mode 100644 ProjectSettings/NavMeshLayers.asset
 create mode 100644 ProjectSettings/NetworkManager.asset
 create mode 100644 ProjectSettings/ProjectSettings.asset
 create mode 100644 ProjectSettings/QualitySettings.asset
 create mode 100644 ProjectSettings/TagManager.asset
 create mode 100644 ProjectSettings/TimeManager.asset
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

So, we commit a bunch of stuff! Lovely right? Let’s look at our log.

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git hist
* [e143bb3] 2012-03-20 (HEAD, master) | Initial commit

Git hist is an alias that I set up for the git command git log. There’s a bit more formatting details that I won’t get into, but it makes everything look pretty:

Git log made 'pretty'

After looking at the history, we can see that our log contains the initial commit with the message.

Let’s run ‘git status’ again:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 # Untracked files:
 #   (use "git add <file>..." to include in what will be committed)
 #
 #       Library/
 nothing added to commit but untracked files present (use "git add" to track)

Looks like there’s some of stuff that we don’t want to track. In fact, we just want to ignore it. Well, there’s a nice file that we can create called ‘.gitignore‘, which will do that for us. You can open up whatever editor you want, name a file .gitignore, and add the files you want git to…well, ignore. Let’s take a look at some of the files I have in my .gitignore:

.gitignore
 Assembly-CSharp-vs.csproj
 Assembly-CSharp.csproj
 Assembly-CSharp.pidb
 Library/
 TestProject-csharp.sln
 TestProject.sln
 TestProject.userprefs

In this file, I’m ignoring everything under the Library folder, some of the files generated when opening up MonoDevelop, an IDE that comes Unity, and the .gitingore file itself. If I had Unity on two machines, and was doing work on both of them, I may consider leaving the .gitingore line out of the .gitignore file. But, I’m not sure if that would be wise at this point.

Edit: As pointed out by kLinus (and some others), it’s probably better practice to not ignore the .gitignore file most of the time. There may be files that most people should ignore, and it wuld be easier if they didn’t have to set up the .ignore files on their end.  Also, a more transferable version of what to put in .gitignore could look like this:

*.csproj
*.pidb
*.sln
*.userprefs
Library/
Temp/

The Temp folder is created and destroyed when you open/close Unity, so if you happen to commit files while Unity is still open, you won’t run the risk of including Temp files. I’ve also heard talk of people saying that it’s better to close Unity before committing. I’m sure closing Unity is safer, but I don’t have any reasons to promote why committing while Unity is open is bad.

There are a few more thing you can do in regards to ignoring files. If you want to ignore things that everyone should ignore, then .gitignore is a good place to add things, and you can go and commit the .gitignore files. However, if there are files that you want to ignore, but everyone else may not want to, you can add your files to .git/info/exclude. This may be useful for specific files generated by an editor, or a platform specific program (the help and credit for that goes to a coworker of mine).

 

So, we create our file, save it, and run git status again:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 nothing to commit (working directory clean)
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

Now, we don’t need to worry about a Git tracking a bunch of other things. If we made this file before we made our first commit, we could have ran ‘git add . ‘, and only have Git add the files under Assets and ProjectSettings.

Okay, now we’re ready to work on our Unity project some more. Let’s say some changes were made to the example script, such as a Debug.Log statement added, or some new variables. After saving the script, you’ll see something happen after running ‘git status‘ again:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 # Changes not staged for commit:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #       modified:   Assets/Example.cs
 #
 no changes added to commit (use "git add" and/or "git commit -a")
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

Well, we have some modified files that need to be committed. Here, you can see that these file are already tracked by Git. If we made a new file, for example, called NewScriptTwo, and saved it, Git would tell us we also have another file (and it’s corresponding .meta file), but it’s currently not being tracked:

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git status
 # On branch master
 # Changes not staged for commit:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #       modified:   Assets/Example.cs
 #
 # Untracked files:
 #   (use "git add <file>..." to include in what will be committed)
 #
 #       Assets/NewScriptTwo.cs
 #       Assets/NewScriptTwo.cs.meta
 no changes added to commit (use "git add" and/or "git commit -a")
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

Let’s stage things individually. First, let’s add the new file, commit it, and look at our log.

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git add Assets/Example.cs
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git commit -m "Adding Example.cs"
 [master 9e2293f] Adding Example.cs
 1 files changed, 3 insertions(+), 2 deletions(-)
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git hist
* [9e2293f] 2012-03-20 (HEAD, master) | Adding Example.cs
 * [e143bb3] 2012-03-20 | Initial commit
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

The log shows a new commit, right on top of the first commit. Let’s also commit the other files, then view the history.

shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git add .
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git commit -m "Adding NewScriptTwo"
 [master bca80ab] Adding NewScriptTwo
 2 files changed, 22 insertions(+), 0 deletions(-)
 create mode 100644 Assets/NewScriptTwo.cs
 create mode 100644 Assets/NewScriptTwo.cs.meta
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $ git hist
 * [bca80ab] 2012-03-20 (HEAD, master) | Adding NewScriptTwo
 * [9e2293f] 2012-03-20 | Adding Example.cs
 * [e143bb3] 2012-03-20 | Initial commit
shawn@SHAWN-PC ~/Desktop/TestProject (master)
 $

Looks like it’s coming along.

But that’s it for now. I’ve come to realize that this post is getting quite long, which means that it needs to be split up. Next, I’m going to do a little bit more locally, bring remotes into the fold, and look at some Redmine.

About Shawn

Comments

4 Responses to “Some Git and some Unity (and a little Redmine too)….(Uno)”
  1. Mido Basim says:

    Hi shawn, I’m having trouble trying to ignore Library files and .sln files.
    I have been trying to solve this for 4 months now and no luck. I have tried every possible way. Here’s a screenshot to show you what I mean:
    http://puu.sh/1TiqO
    As you can see from the screenshot, I have done every possible combination I can think of to get rid of the stupid folder but no luck T_T.
    Please help!

Trackbacks

Check out what others are saying about this post...
  1. [...] project folder and add a .gitignore file with this list (obviously stolen from another tutorial linked here, hope the original author doesn’t sue me ). #Folders /Library /Temp [...]