There are 2 main GUI clients for it on Windows, SourceTree and TortoiseHg. First has been my personal favorite for a number of years but recently I have fallen out of love with it - the GUI changes made by Atlassian I personally don't find appealing and worse, some features had to be removed because of it. TortoiseHg even seems more powerful, and I've found some features missing in SourceTree (like the ability to compact unpublished history between selected changesets), but the style of its GUI is not really appealing to me.

More importantly, to be able to actually use these options users have to first understand what these commands do and have them memorized to the point where it's instinctive to use them in everyday situations. This comes back to command line, because these commands are best learned and explored where they have originally been conceived - in the command line. Additional options cannot be provided in the GUI, and while GUI seems quicker at first, the command line alternative, styled properly, can be just as appealing.

 

Proper installation:

This whole article is based on Windows usage. You have a couple of options:

1. Download only the executable from the Mercurial web site: this is fine and will give you the latest version. However, there is no GUI with it.

2. Download SourceTree and use Hg from the terminal that comes with it. It does not add the path to hg executable to the Path system variable, so you have to do it manually. Also, you will not get the most recent version, depending on which version of ST you have installed. The best version of ST for Windows, in my opinion, is 1.7.0.3, but it comes with an outdated version of hg. You can tell it to use the "System Mercurial", whatever other installation you have, but then some things won't work (like hgflow) without manual fiddling.

Update (mid-2017): I can no longer recommend SourceTree as a useful tool. Atlasssian has been systematically destroying the tool starting from interface to functionality and forums are full of people complaining about the changes and bugs. The old, good version (1.7 on Windows) has a security bug so it is not recommended. This guide should be a big help in growing out Source Tree. 

3. Download TortoiseHg. It is useful with a Visual Studio extension that I will explain below. I really haven't used it much because of the archaic interface, but it has its following.

For beginners I would actually recommend both (2) and (3), ST for everyday use and THg for integration with Visual Studio. To check which hg you have installed, type in: where hg and you will get a path to hg executable. If you don't get anything you need to add it to your Path.

If you use Visual Studio in you development, which you should, you may want to have an extension for it which helps a bit with Hg repositories. There are a couple of options, but the best one is VisualHg2, as here. This version actually looks good. I would recommend opening a small window with status and docking it in a corner: it shows you which files are changed and provides some common options in context menu. However, it relies on you having installed THg previously, thus the recommendation, and all the operations chosen from VS menu will be diverted to it.

Besides graphical tools, for learning it is best to use the command line. I am also not a fan of the cmd console, so I strongly recommend installing a terminal emulator such as ConEmu. That is one of the more useful free tools you can install. Highlights include: "knowing" if you want to select a line or a square space, automatic copy, allowing paste with Ctrl+V, multiple tabs split to sides and bottom, user themes. Just install it and select the default theme, with Consolas 11pt font, and it will look and work great. You also want it integrated in the Right-Click context menu, which it isn't by default. You do that by going into: Settings > Integration and clicking Register on the top option.

Here is how I use these tools. I open a VS project and Right-Click on the Solution > Open Folder in File Explorer. This opens the folder where the project is. There I Right-Click and chose ConEmu here and I can command line from there really quickly. All the other external tools are optional, but I still use SourceTree sometimes.

 

Where to learn it:

It is best to learn from daily usage of these tools once you get the basic concepts. For basic concepts, there are 3 authoritative resources: http://hginit.com/ for complete beginners, this book: http://hgbook.red-bean.com/ which will tell you almost everything you need to know for the start, and you also need to understand branching. Once you have that, you're not missing out, even if the book is pretty old. After the basic concepts, it's pretty much StackOverflowing and Googling when you need something, you know the drill.

 

On to the actual content, what do I do next:

You set up all options in mercurial.ini, which is found in your %UserProfile% folder. Once you make changes, you don't have to restart anything or load anything, they will be used on the next command run. The file is separated in sections, where each section is determined by a heading like this [extensions].

So, let's walk through all the extensions I use:

extdiff=

This is critical. It allows you to specify which GUI tool to use for merging conflicting code files. I would personally recommend CodeCompare, look around the site for tutorials about setting it up.

shelve=

Shelving takes files that hg status reports as not clean, saves the modifications to a bundle (a shelved change), and reverts the files so that their state in the working directory becomes clean.

To restore these changes to the working directory, use hg unshelve; this will work even if you switch to a different commit.

Let's say you are working on a specific feature, but you don't know exactly how to go about it. You try one solution, but you bump into a wall. Now the other solution seems much more appealing. Do you remove all the changes in your code, risking to have to redo them again? Do you commit and this becomes a permanent part of repo history, potentially confusing your teammates? No, you do a shelve operation. This feature for some reason wouldn't work in SourceTree (at least for me at the time of writing!) and it is so nice that it is worth exploring the command line for.


If you're finding this article helpful, consider our asset Dialogical on the Unity Asset store for your game dialogues.


color=

This colorizes the output of most commonly used commands, really handy with diff and status. Use this one, it makes things really readable.

purge=

This cleans up all the files in the repo that Hg doesn't know about (haven't been added to tracking yet). This tends to be really useful in everyday work.

churn=

This command will display a histogram representing the number of changed lines or revisions, grouped according to the given template. Statistics are based on the number of changed lines, or alternatively the number of matching revisions if the --changesets option is specified.

This is one is fancy but optional.

hgext.mq =

Mercurial Queues are critical when working with patches. They are explained in detail in the book I recommended above, and are a bit advanced but useful when you need them. You can't do this with the GUI.

rebase =

This is a history editing operation, which means it's advanced (and evil). You can certainly create a mess with it, but you can for example join a couple latest commits before pushing them, which is a common use case. It also serves as a base for some other commands such as hgflow and histedit, which automate a number of steps for specific use cases, so I would recommend them instead for these.

hgflow=C:\Program Files (x86)\Atlassian\SourceTree\extras\hgext\hgflow\hgflow.py

HgFlow is an extension that implements gitflow. Let me first say that for GameDev this branching strategy is a bit of an overkill. In fact, there are multitudes of articles online about alternatives to gitflow. What I think works best for GameDev is a variation of gitHub Flow. If you do decide to use it, it works out of the box in SourceTree, and if you want to use ST with latest Hg installation you supply the path to the latest hgflow.py file in your config file.

Side note: if you want to use the latest Hg with SourceTree 1.7.0.3 you'll have to get the latest hgflow.py to the path listed above and it will work with the GUI.

histedit=

What histedit does is:

  • 'pick' to [re]order a changeset
  • 'drop' to omit changeset
  • 'mess' to reword the changeset commit message
  • 'fold' to combine it with the preceding changeset
  • 'roll' like fold, but discarding this commit's description
  • 'edit' to edit this changeset

It is powerful, but you have to know working with editing history is no picnic. There are cases where you chose to do some of these things, and this is where knowledge of tools like this comes in handy. It is easy to do what you want to do: a default text editor will pop up and you will get a choice of what to do through it. 

mercurial_keyring=

Install it by following the instructions here, and you will have to type the password for a repo only once. This is critical when you push/pull a lot! The password is stored in your Windows Credentials Vault, so they are saved securely.

 

Aliases:

This is my favorite part, aliases make things so easy and quick, and allow for nice customization. Aliases are defined in their own header [alias], they start with the name of the alias followed by = and then the parameters that you'd normally supply to hg. If you start an alias with ! then that alias is instead a System command, and what follows you'd normally type in the shell you're executing the hg command from. This means the aliases you use may not be cross platform. You don't even have to type the whole command/alias every time, just the distinguishable part.

clean = !hg revert --all --no-backup && hg purge

Hg already has an alias clean that is a synonym for purge, but I decided to steal it. This creates no problems and "just works". This alias has 2 parts: first, it reverts all files to the state of the last commit; second, it erases all the files found not known to Hg. The commands are separated by && which means you'd normally do something like this in 2 steps. Also, note the no-backup option. This will really clean up the working directory, so you've been warned.

pushbranch = push --rev .

In Hg, as opposed to Git, you push all branches when you do a push. This may not be what you want (though it normally is). With this alias you just push the branch you're currently on.

slog = log -l 15 --template "\x1B[4m{pad('({rev})',6,' ',True)} \x1B[5m{node|short} \x1B[8;9m{word(0, '{date|isodate}')} {word(1, '{date|isodate}')} \x1B[6m=> {author|user} {ifcontains(rev, revset('.'), '\x1B[8;9m@', ':')} \x1B[7m{desc|firstline} \x1B[8;9m[{branch}]{if(tags, ' [{tags}]')}{if(bookmarks, ' [{bookmarks}]')}\n"

slog is my personal beast! It's a shorthand of short log. The original log command produces quite line-heavy output, so I prefer output like this:

Fancy, hmmm?

You would have to take a look in the templating mechanism to understand what this actually does, but the more confusing part are terminal codes starting with \x1B. This presumes you've enabled the color extension as explained before.  After the [ sign the code will determine the color. You can read more about terminal codes here.

This is probably my #1 favorite hg command now, and you limit the output like this hg slog -l 5. I have limited the output already with the -l 15 you can see above, but if you specify it in your command it will take precedence.

glog = log -l 15 -G --template "\x1B[4m({rev}) \x1B[5m{node|short} \x1B[8;9m{word(0, '{date|isodate}')} {word(1, '{date|isodate}')} \x1B[6m({author|user}) {ifcontains(rev, revset('.'), '\x1B[8;9m@', ':')} \x1B[7m{desc|firstline} \x1B[8;9m[{branch}]{if(tags, ' [{tags}]')}{if(bookmarks, ' [{bookmarks}]')}\n"

glog - the graphical log is even better:

You can also see "closed branches" displayed differently on the tree. This arguably replaces any need for a visual tool in most cases (depending on the complexity of your workflow). Another critical alias.

blame = annotate --user --number

A small optional alias that shows who actually changed which line of the supplied file. SourceTree has this option, but I find this really quick, if not necessarily frequently used.

noorig = !del /S/P *.orig

When you have merge conflicts you may leave .orig files laying around after you do the merge. This a shortcut on system command del, and it will prompt you for each individual file and search subdirectories. You would call it like hg noorig.

here = log -r .

Just a quick alias to show you the current commit you're working off of. You could also change it for here= slog -r . if you liked that compact output from before, but I don't see much point in this case.

plog = log --style=compact --patch -r .

As in patch-log. It shows the patch view of the last commit relative to the commit before it. The patch view is very useful, it shows differences very colorfully.

qlist = !echo \033[34m Series: | cmdcolor && hg qseries && echo \033[95m Applied: | cmdcolor && hg qapplied

To get this to work you need to download the small utility from here and place it in your Path. What it does is it allows for the same coloration we mentioned in the templating alias, but the cmd does not actually support that kind of coloration when output is printed to it. It does work, but the range of options is somewhat limited. Here is a list of colors with codes:

Beyond that, it simply joins the outputs of 2 commands used together commonly when working with patches.

upsafe = update --check

When changing the current working directory, unless the option --check is supplied it will try to carryover the unclean content into the new commit. This is seems somewhat out of line with Hg's "safety first" policy, because in Gamedev environments it can create a bit of havoc. It's better to just use hg ups to be safe and let Hg warn you if there are any outstanding changes.

fa = forget "set:added()"

As in forget-all. If you added a range of files by mistake, this is the quickest way to "un-add" them all.

stnm = status -X "**.meta"

Unity's .meta files are a bit annoying when you have to look at the file system. They also create some visual clutter when reviewing changes either in SourceTree or from command line. This is a quick shorthand to exclude the .meta files from the output of the status command.

gst = !hg status | PathToTree /s /c | cmdcolor

Now for the real kicker, graphical status. For this you would need my little utility downloaded from here and also the cmdcolor program mentioned before (optional). 

Instead of showing the linear list of files in the output of the status and building the tree in your head, why not let the computer display the tree? This is especially useful to us in GameDev because we tend to have somewhat deep hierarchies of folders. You can read the details about the utility on Bitbucket, so I won't repeat it here.

gstnm = !hg status -X "**.meta" | PathToTree /s /c | cmdcolor

This combines the outputs of the last 2 aliases: it omits the .meta files and builds the tree.

close = commit -m "Closed branch" --close-branch

When you do feature branches, at some point you'll - of course - want to merge them back into the original. If you don't close feature branches first, they will show in the output of hg heads and hg branches, This may not be what you want, so you have to manually close the branch, preferably before merging it back, by creating another commit with --close-branch option. This option is a shorthand for such biolerplate commit.

 

Bonus tip:

When you rename a file tracked by Hg, it needs to know it's the same file and not deletion + addition if you want to keep its history. This is determined by "similarity factor", if it's just the rename of the file it is 100% similar. However, when working with Unity it's never just a simple rename: if you rename the source file you have to rename the class too, because it would not work otherwise. SourceTree seems to be stuck at 100% similarity and I haven't seen the way to change that. You need to do something like hg addrem and the system should automatically use some similarity lower than 100%. To achieve that, you put in this alias:

[defaults]

addremove = --similarity 90

 
Conclusion:

I hope you have enjoyed this article and tried these commands. Reading about these things is really easy but in heat of development problems of this nature are really not welcome. That's why it's important to be properly prepared and practiced when it comes to these things, and have a standardized, reliable, understood workflow in your GameDev shop. 


If you're finding this article helpful, consider our asset Dialogical on the Unity Asset store for your game dialogues.