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