views:

6020

answers:

22

Inspired by Git for beginners: The definitive practical guide.

This is a compilation of information on using Mercurial for beginners for practical use.

Beginner - a programmer who has touched source control without understanding it very well.

Practical - covering situations that the majority of users often encounter - creating a repository, branching, merging, pulling/pushing from/to a remote repository, etc.

Notes:

  • Explain how to get something done rather than how something is implemented.
  • Deal with one question per answer.
  • Answer clearly and as concisely as possible.
  • Edit/extend an existing answer rather than create a new answer on the same topic.
  • Please provide a link to the the Mercurial wiki or the HG Book for people who want to learn more.

Questions:

Installation/Setup

Working with the code

Tagging, branching, releases, baselines

Other

Other Mercurial references

+4  A: 

How do you create a new project/repository?

$ hg init my-repository
+2  A: 

How do you branch?

$ hg clone original-repository my-branch

or

$ hg branch my-branch
This is the heavyweight way that git people always make fun of Mercurial people for recommending. A lighter, more familiar way to beginners would be `hg branch my-branch`
Steve Losh
You must note, that these are two completely different operations.
stepancheg
I found this guide that could be helpful for branching in Mercurial: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
GoodEnough
For lightweight branches in hg that are not permanent(as the hg branch) use the mercurial bookmarks extension
phq
The article linked by GoodEnough provides another lightweight method using bookmarks. Seems pretty good for changes that aren't significant to deserve their own branch
Casebash
+2  A: 

How do you merge branches?

$ cd repository-where-i-want-to merge
$ hg pull branch-i-want-to-merge
$ hg merge # if necessary
Just "hg update" does not merge.
stepancheg
+9  A: 

How do you configure it to ignore files?

Ignore is configured in a normal text file called .hgignore in the root of your repository. Add it just like a normal file with:

hg add .hgignore

There are two syntax options available for file matching, glob and regexp. glob is unix-like filename expansion and regexp is regular expressions. You activate each by adding syntax: glob or syntax: regexp on a line by itself. All lines following that will use that syntax, until the next syntax marker. You can have as many syntax markers as you want. The default syntax is regexp, so if you only use regexp you don't need any syntax marker.

You can add comments with #

Example:

# python temporary files
syntax: glob
*.pyc

#editor autosaves
*~

# temporary data
syntax: regexp
temp

Ignore only applies to unmanaged files (i.e. files that are not already checked in). To ignore files that are under version control, you can use the switches -I and -X.

Joakim Lundborg
It could be useful to mention that if you manually `hg add` ignored files Mercurial will track them. For example, if you have a bunch of files like `deploy-test.conf`, `deploy-production.conf`, etc and don't want to version them (they might have passwords in them) but you *do* want to version `deploy-template.conf` you can just ignore `deploy*` and manually add `deploy-templace.conf`.
Steve Losh
+2  A: 

How do you 'mark' 'tag' or 'release' a particular set of revisions for a particular set of files so you can always pull that one later?

$ hg tag my-tag

You can also clone your repository to create a special tag repository.

$ hg clone working-repository my-tag-repository
Why not `hg tag my-tag`?
Steve Losh
+3  A: 

How do you see what's uncommitted, or the status of your current codebase?

To see a list of files that have been changed:

$ hg status

This will print each file that has been changed along with its status, which can include:

  • M - Modified. The file has been changed and the changes have not been committed.
  • A - Added. The file was not tracked before, but if you commit Mercurial will begin tracking it.
  • R - Removed. The file was tracked before, but if you commit Mercurial will cease tracking it in this and future commits.
  • ? - Unknown. The file is not currently tracked by Mercurial. Committing will have no effect on it unless you use hg add to add it.
  • ! - Missing. The file was tracked but Mercurial cannot find it in the working copy.

To see the changes that have actually been made to the files:

$ hg diff
Steve Losh
+2  A: 

How to install Mercurial?

Please edit nicely if you have installed from source on Linux, or used the Windows installers.

Mac OS X 10.4 (Tiger), 10.5 (Leopard)

Use Python's easy_install (with Setuptools):

sudo easy_install mercurial

This finds the latest version (1.3.1 at time of writing) and installs at:

/Library/Frameworks/Python.framework/Versions/2.6/bin/

With Python 2.6 this also gets around the Mercurial OS X installer package (at 1.2.1 as of July 26 2009) complaining that it needs Python 2.5. From the documentation, it appears that Fink and Macports install version 1.2.

Linux

Most of the explicit Linux packages appear to lag behind the current version, so use easy_install (as above) or download the Mercurial tarball, extract the archive, change to the mercurial directory, and run:

$ make
$ sudo make install    # do a system-wide install
$ hg debuginstall      # sanity check
$ hg                   # see help

(from Introducing Mercurial, a distributed version control system)

Windows

There is a binary package of the latest version of Mercurial. TortoiseHg includes MS-Explorer integration, and cygwin can also install Mercurial.

Alternatively (instructions too lengthy so linked here), you can build an optimised or pure Python version of Mercurial from source.

Dave Everitt
To build mercurial from source, one will need the Python headers. Install python-dev or python-devel for those using package-oriented distributions.
NicDumZ
A: 

How do you get the latest code?

hg pull origin-repository

to pull the latest code from origin-repository. (This does not update the working directory)

hg update

to update the working directory.

hg pull -u origin-repository

to perform both a pull and an update at once.

Laz
The origin is recorded in `.hg/hgrc` when you do a clone, so you don't have to specify it when you pull/push. You can add more paths to the `[paths]` section in `.hg/hgrc` if you want.
Martin Geisler
+4  A: 

How do I interface with Subversion?

There are three ways:


The convert extension will clone an existing Subversion repository into a Mercurial one. It comes with Mercurial. It works roughly like this:

hg convert <Subversion URL or directory> <path to new Mercurial repository>

For example this will grab the trunk of the SixApart memcached repository.

hg convert http://code.sixapart.com/svn/memcached/trunk

The extension can incrementally bring in new revisions from a Subversion repository into the Mercurial one (a little like pull). However it does not support taking Mercurial revisions and sending them back to Subversion (no push). [XXX: Correct this if it is wrong].


The hgsubversion extension. It is in many ways the most sophisticated solution as it uses the Subversion API to communicate with the Subversion repository. It aims to become the hg-svn bridge. It allow full round-tripping of revisions (full clone, pull, and push), However as of this writing [XXX: Amend this if/when it becomes incorrect] it is still in development and there are not yet official releases. As a consequence it works with only the most up-to-date Mercurial (1.3 as of this writing).

  • It maps tags and branches (preceding all tags with tags/ to distinguish them from equivalently named branches).
  • It maintains a special branch closed-branches for closing off branches which are removed in Subversion.
  • It requires that the Subversion repository be laid out according to the convention of trunk/branches/tags.
  • The command set is typically hg svn <subcommand> though it aims at being integrated to the point that you don't need the 'svn' part (i.e. it wants to treat a Subversion clone as much as possible like any other Mercurial repository).;

It works like this:

clone:

hg svnclone <Subversion URL>

OR (only for svn:// URLs)

hg clone <svn:// URL>

pull:

hg svn pull

push:

hg svn push

incoming:

hg svn incoming

outgoing:

hg svn outgoing

Checking out an entire repository:

hg svnclone http://code.sixapart.com/svn/memcached


The hgsvn utility (bitbucket tree). Up until recently this only let you clone and pull a Subversion repository, but as of hgsvn 0.1.7 it supports push. [I do not know how well it does push. Anyone with more experience should update this.] It has the following notable features:

  • It generates a Mercurial tag for every SVN tag.
  • It puts a local tag on every changeset to mark its SVN revision.
  • It puts every Mercurial revision on a named branch named after its SVN branch. For example branches/some-feature would be like hg branch some-feature. It puts the trunk on trunk (i.e. nothing is on the Mercurial default branch, unless the user explicitly switches to it.)
  • It will try to identify branches and tags, and create them but if it can't it just skips them. This is handy when the Subversion repository is not following the conventional trunk/branches/tags layout.

It works like this:

clone:

hgimportsvn <Subversion URL>

pull:

hgpullsvn

push:

hgpushsvn

incoming:

hgpullsvn -n

outgoing:

hgpushsvn -n

Checking out an entire repository:

hgimportsvn http://code.sixapart.com/svn/memcached

Checking out just the trunk:

hgimportsvn http://code.sixapart.com/svn/memcached/trunk
quark
I just used `hg convert` and it really takes a long time when you have an svn repository with many commits. Setting up a local repository with `svnsync` helps a lot speeding things up – especially when you need to do it several times, because you had some wrong options in your convert command.
Debilski
I think all these methods are faster if you have a local copy of the SVN repository. But you can't always get at the full repository right? I thought `svnsync` needs to access the actual files of the repository, not just the URL.
quark
A: 

How do you check out code?

hg clone [OPTION]... SOURCE [DEST]

Where option can be:

 -U --noupdate      the clone will only contain a repository (no working copy)
 -r --rev           a changeset you would like to have after cloning
    --pull          use pull protocol to copy metadata
    --uncompressed  use uncompressed transfer (fast over LAN)
 -e --ssh           specify ssh command to use
    --remotecmd     specify hg command to run on the remote side

Where source is the source of the original files located in the repository, where it can be a remote url or a file system directory. e.g:

And destination is where the source code will be located in your local filesystem.

jpartogi
A: 

How do you commit changes?

$ hg commit -m "Commit message"
NawaMan
A: 

How do you commit changes?

Invoke this command from the current local* mercurial repository

hg commit [OPTION]... [FILE]...

aliases: ci

  • A local mercurial repository has .hg inside the current directory

Where option can be:

 -A --addremove     mark new/missing files as added/removed before committing
    --close-branch  mark a branch as closed, hiding it from the branch list
 -I --include       include names matching the given patterns
 -X --exclude       exclude names matching the given patterns
 -m --message       use <text> as commit message
 -l --logfile       read commit message from <file>
 -d --date          record datecode as commit date
 -u --user          record user as committer

An example command would be:

hg commit -m "added readme" README

NOTES:

  • If a list of files is omitted, all changes reported by "hg status" will be committed.
  • If you are committing the result of a merge, do not provide any file names or -I/-X filters.
  • If no commit message is specified, the configured editor is started to prompt you for a message.
jpartogi
+1  A: 

How do you compare two revisions of a file, or your current file and a previous revision?

Both use hg diff. When hg diff is used all changes in the working copy and the tip (the latest commit) is displayed.

For "How do you compare two revisions of a file?"

$ hg diff -r{rev1} -r{rev2} {file.code}

The above command will show different between rev1 and rev2 of "file.code".

For "How do you compare your current file and a previous revision?"

$ hg diff {file.code}

The above command will show different between the current version of "file.code" and the lastest revision (the lastest commited).

:D

NawaMan
+2  A: 

How to set up Mercurial?

Mercurial stores its configuration information in ~/.hgrc on *nix systems and in %UserProfile%\mercurial.ini on Windows systems. (%UserProfile% is typically "C:\Documents and Settings\[username]\" on Windows 2000 or Windows XP systems, and typically C:\Users\[username]\ on Windows Vista and Windows 7 systems.)

As a starting point, you should set your Mercurial username by placing the following in your .hgrc or mercurial.ini:

# This is a Mercurial configuration file.
[ui]
username = Firstname Lastname <[email protected]>

TortoiseHg users on Windows systems can alternatively run hgtk userconfig

See also "Creating a Mercurial configuration file" in chapter 2 of "Mercurial: The Definitive Guide."

las3rjock
+1  A: 

Good GUI/IDE plugin for Mercurial?

GUI

  • TortoiseHg for just about any OS. Includes Windows Explorer integration. It also works in Linux and a few other OS:es including Max OS X. It has a somewhat clunky interface and is a little awkard to use at first, but it is very complete and powerful.
  • Murky runs on Mac OS X 10.5 or later. Murky is good for exploring the repository and basic commands, but you will need to know how to use the command line as well.
  • MacHg is a nice Mac OS X Gui that has a little more functionality and polish than Murky, but you will still need the command line with it as well.

Plugins

Marcus Lindblom
A: 

How do you see what changes will be sent to the upstream repository when you push?

Use hg outgoing to get the list of changesets that will be set to the default repository:

$ hg outgoing

To get the actual code changes, use -p (--patch). This will output each changeset in full:

$ hg outgoing -p
robotadam
A: 

How do you see the history of revisions to a file or repository?

To show the revision history of entire repository or files

$ hg log {file(s)}

or

$ hg history {file(s)}

And to see the list in reverse order

$ hg log -r:
David Sykes
+7  A: 

I may be biased ;) but I like Joel Spolsky's new tutorial, hginit.com

adambox
DaveE
I like that you can use it on your machine alone with no other server if it's purely personal stuff and you have some backup scheme going to make sure you don't lose it. And in a distributed setup (with or without "central" repo) you get automatic backups on other machines! Joel's tutorial gets you up and running for the personal case super-fast
adambox
A: 

How do you remove a file from the repository?

To remove a file from the repository, and have it deleted on the next commit:

$ hg remove {file(s)}

To remove a file from the repository, but not have it deleted

$ hg remove -Af {file(s)}

or from Mercurial 1.3

$ hg forget {file(s)}
David Sykes
A: 

How do you revert a Changeset?

A couple of options available

Easy Way (backout a single change set)

$ hg backout -m 'back out second change' tip
reverting myfile
changeset 2:01adc4672142 backs out changeset 1:7e341ee3be7a
$ cat myfile
first change

Hard Way (manually diff and apply)

Step 1: Create a patch file to revert what changed between revision 107 and 108:

hg diff -r107 -r108 --reverse  > revert-change.patch

(alternately, hg diff -r108 -r107 with no --reverse will do the same thing)

Step 2: Apply the patch file:

patch -p1 < revert-change.patch

Some of the diff may fail to apply, for example:

Hunk #3 FAILED at 517.
1 out of 3 hunks FAILED -- saving rejects to file 'foo/bar.c.rej'

The .rej file will contain the contents of the diff that failed to apply, you'll need to have a look.

slf
Isn't this what `hg backout` is for?
Wim Coenen
Yes, however hg backout only supports a single changeset id to backout. Definitely should be mentioned, I will update accordingly
slf
A: 

How do you go back to a previous version of the code?

From this question

$ hg update [-r REV]

@van: If later you commit, you will effectively create a new branch. Then you might continue working only on this branch or eventually merge the existing one into it.

David Sykes
A: 

How do you extract a patch from a specific changeset?

$ hg export -o patchfile changeset
David Sykes