Mon 23 Jul 2012
Mercurial is a free, distributed source control versioning tool, similar to git or bazaar. Some might even compare it CVS or Subversion (SVN), although those are not distributed versioning systems. The Python programming core development team chose to switch to Mercurial from SVN a couple years ago and many other high profile 3rd party Python projects have too. There are many projects that are using Git as well. In this tutorial, we will go through the basics of using Mercurial. If you need more in depth information, there is a pretty exhaustive guide and an online Mercurial book that should fulfill your needs.
First of all, you’ll probably need to install Mercurial. Follow the directions on their website. It’s really easy to do. Now we’re ready to use it. If you installed it correctly, you should be able to open a terminal (i.e. command line) window and create a new repository or check one out. You’ll learn how to do both in this article. We’ll start with creating our own repository from scratch.
To begin, create a new folder somewhere on your machine. We’ll use “C:\repo” (Windows). Your path can vary, of course. Then in your terminal, change directory into the repo folder. Now type the following:
Wait! What’s that “hg” bit all about? Well, “hg” is the chemical symbol for Mercury. You will always use the “hg” command to interact with your Mercurial repositories (aka: repos). Your folder should now have a .hg folder in it which will contain an empty store folder, a changelog file (some kind of dummy file) and a requires file. For the most part, you don’t really care what’s in the .hg folder as it’s whole point of being there is to store repo information so that Mercurial can revert to previous revisions and keep track of history.
Of course a repository isn’t very useful if it’s empty, so let’s put a file in it. In fact, we’ll use the silly math package from a previous article so that we’ll have several files and a folder. Now type hg status (or “hg st”). you should see something like this:
This is a list of files that we could potentially add to the repo. The question marks indicate that they have NOT been added. You’ll notice that I accidentally left some Wingware IDE files in the archive, the ones with the extensions wpr or wpu. Now if you have Wing, then these are handy. If you don’t, then you won’t care. Let’s say we have Wing but we don’t want to share our Wing config files. We need a way to exclude them from the repository.
Excluding Files from Mercurial
Mercurial includes a special file called .hgignore that we put in our root directory that Mercurial will look at for directions on what to ignore. You can use either regular expressions or glob (or you can alternate) to tell Mercurial what to ignore. On Windows, you’ll probably have to create the file with Notepad or a similar text editor as Windows Explorer is stupid and won’t let you name a file that begins with a period. Anyway, to set the type (glob or regex), you preface it with the word “syntax:”. Here’s an example to make it especially clear:
# use glob syntax.
This tells Mercurial to ignore any files with the following extensions: pyc, wpr or wpu. It is also using the glob syntax. If you re-run the hg st command, you should no longer see those Wing files listed any more. Now we’re ready to actually add files to the repo!
How to Add Files / Directories to Your Mercurial Repository
Adding files to Mercurial is really easy too. All you have to do is type: hg add. Here’s what I get when I run it:
Note the capital “A” in front of each item. That means it’s been added, but not committed to the repository. If it’s not committed, then it’s not saved in your version control yet. We should probably do that! All you have to do is enter hg commit or hg com and it will open a text editor for you to enter a comment about your commit. Well, actually that’s what should happen, but unless you have set up a config file you’ll probably get this mysterious message: commit no username supplied. Here’s where things get interesting. You need to create a config file for Mercurial.
How to Create a Mercurial Config File
Mercurial looks in several places for the config file. Here’s the order listed in their documentation:
Note that if you do a per repo config file (the first example), the hgrc file does NOT begin with a period. Otherwise you create a system wide config when you make the one WITH the period and you place it in the specified location above (or you create a Mercurial.ini file). We’ll create a simple repo config file and put it in our .hg folder. Here’s is some example contents:
username = Mike Driscoll <firstname.lastname@example.org>
Now if you save that and retry the commit command, it should work. On Windows, it will pop up a Notepad instance where you can write a brief comment about what you’re doing. If you don’t put something in there, then the commit will abort and you won’t save anything to the repo. Once you’ve committed it though, you can run hg st again and it shouldn’t return anything. Now whenever you edit a file in the repo, you can run hg st and you’ll see a list of all changed files. Just commit them to add the changes. What if you want to check out someone else’s code? I’m glad you asked. We’re covering that next!
How to Check Out a Mercurial Repository
Let’s say we want to check out my old wxPython music player project from bitbucket. To do that, you would type the following:
hg clone https://bitbucket.org/driscollis/mamba
This will create a mamba folder on your hard drive wherever you currently are in the file system. So if you have changed directories to your Desktop, that’s where the folder will go. Note the keyword clone followed by a URL. Here’s another example:
hg clone http://hg.python.org/cpython
This is how you checkout the Python programming language if you want to help with its development. If you’re a Windows user and you want more info, you can read more about that here. This is an example of checking out a shared repository. It may change before you upload your changes. So you should always do a pull to make sure you have the latest copy before you push your changes back to the shared repo. Here’s what I do when I want to update my local Python repository:
pulling from http://hg.python.org/cpython
searching for changes
adding file changes
added 58 changesets with 109 changes to 36 files
(run 'hg update' to get a working copy)
654 files updated, 0 files merged, 276 files removed, 0 files unresolved
So when you pull down changes, you have to do an update to update your local repository. Then when you want to send your changes back to the server repository, you do an hg push. Most of the time, it will ask you to enter a username and password or you can set up the username in your config file and then you’ll just have to enter a password. Some repositories require credentials for pull requests too, but you don’t see that very often. You can also use hg update –rev to specify which revision to update to. Use in conjunction with the log command to figure out what revisions there are.
Creating a Patch with Mercurial
Often you’re not allowed to contribute to an open source project until you’ve earned the privilege, so instead you have to create patches instead. Fortunately, Mercurial makes creating a patch super easy! Just clone (or pull the latest changes) the repository and edit the file(s) you need to. Then do this:
hg diff > example.patch
You should probably name the patch after the file you changed, but this is an example after all. If you submit multiple patches of the same thing over the course of fixing a bug, you’ll probably want to rename each patch by adding an incrementing number to the end so it’s easy to tell which is the latest patch. You can read more about submitting patches to Python here.
Other Odds and Ends
There are several other commands that we just didn’t have time to cover. Probably one of the most important to know about is merge, which allows you to merge two repositories together. You should read their documentation for more on that. Here’s a list of the typical commands you’ll see most often used, which you can get by typing just hg:
Mercurial Distributed SCM
add add the specified files on the next commit
annotate show changeset information by line for each file
clone make a copy of an existing repository
commit commit the specified files or all outstanding changes
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
init create a new repository in the given directory
log show revision history of entire repository or files
merge merge working directory with another revision
phase set or show the current phase name
pull pull changes from the specified source
push push changes to the specified destination
remove remove the specified files on the next commit
serve start stand-alone webserver
status show changed files in the working directory
summary summarize working directory state
update update working directory (or switch revisions)
use "hg help" for the full list of commands or "hg -v" for details
Now you should know enough to start using Mercurial for your own work. It’s an excellent way to store your code and go back to previous revisions. Mercurial also makes collaboration easier. There are command-line tools for it and the ever popular tortoise GUI for those of you who like to click. Good luck!