Dota 2 - Version control

Talking to dota 2 mod developers, or just software developers in general, you will often hear the words 'repositories', 'version control' and 'git'. The reason these are such popular topics is that version control is a very important topic within software development, and if you are working on a piece of software you SHOULD use it. In this article, I will try to clarify firstly what version control is, why you would want to use it, and how I have personaly set it up for dota 2. If you read it all the way to the end I might even give you some shameful stories about how I learnt most of this through trial and error.

Table of contents

  1. What is version control
  2. Why use version control
  3. Git
  4. How to use git
  5. Remotes
  6. Git clients
  7. How to set up a dota 2 mod repository
  8. Embarrasing stories

What is version control

The name already gives it away, but version control is a method to control.. well, your versions. A more useful description would be that version control is a way of tracking different versions and stages of development in your software. The term repository is used to describe a project that is managed by some kind of version control. You basically have a system in place that tracks any changes and makes sure that everyone working on the software can work on the same version of this software simultaneously. This usually means that you have a 'remote' server that has all files, and every time you or somebody else makes a change, this remote knows this and can distribute this version to other people working on the software. There are multiple methods to do version control, popular ones include Git, SVN and Mercurial. This article will focus on Git as it is in my opinion the most convenient method.

Why should you use version control

There are a lot of reasons so use version control, I will list the ones that I personally think are the most important:
I would also like to mention that there are no 'simple' reasons not to use version control. Some common misconseptions:

Git

Like mentioned before, this article will focus on the use of Git. So what is Git? Git is a method of version control where all collaborators have their own repository on their machine. Whenever they commit a change, only their repository is updated. Once the developer is happy with what he has he can push all changes he has made to the remote, so other collaborators can pull them. Git also allows for different branches, meaning that you can have two branches with different versions of your software active at the same time, and changes by developers are only applied to one branch. Branches can also be merged so that changes made in one branch are also applied in the other branch. A common example of this is software having a master branch and development branch. While developing the developers push to the development branch, once the software is at a major milestone they merge the development branch into the master branch, so that has only major milestone versions on it. Meanwhile the developers can continue working on the development branch again.

How to use Git

There are a lot of tutorials on git you can find on google, I will however give a summary of the core concepts here.
First of all commit every time you want to save your changes. A commit is basically a version of your software, you can always to back to your commits at a later point in time.
Pulling is the action of getting all commits for some branch from your remote. This way you also get your collaborator's changes.
On the other hand, pushing is the opposite of pulling. It pushes your commit history to the remote, so the other collaborators can get it. Remember: always pull before pushing!

Merge conflicts Even though Git keeps track of individual lines, you will have situations where multiple collaborators have changed the same lines. When pulling from the remote, git will automatically detect these so called 'merge conflicts' and ask you to resolve them. The basic way of resolving merge conflicts is to open the file that has the conflict. You will see some lines that basically look like this:
<<<<<<< HEAD
nine
=======
eight
>>>>>>> branch-a
Basically everything between '<<<<<<<HEAD' and '=====' is what you have for that line, everything between the '==========' line and the '>>>>>>>' line is what you pulled from the remote. Resolve the conflict by just removing everything except the code you want to keep. This can be your stuff, the stuff from the remote or even both! A fixed file could look like this (I chose to keep both):
nine
eight

Remotes

A remote is basically a remote location at which your software and its different versions are stored, and which are used to communicate versions to all collaborators of that piece of software. There are many different services providing remotes, though for dota 2 modding I would recommend using Git with one of these two services:

Git clients

There are three main methods of doing git:

How to set up a dota 2 mod repository

Setting up a dota 2 mod repository is not entirely trivial, as there two directories you want to include at diffent locations instead of creating your repository on just one directory. You could of course make a repository of your dota_ugc folder, but ideally you would like to have one repository per project instead of having to track changes to all of them in the same repository.

So here is my solution:
I made a directory somewhere on my harddrive, doesn't matter where, and called it 'Dota 2 Mods'. Inside this directory I made different directories for each mod I made, so I would have a Bomberman directory, Invoker Warfare directory, etc etc. So how do I get my mod files in here? The answer is symbolic links, or symlinks for short. A symlink is basically a reference to a different directory on your PC. This means that you can have the same directory at two locations in your file system. Changing the contents of this directory will affect the files in the directory at both locations.

How to make your dota 2 symlinks Inside your mod's folder open the command window by shift-rightclicking the folder (make sure you have no files selected) and pressing 'Open command window here'. Now just fill in the commands for each folder you want to include. I'll show you my commands, but keep in mind you might have to change the path to your directories:
mklink /j "Game" "D:\Program Files\Steam\steamapps\common\dota 2 beta\dota_ugc\game\dota_addons\bomberman" mklink /j "Content" "D:\Program Files\Steam\steamapps\common\dota 2 beta\dota_ugc\content\dota_addons\bomberman"
If you did it right you should now see a Game and Content directory inside your mod's directory! You can now just make a repository of that directory, and it should automatically also take the contents of your symbolically linked directories into account. An additional benefit of this method is that you can also put other things in your mod folder to be included in your version control. Personally I have a Documents directory in there too, storing all documents I have produced related to the mod.

Bonus hint: Make sure you add thumbnail_cache.bin to your gitignore. It prevents this useless file from bloating your repository.

Embarrassing stories

I am now going to share some embarrassing stories about how I messed up with version control in the hope that you will not make the same mistakes.