Fifth in a series of posts on Software Design for Unity. Read the introduction here.
As I noted in the first post in this seriesor rather, in the footnotes – but if you read the footnotes you’ll already know that, and if you don’t then you’re not reading this either., Source Control, or Version Control, isn’t strictly a software design topic. But I’m going to argue – unlike specific patterns, which suit some tasks and not others – that it’s the one thing that will always, without question, improve your code (and life) no matter what.
Note that, perhaps even more than usual, this is mainly a “Why” post, not a “How” post. There are plenty of resources out there to help you get started – I just want to convince you that you should. Right now.
If you listen to me about only one thing, it should be thisActually, it should be sunscreen..
What is Source Control?
For the uninitiated, source control is a bit of a dark art. It can be really daunting, and it’s not always clear what the benefits are (particularly if you’re doing old-fashioned backups). But it shouldn’t be, and the benefits are enormous. Source control does two things. Firstly it makes everything safer, in much the same way that backups do, but better.
Backups are fine, but in reality no-one’s that good at them. You’ll get sloppy, your naming convention will inevitably get confused, and frankly it just tends to be a ball-ache. Source control affords you a really good backup system and much more. With source control it’s really fast to undo changes or go back to a previous version. The reason is that source control records everything as changes, not an entire version. Instead of using (project size x number of backups) space, the repository only grows slowly. Since these changes are small, it’s much faster to revert them than find and copy a fresh version of the entire project.
But the really cool thing is how that changes how you work.
Since ‘backups’ (or in source control changesets or commits) are just lists of changes, you can do something amazing. You can merge two versions of the codebase together. This changes everything.
Consider working in a team. Without source control, every person has to make sure every other person has the latest version of their work. This is error prone, takes time and effort, and is tedious in the extreme. With source control however, since the software knows who’s changed what and when, it’s easy to merge everyone’s work together automatically. In fact, in many cases, you can do this when multiple people have worked on the exact same file! Suddenly, the thought of working with a team isn’t a scary mess of logisticsor, at least, you’ve removed one source of scary logistical messes.. Plus this can (should!) all be on a server rather than locally, so you’re getting remote access and backup for free.
But what if you take this a step further? If you can merge with other peoples’ work, you can merge with your own too. Which means you can create a separate branch of your codebase, work on something, leave it for a bit, come back to the main branch, do some work, switch back to the new branch, finish it off, and just merge it seamlessly back into the main branch again.
This means you can develop new features in a sandbox, only merge them back when they’re done, and your main branch can always be stablein theory anyway – in reality you main branch will still break sometimes unless you’ve got impeccable project management!! Obviously this is super-cool, but the less obvious thing is how it changes your whole mindset.
The true value of source control is the Undo mentality
The Undo Mentality
Consider ‘undo’. Think about what life would be like without undo. You’d never try anything interesting. You’d be so scared of breaking things and not being able to quickly return to an un-broken state. This is for anything – Word, 3DS Max, Photoshop, Unity. Undo allows you to try stuff quickly without fear.
Source control does exactly this, but on a longer timescale. This is the true value of source control. You can try out entire new features, break everything, and scrap it all with a couple of clicks. You can try crazy things. You no longer fear change. I’m being totally sincere when I say that the mere thought of coding without source control makes me feel a little sick, both for the fear of losing work and the fear of doing work.
I can’t emphasise this enough, but I also can’t make you feel it – you’ve just got to trust me and start using source control. Use it habitually and religiously. As I say, it can seem daunting – magical, but in the bad, lack-of-understanding way – but jump in feet first and just do it.
Which One Should I Use?
Ok, so I’m being a bit glib. But which one you use isn’t important compared to the importance of just using one. Don’t worry about which one. Get started with Git, and once you feel like you understand it, see if you want to try a different one, like Mercurial (also known as Hg)Having spent lots of time with both, I recommend Git. It’s a touch more complex, but the way it handles concepts like branches just make much more sense in my mind. Personal choice though..
Coding without source control makes me feel sick, both for the fear of losing work and of doing work
That said, don’t use SVN (or heaven forbid, CVS)Let me repeat that. DO NOT USE SVN.. SVN is old and outdated. Merging, branching, all of that stuff I just raved about, basically doesn’t happen with an old-style non-distributed source control system like SVNI’m not arguing with you on this. Yes, you can do it, but it’s horrible and why even try?.
There are exceptions of course. SVN is arguably better for artists, since there’s no good way to merge changesets for binary assets like images, and SVN assumes only one person can work on any file at once. But there are ways around this; you can actually use an SVN repo for your assets and a git repo for your code, and get git to pretend to the SVN repo that it’s SVN. Needs a bit of experience to set up though. If you’re willing to pay, commercial solutions like Perforce and Plastic are pretty good at allowing artists and coders to work together on one repo in a distributed-style fashion. On large projects, a paid solution can really be invaluable.
Utilities and GUIs
For Git and Hg, if you don’t want to use the command line, GUIs like SourceTree make things a lot friendlieralthough you should still get familiar with the command line. It helps you to know what’s actually going on, and there are lots of strange little things you end up wanting to do which are more specific than a GUI can cater to.. Plus they generally install a version of your chosen source control software automatically so you kill two birds with one stone.
Commercial source control software generally comes with a GUI anyway, so if you’re paying, you shouldn’t have to worry about that.
As for where to store your repositories; Bitbucket is a great place for smaller projects you want to keep private. Repos are free for up to 5 team members. But be warned, repos can only be about 2Gb in size (and you’ll start getting warnings at 1Gb) and there’s no way to pay for more space. If you’re hitting that limit, you might want to consider setting up your own server. GitHub has similar limits but the other way around – public projects are free (i.e. anyone can pull, although only authorised members can commit) and repos can again only go up to about 1Gb, paid or not.
Source Control with Unity
There are a couple of things you’ll need to do to get Unity to work nicely with source control. Firstly, go to Edit > Project Settings > Editor and switch Version Control Mode to Visible Meta Files just in case. Then change Asset Serialization to Force Text. Finally, you’ll want to create a text file called .gitignore (no .txt or anything on the end, just “.gitignore”) in your project root folder. This tells Git what not to include in the repository. If you include things like the Library folder, you’ll fill your repo up with useless crap in no time. You’ll also want to exclude any builds you do – I always build into a folder called Bin, and set git to ignore that folder. My default .gitignore file is as follows:
# =============== # # Unity generated # # =============== # /[Ll]ibrary/ /[Tt]emp/ /[Oo]bj/ /[Uu]nity[Gg]enerated/ # ===================================== # # Visual Studio / MonoDevelop generated # # ===================================== # ExportedObj/ *.svd *.userprefs *.csproj *.pidb *.suo *.sln *.user *.unityproj *.booproj # ============ # # OS generated # # ============ # .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes Icon ehthumbs.db Thumbs.db Thumbs.db.meta # ===== # # Other # # ===== # *.unitypackage /[Bb]in/
You may want to exlude binary files such as *.psd, *.png etc. You’ll also want to keep on top of your .gitignore file as you develop – you’ll often find that you want to exclude one file or another for various reasons. Note that it can be difficult to strip out unwanted files from a repo after they’re added, so try to think ahead about such things. That said, there’s a useful utility to help with such things, but it should be treated as a last resort compared to just planning what to ignore.
Start using source control now.
No, seriously, now. I’m not joking around here.
Footnotes [ + ]
|1.||↑||or rather, in the footnotes – but if you read the footnotes you’ll already know that, and if you don’t then you’re not reading this either.|
|2.||↑||Actually, it should be sunscreen.|
|3.||↑||or, at least, you’ve removed one source of scary logistical messes.|
|4.||↑||in theory anyway – in reality you main branch will still break sometimes unless you’ve got impeccable project management!|
|5.||↑||Having spent lots of time with both, I recommend Git. It’s a touch more complex, but the way it handles concepts like branches just make much more sense in my mind. Personal choice though.|
|6.||↑||Let me repeat that. DO NOT USE SVN.|
|7.||↑||I’m not arguing with you on this. Yes, you can do it, but it’s horrible and why even try?|
|8.||↑||although you should still get familiar with the command line. It helps you to know what’s actually going on, and there are lots of strange little things you end up wanting to do which are more specific than a GUI can cater to.|