A Complete Guide to Source Control

This guide is divided into three primary parts: 1. What is Source Control and Why is it Important? 2. Important Terms and Commands 3. Suggested Workflows 4. Which GUI is right for me? 5. The Git Terminal

What is Source Control and Why is it Important?

Source Control, otherwise known as Version Source Control (VSC) describes a series of methodologies and softwares used to increase workflow productivity, safeguard progress, store files, and share work across multiple users and workstations. There are many VSC's and some of the one's worth being familiar with, at least by name, are Git, Subversion, Perforce, and Mercurial.

Using a VSC is important to all kinds of developers, from artists and programmers to composers and designers. Almost all the work we do as game makers is collaborative, and so having a way to easily trade files is important. But we could just use Google Drive or Dropbox for that. However, the additional functionality to look back on changes to files, who wrote (or broke) what, and the ability to retrieve a comprehensive history of files is what begins to set a VSC above traditional file methods. VSC's also, in many cases, allow multiple users to edit a file at the same time by merging the changes together later.

Important Terms and Commands

For the rest of this guide, I'll be talking in terms of Github or Git, which is a single VSC among many. Many of the ideas of Git are shared among others, so this should simplify this tutorial without causing too much confusion.

We will be using these terms for the rest of the guide, so familiarize yourself with them. Additionally, these are terms used across the CS industry, so if you want to work pretty much anywhere which uses a VSC, now is the time to learn!

Some important terms to learn with Git are:


Suggested Workflows

It will be up to each project to decide which workflow is best for it. Almost always, an agreed-upon structure on each team is critical, but the exact nature of that structure is up to the needs and proficiencies of those involved. I have worked on projects where we pulled hundreds of branches and reviewed people's code before it could merge, and I've worked on R&D projects where the only thing I ever did was commit straight into the master without any branching at all. Each project is different, but here are some heuristics that have served me well:

Branch and Merge, With Leads Committing to Master

In this tactic, whenever anyone wants to do anything: add a feature, edit some code, upload art or music, delete a design document --they should pull a branch, commit changes into that branch, and then when they're ready to join everything back in, they should update that branch from the master branch and then submit a pull request (merge). Team leads, where appropriate, or the director, should then approve these. Usually these people can also commit straight into master, without cutting a branch, which will save the team time.

Code Review

Code Reviewing is the practice of having leads, usually engineers, look over peoples' code and suggesting fixes, changes, and bringing up possible bugs, edge cases, etc... that the original programmer may not have considered. Code Reviewers are usually skilled and experienced, but it may also be useful to have young programmers code review each others; even at a early stage, different programmers think differently and so this can be fruitful. The easiest way to code review is to look over commit history or check out pull requests (merges) from branches before approval.

Stash, Pull, Pop, Push

There are many kinds of conflicts in VSC; conflicts usually occur when two different people change the same file at once and then try to reconcile those separate changes together. Text-file based conflicts are simple and can usually be resolved by simply adding all of the changes together or else by cherry-picking the changes (either by hand or with a Diff Merge tool). However, binary files --like Unity's scenes or prefabs-- require a little more finesse. For these, we want to avoid conflicts altogether, as resolving them is much harder. Binary conflicts are much more common when branching and merging, especially when members forget to update from master before they submit a pull request, which is why lots of teams opt to commit straight into master. This will prevent many types of binary conflicts, but isn't a veyr safe practice, as now anybody at all can 'corrupt' or break the master code. Instead, let's talk about Stash, Pull, Pop, and Push.

The first command here, Stash, will be used to store our current changes so they don't go away. Next, we will Pull; this brings all recent commit changes from our branch into our working, local repository. Next, we will Pop, which restores our stashed changes. In some GUI's, you will then have to stage all these files next. After that, we can commit and Push. This accomplishes the task of adding our work to the remote repository but is a drastically different, much safer workflow than commit straight into master. This can be done in any branch and combined with earlier mentioned workflows for even greater productivity.

Which GUI is right for me?

For beginners, I'm going to recommend Github for Desktop. This has your basic branching, push, pull, sync, commit, and merge commands built in and is really simple for first-timers. Quickly, you'll outgrow this, especially if you're a programmer.

For the brave, I think you're up for GitKraken, a javascript-based GUI that has all the basic commands plus easy buttons for stashing, poping, staging and unstaging changes! GitKraken also has an nice branching and merging visualizer along the side, but if you find yourself truly in need of this vis, GitKraken maxes out at 6 branches at a time.

For the braver, SourceTree is an industry standard, widely-used, incredibly-competent, smooth, sexy GUI. Pretty much every professional I know that doesn't use the Terminal uses SourceTree. Honestly, the only reason I'm not recommending it sooner is that the UI is a little busy for noobs.

Finally, if you're really feeling underpowered by these GUIs or desirous of a new challenge, check out ...

The Git Terminal

So you think you can dance? Seriously, the Git Terminal isn't that bad. Sorry I've been creating so much anticipation. The Git Terminal is great because it has all the commands we've gone over (most by name) and tons of other handing ones --like looking up logs or easily accessing git blames, even handling messy merges are often easier in the Terminal. Let's go over some Git Terminal commands:

If you're looking for more tips and tricks, check out https://github.com/git-tips/tips and http://nuclearsquid.com/writings/git-tricks-tips-workflows/ especially the sections on .gitignore and .gitattributes, which we haven't gone over at all!

Large File Storage

If you're on Mac, this is super easy. If not, sorry. First, install Homebrew if you don't already have it. The terminal command is:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Next, let's brew us up some lfs with the command:

brew install git-lfs

After this runs, you can ensure it worked by seeing if lfs initalized. Try the command:

git lfs install

Finally, if you want to use LFS on a file (that is more than 100MBs), then simply track it before you add and commit it. Use the command:

<<<<<<< HEAD git lfs track "[file-name]"