Unity 3.5, Mercurial, and BitBucket

I have successfully updated my project to 3.5 and switched to using external version control, moving it into a Mercurial repository.  I am still a little dismayed that Unity doesn’t work a little more smoothly with things under version control.  Having a second set of meta files for everything means that you need to manage moving and renaming everything yourself and then doing the proper commands to your VCS when you do that.  Workflow like that is beyond painful and makes any major restructuring a nightmare!

Being a long time Java developer with super powerful high quality IDEs like Eclipse I have gotten used to working through it to do any changes and having it take care of everything with the VCS.  I wish Unity did this out of the box with external version control, especially because they force you into a mindset of only manipulating the assets via the project view, yet this completely breaks down moving to external version control.  Hopefully they will add this in a future release so we can focus on development and not file management.  In the mean time, I did find a workaround someone developed using the asset post processing hooks, and this makes life a lot easier.

For those out there struggling to decide between Git and Mercurial, I can tell you what my conclusion was and why I chose Mercurial.  First, I started looking at it because Unity uses it in their build process.  They did a blog post on all the build technologies they use and they have some good reasoning.  I also found a great Mercurial tutorial called HgInit that you should go through first before anything else if you are interested in Mercurial.  I can’t rate this tutorial high enough and I love the humor in it – especially about undoing the brain damage caused by Subversion!  And they are right about everything – I work in a semi-large development team using Subversion and we have the nightmare branching and merging and the multi-week projects with no commits of our working copies – all so we don’t disrupt others.  I have seen the light now and distributed source control rules!  While doing my research I found Mercurial to be simpler and less tethered to non-portable libraries.  I also liked that there are TortoiseHg clients for both Windows and Mac to provide a similar GUI experience if I don’t want to go command line.  I also liked that it has features to instantly serve repositories over HTTP which is useful for doing clones and push/pulls with ease between different computers.

What finally clinched my Mercurial usage was finding a post processing editor script that manages the add/removes of both the source and meta files directly in the editor.  This makes it easy to add, delete, or move stuff in the project view just as you did before and it automatically does the Hg commands using a .NET library.  You can then review and commit with a client like TortoiseHg when you have completed your changes.  This kind of functionality should be built into Unity in my opinion.  The downside is that it requires pro since the post processing is only available in the pro version.

Also, I did have to fix the script for windows paths and make it so you can properly rename something and then rename it back and be at the original state with nothing to commit.  You can contact me for the changed one but I am still testing it so there is no guarantee it will work in all cases.  If I can thoroughly test it and refine it I will try and submit a change to the original project.

The process to switching on version control can be found in the Unity docs.  You can follow it although you must create the repository at step 5 and 6.  For these steps I just used TortoiseHg to create a repository for my project directory.  

Also the ‘.hgignore’ ignore file I use in step 8 is:

syntax: glob
.DS_Store
Library/*
Temp/*
*.csproj
*.pidb
*.sln
*.unityproj
*.userprefs      

I added the hgpostprocessor script at the end once the project was all setup.

Distributed version control is great except for one side effect that hits us game developers hardest.  With any distributed VCS including Mercurial or Git, all history for a project is kept locally which means you have every change to every file in your local repository.  This is also true for the large binary files we have for models, textures, etc.  Because of this, the local repositories can become very large as binary files are revised and this is likely going to be extreme in any project using a lot of art and that art being refined over the course of the project.

Once the repository becomes very large, cloning and pulling becomes difficult.  Cloning is the core of distributed version control.  The idea being that you clone for any new major work you want to do that you don’t want impacting your other repositories.  So for example, I have a clone to gut the existing pathfinding system and replace it with the NavMesh pathfinding system in 3.5.  I want to do this separate from all other work and then push the changes back to my main repository.  And this workflow is repeated many times for many features.  As you can imagine this starts becoming more painful as the repository becomes larger.  This is also magnified if you are cloning or pulling over the internet with a larger team.  Unity even adds more time because after an initial clone, Unity re-imports everything to rebuild its ‘Library’ in that new clone. 

With Mercurial there is a feature for dealing with this issue called the LargefilesExtension which moves only files needed for the revision you have updated to.  I have yet to try this extension and my project is only a couple of GB right now.  Of course a project like AOS could likely grow to the 10 to 20 GB that builds down to 1 GB in the end.  I will probably experiment with it in the future as I get more comfortable with Mercurial and distributed version control concepts in general.

Last, I am looking into pushing it to BitBucket however I haven’t yet due to size.  I did find out that they do allow large projects up to 10GB, but in practicality it is too big.  They did recommend using modules, however I have not investigated that yet.  They also do not support the large binary extensions.

Since I am still experimenting I have decided to stick to just using it internally where large repositories due to modified binaries won’t matter much and I can push/pull on a LAN which is reasonable even for these large repositories.

Bookmark the permalink.

2 Comments

  1. Did you ever end up using the largefiles extension? I’m trying to figure out a similar solution for VC with Unity and I like Hg, but I just worry about all the binary files.

  2. Unfortunately I have not had the time to try this out. I have had no issues with the approach I mentioned in the post (with my modified post processor script), however it is only me working among multiple repositories on a LAN. I have not had enough participation in the project to warrant sharing over the internet yet.

    When I do get to the point of hosting it somewhere the size is going to be the major issue but a large repository accessed locally is not an issue at all. My repository has grown some and is now around 4GB with 1GB of that being in the .hg folder which is all the extra history.

    Even hosted over the internet, it is only the initial clone to your local drive that is going to be time consuming and then letting Unity rebuild the Library folder. Once this is done it shouldn’t be too bad. You can even make other clones from your local master to do iterative longer running work and just pull/push though your local master. That way you have a running version of the team master repository locally.

    I still think it isn’t much of an issue for smaller projects, just ones like mine which have a huge number of large assets. You can always try it and if you don't like it just delete the Hg stuff and switch it to another VC system. Another option is just to destroy the history if you don't need it after a while or recreate a new repository and archive the old one.

    Hg is definitely worth it over subversion and the TortoiseHg client is fantastic at least on Windows (have not tried the Mac yet). I would suffer the binary issues just to stay with a DVCS and Hg.

    The only downside to all this is that you can't use the services like BitBucket because they don't like large repositories > 1GB and don't even support the extensions anyway. If you need to share a large repository you are going to have to host it yourself somehow.

    I did look at some tools for this which can be found here:

    http://mercurial.selenic.com/wiki/PublishingRepositories

    and tried:

    http://www.scm-manager.org/

    which worked but is a little rough around the edges – it does other VCSs so may be useful to try. I will let you know how things go once I am back to pushing my stuff on the internet. Best of luck, contact me anytime if you need anything, and thanks for reading the blog!

Leave a Reply