Difference between revisions of "Mercurial"

From Eigen
Jump to: navigation, search
Line 1: Line 1:
 
[[Category:Developer]]
 
[[Category:Developer]]
  
Mercurial howto.
+
[http://hg-scm.org/ Mercurial], also known as '''hg''', is the source-control management (SCM) tool that we use for Eigen.
 +
 
 +
== Installing Mercurial and finding documentation ==
 +
 
 +
* If you are using Windows or Mac, download it from [[http://hg-scm.org/downloads/|their website]].
 +
* If you are using Unix/Linux, just install Mercurial from your package manager.
 +
 
 +
If you want a graphical user interface, install Tortoise-Hg, but below in this page we will only be referring to the command-line interface.
 +
 
 +
Below in this page we explain some usual commands, but Mercurial has lots of documentation available on the Web:
 +
* http://www.selenic.com/mercurial/wiki/UnderstandingMercurial
 +
* http://www.selenic.com/mercurial/wiki/Tutorial
 +
* http://hginit.com
 +
== Basic usage ==
 +
 
 +
 
 +
===Getting the source===
 +
 
 +
Initial checkout:
 +
 
 +
  $ hg clone http://bitbucket.org/eigen/eigen
 +
 
 +
or if you have a write access to the repository you have two options:
 +
 
 +
  $ hg clone ssh://hg@bitbucket.org/eigen/eigen/        # See [http://bitbucket.org/help/using-ssh/] to setup ssh
 +
  $ hg clone https://login@bitbucket.org/eigen/eigen/  # password login
 +
 
 +
 
 +
After that, to update your checkout (get the new changes made to the repository):
 +
 
 +
  $ hg pull -u      # hg pull brings the changes into your store, and -u updates
 +
                    # your working directory to the latest revision.
 +
                    # 'hg pull -u' is the same as 'hg pull && hg update'.
 +
 
 +
==Configuring Mercurial==
 +
 
 +
Before using Mercurial to make Eigen changes/patches, please make sure that you have configured it as described in this section. To do so, edit (or create) your mercurial config file.
 +
* On Unix-like systems, the global config file is ~/.hgrc
 +
* On Windows systems, the global config file is Mercurial.ini in your home directory
 +
 
 +
Note that if you need a different mercurial config for another project, you can also use a per-clone config file: .hg/hgrc inside the clone directory. We recommend using the global config file unless you really know what you are doing.
 +
 
 +
Put these lines in the Mercurial config file:
 +
 
 +
<pre>
 +
[diff]
 +
git = 1
 +
showfunc = 1
 +
unified = 8
 +
 
 +
[defaults]
 +
commit = -v
 +
 
 +
[ui]
 +
username = Your Real Name <your.email@address.com>
 +
merge = internal:merge
 +
editor = YourFavoriteEditorExecutable
 +
</pre>
 +
In the above config file sample, note that some lines are placeholders that you must replace with correct values:
 +
* Enter your '''real name''' and '''email address'''. Will be used to credit you, and contact you in case of a problem.
 +
* Enter your choice of text editor. Will be used to write commit messages.
 +
 
 +
=== Note to Windows users ===
 +
 
 +
In order to deal with Windows end-of-line encoding, please follow [http://mercurial.selenic.com/wiki/Win32TextExtension these instructions].
 +
 
 +
In the end you should be adding something like this to your config file:
 +
 
 +
<pre>
 +
[extensions]
 +
hgext.win32text=
 +
[encode]
 +
** = cleverencode:
 +
[decode]
 +
** = cleverdecode:
 +
[patch]
 +
eol = crlf
 +
[hooks]
 +
pretxncommit.crlf = python:hgext.win32text.forbidcrlf
 +
</pre>
 +
 
 +
===Branches===
 +
 
 +
By default, what you now see is the development branch, called the 'default branch'.
 +
 
 +
  $ hg branch        # show the name the current branch
 +
  $ hg branches      # show the list of branches
 +
  $ hg up 2.0        # switch to 2.0 branch
 +
 
 +
===Local commit===
 +
 
 +
First of all, make sure you have put any new files under revision control:
 +
  $ hg add <filename> # Put a file under revision control
 +
 
 +
Then you can examine before committing:
 +
  $ hg status        # see what files are affected
 +
  $ hg diff          # show differences that are to be committed
 +
 
 +
To proceed with the local commit:
 +
  $ hg commit        # take care, this will commit changes for the whole repository
 +
                    # even if you are in a sub-directory (this is '''not''' as SVN does)
 +
  $ hg commit .      # if you want to commit only the local directory
 +
 
 +
This will open the text editor that you specified in your config file. This will also use the identity that you specified in your config file.
 +
 
 +
===Undoing uncommitted changes===
 +
 
 +
You can undo all uncommitted changes by doing:
 +
  $ hg revert somefile  # undo uncommitted changes to this file
 +
  $ hg revert -a        # undo all uncommitted changes to all files. Careful!
 +
 
 +
===Undoing a local commit===
 +
In case you want to undo a local commit, e.g. to deal with typos in the commit log or similar, do:
 +
  $ hg rollback      # roll back the last transaction
 +
 
 +
Notice that this will only undo the committing action. See previous section for undoing the changes to your working copy.
 +
 
 +
'''Only''' use this technique for local commits. Otherwise, it doesn't make sense, since it cannot be guaranteed that other users already pulled in public changes.
 +
 
 +
===Generating a patch===
 +
 
 +
Once you have made a local commit, you can generate a patch from it:
 +
 
 +
  $ hg export tip > somefile
 +
 
 +
Here, 'tip' means the latest revision. Try "hg help export" to see other options. This generates a file that you can then attach to a bug report or to an e-mail to the [[Main_Page#Mailing_list|Eigen mailing list]]. If you have properly configured your identity as above before committing, then importing your patch will properly credit you.
 +
 
 +
===Pushing the local changes to the central repository===
 +
 
 +
Once you have made a local commit, you can push it to the central repository.
 +
  $ hg out          # to check what you are actually pushing
 +
  $ hg push          # push your commits. No need to give the repository if this is the one cloned
 +
You may see this error message:
 +
  abort: push creates new remote heads!
 +
  (did you forget to merge? use push -f to force)
 +
This means that one of your modified files has been modified meanwhile in the repository. You need to merge before you can push: see next section. Do '''not''' use push -f as mentioned in that message, as there may be a conflict to resolve manually.
 +
 
 +
===Merge changes from another repository===
 +
  $ hg in <repo>    # check what's coming in
 +
  $ hg pull <repo>  # pull changesets from <repo>
 +
  $ hg merge        # merge the new tip from <repo> into our working directory
 +
  $ hg parents      # see the revisions that have been merged into the working directory
 +
  $ hg commit        # commit the result of the merge
 +
After 'hg merge', you may see this error message:
 +
  warning: conflicts during merge.
 +
  merging <filename> failed!
 +
  0 files updated, 0 files merged, 0 files removed, x files unresolved
 +
In that case, read the section "Resolving Conflicts" below.
 +
 
 +
===Resolving conflicts===
 +
This is very similar to SVN. After a 'hg merge' has found conflicts, the files are left with special markers at the locations of conflicts, like:
 +
  <<<<<<< local
 +
  Hello Sir
 +
  =======
 +
  Hello Madam
 +
  >>>>>>> other
 +
You have to edit these files manually to resolve the conflict. Once a file <filename> is fixed, do:
 +
  hg resolve -m <filename>  # mark the file as resolved
 +
Once all the files are marked as resolved, you can proceed with committing.
 +
 
 +
===Viewing history===
 +
The basic command here is 'hg log'. If you want to see full information about a certain revision, you can do:
 +
 
 +
  $ hg log --style changelog -r 1000  # examine revision 1000
 +
  $ hg log -u someuser  # see all commits made by someuser
 +
 
 +
But you can also enable a couple of extensions that provide fancier views. Edit (or create) your global .hgrc file (in your home directory) and add these lines:
 +
 
 +
[extensions]
 +
hgk=
 +
hgext.graphlog =
 +
 
 +
You can now enjoy a graphical view of the commit history:
 +
 
 +
  $ hgk  # or try 'hg view' if that doesn't work
 +
 
 +
Or if you prefer a plain text output of the graph:
 +
 
 +
  $ hg glog
 +
 
 +
Finally, if you want something more powerful, have a look at the following external programs: hgtk and hgview. [http://bitbucket.org/tortoisehg/stable/wiki/hgtk Hgtk] allows many things, like viewing only as specific branch, viewing only merges, etc. Do:
 +
 
 +
  $ hgtk log
 +
 
 +
[http://www.logilab.org/project/name/hgview Hgview] is simpler but still allows viewing a specific branch:
 +
 
 +
  $ hgview

Revision as of 23:57, 3 October 2010


Mercurial, also known as hg, is the source-control management (SCM) tool that we use for Eigen.

Installing Mercurial and finding documentation

  • If you are using Windows or Mac, download it from [website].
  • If you are using Unix/Linux, just install Mercurial from your package manager.

If you want a graphical user interface, install Tortoise-Hg, but below in this page we will only be referring to the command-line interface.

Below in this page we explain some usual commands, but Mercurial has lots of documentation available on the Web:

Basic usage

Getting the source

Initial checkout:

 $ hg clone http://bitbucket.org/eigen/eigen

or if you have a write access to the repository you have two options:

 $ hg clone ssh://hg@bitbucket.org/eigen/eigen/        # See [1] to setup ssh
 $ hg clone https://login@bitbucket.org/eigen/eigen/   # password login


After that, to update your checkout (get the new changes made to the repository):

 $ hg pull -u       # hg pull brings the changes into your store, and -u updates
                    # your working directory to the latest revision.
                    # 'hg pull -u' is the same as 'hg pull && hg update'.

Configuring Mercurial

Before using Mercurial to make Eigen changes/patches, please make sure that you have configured it as described in this section. To do so, edit (or create) your mercurial config file.

  • On Unix-like systems, the global config file is ~/.hgrc
  • On Windows systems, the global config file is Mercurial.ini in your home directory

Note that if you need a different mercurial config for another project, you can also use a per-clone config file: .hg/hgrc inside the clone directory. We recommend using the global config file unless you really know what you are doing.

Put these lines in the Mercurial config file:

[diff]
git = 1
showfunc = 1
unified = 8

[defaults]
commit = -v

[ui]
username = Your Real Name <your.email@address.com>
merge = internal:merge
editor = YourFavoriteEditorExecutable

In the above config file sample, note that some lines are placeholders that you must replace with correct values:

  • Enter your real name and email address. Will be used to credit you, and contact you in case of a problem.
  • Enter your choice of text editor. Will be used to write commit messages.

Note to Windows users

In order to deal with Windows end-of-line encoding, please follow these instructions.

In the end you should be adding something like this to your config file:

[extensions]
hgext.win32text=
[encode]
** = cleverencode:
[decode]
** = cleverdecode:
[patch]
eol = crlf
[hooks]
pretxncommit.crlf = python:hgext.win32text.forbidcrlf

Branches

By default, what you now see is the development branch, called the 'default branch'.

 $ hg branch        # show the name the current branch
 $ hg branches      # show the list of branches
 $ hg up 2.0        # switch to 2.0 branch

Local commit

First of all, make sure you have put any new files under revision control:

 $ hg add <filename> # Put a file under revision control

Then you can examine before committing:

 $ hg status        # see what files are affected
 $ hg diff          # show differences that are to be committed

To proceed with the local commit:

 $ hg commit        # take care, this will commit changes for the whole repository
                    # even if you are in a sub-directory (this is not as SVN does)
 $ hg commit .      # if you want to commit only the local directory

This will open the text editor that you specified in your config file. This will also use the identity that you specified in your config file.

Undoing uncommitted changes

You can undo all uncommitted changes by doing:

 $ hg revert somefile   # undo uncommitted changes to this file
 $ hg revert -a         # undo all uncommitted changes to all files. Careful!

Undoing a local commit

In case you want to undo a local commit, e.g. to deal with typos in the commit log or similar, do:

 $ hg rollback      # roll back the last transaction

Notice that this will only undo the committing action. See previous section for undoing the changes to your working copy.

Only use this technique for local commits. Otherwise, it doesn't make sense, since it cannot be guaranteed that other users already pulled in public changes.

Generating a patch

Once you have made a local commit, you can generate a patch from it:

 $ hg export tip > somefile

Here, 'tip' means the latest revision. Try "hg help export" to see other options. This generates a file that you can then attach to a bug report or to an e-mail to the Eigen mailing list. If you have properly configured your identity as above before committing, then importing your patch will properly credit you.

Pushing the local changes to the central repository

Once you have made a local commit, you can push it to the central repository.

 $ hg out           # to check what you are actually pushing
 $ hg push          # push your commits. No need to give the repository if this is the one cloned

You may see this error message:

 abort: push creates new remote heads!
 (did you forget to merge? use push -f to force)

This means that one of your modified files has been modified meanwhile in the repository. You need to merge before you can push: see next section. Do not use push -f as mentioned in that message, as there may be a conflict to resolve manually.

Merge changes from another repository

 $ hg in <repo>     # check what's coming in
 $ hg pull <repo>   # pull changesets from <repo>
 $ hg merge         # merge the new tip from <repo> into our working directory
 $ hg parents       # see the revisions that have been merged into the working directory
 $ hg commit        # commit the result of the merge

After 'hg merge', you may see this error message:

 warning: conflicts during merge.
 merging <filename> failed!
 0 files updated, 0 files merged, 0 files removed, x files unresolved

In that case, read the section "Resolving Conflicts" below.

Resolving conflicts

This is very similar to SVN. After a 'hg merge' has found conflicts, the files are left with special markers at the locations of conflicts, like:

 <<<<<<< local
 Hello Sir
 =======
 Hello Madam
 >>>>>>> other

You have to edit these files manually to resolve the conflict. Once a file <filename> is fixed, do:

 hg resolve -m <filename>   # mark the file as resolved

Once all the files are marked as resolved, you can proceed with committing.

Viewing history

The basic command here is 'hg log'. If you want to see full information about a certain revision, you can do:

 $ hg log --style changelog -r 1000  # examine revision 1000
 $ hg log -u someuser  # see all commits made by someuser

But you can also enable a couple of extensions that provide fancier views. Edit (or create) your global .hgrc file (in your home directory) and add these lines:

[extensions]
hgk=
hgext.graphlog =

You can now enjoy a graphical view of the commit history:

 $ hgk   # or try 'hg view' if that doesn't work

Or if you prefer a plain text output of the graph:

 $ hg glog

Finally, if you want something more powerful, have a look at the following external programs: hgtk and hgview. Hgtk allows many things, like viewing only as specific branch, viewing only merges, etc. Do:

 $ hgtk log

Hgview is simpler but still allows viewing a specific branch:

 $ hgview