Difference between revisions of "Using Mercurial"

From GeeklogWiki
Jump to: navigation, search
m (you can now use hg.geeklog.net instead of cvs.geeklog.net)
 
(44 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
== Introduction ==
 
== Introduction ==
  
[http://www.selenic.com/mercurial/ Mercurial] is a distributed version control system (DVCS). The differences to a "traditional" centralized VCS (like CVS or Subversion) include:
+
[http://mercurial.selenic.com/ Mercurial] is a distributed version control system (DVCS). The differences to a "traditional" centralized VCS (like CVS or Subversion) include:
  
 
* Users get a self-contained repository that they can commit changes to, even when being offline.
 
* Users get a self-contained repository that they can commit changes to, even when being offline.
 
* Changes can be pushed back to the parent repository or even to other repositories.
 
* Changes can be pushed back to the parent repository or even to other repositories.
  
As an experiment, we are going to use Mercurial during the 2008 [[Google Summer of Code]]. The distributed model fits this scenario nicely, as each of our students will work on a separate feature. So now they have a local repository to check in to (giving them all the benefits of a version control system). Once a feature or part of a feature is done, it can be pushed back to the parent repository. And in the meantime, it's easy to let other people, e.g. their mentor or interested members of the Geeklog community, pull the changes from the student's repository to show things off or get help on a problem.
+
Having used CVS since its inception, Geeklog [http://www.geeklog.net/article.php/geeklog-goes-mercurial switched] to Mercurial after the release of Geeklog 1.5.1. This switch was preceded by a [[Mercurial Use in GSoC|successful experiment]] using Mercurial during the 2008 [[Google Summer of Code]].
  
 
== Installing Mercurial ==
 
== Installing Mercurial ==
  
 
Installation instructions are provided for [http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall Windows], [http://www.selenic.com/mercurial/wiki/index.cgi/UnixInstall Mac OS X], and [http://www.selenic.com/mercurial/wiki/index.cgi/UnixInstall Linux]
 
Installation instructions are provided for [http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall Windows], [http://www.selenic.com/mercurial/wiki/index.cgi/UnixInstall Mac OS X], and [http://www.selenic.com/mercurial/wiki/index.cgi/UnixInstall Linux]
 +
 +
On the server, we are currently using '''Mercurial 1.5.1'''. While Mercurial is pretty good at being both backward and forward compatible, we recommend that you use the same version locally.
 +
  
 
== Setup ==
 
== Setup ==
Line 16: Line 19:
 
Geeklog's Mercurial repository is available from this URL:
 
Geeklog's Mercurial repository is available from this URL:
  
: http://project.geeklog.net/cgi-bin/hgweb.cgi
+
: http://project.geeklog.net/cgi-bin/hgwebdir.cgi/geeklog/
  
This repository was converted from the CVS repository right after the release of [http://www.geeklog.net/article.php/geeklog-1.5.0 Geeklog 1.5.0].
+
This repository was converted from the CVS repository right after the release of [http://www.geeklog.net/article.php/geeklog-1.5.1 Geeklog 1.5.1].
  
 
To create a copy of that repository, simply do
 
To create a copy of that repository, simply do
  
<pre>hg clone http://project.geeklog.net/cgi-bin/hgweb.cgi geeklog</pre>
+
<pre>hg clone http://project.geeklog.net/cgi-bin/hgwebdir.cgi/geeklog/ geeklog</pre>
 +
 
 +
Where the last "geeklog" is just a directory name for the local copy (and can be changed at will). This will give you a fully working local repository that you can commit changes to.
  
Where "geeklog" is just a directory name for the local copy (and can be changed at will). This will give you a fully working local repository that you can commit changes to.
+
'''Note:''' The same URL can also be used to browse the repository online. Simply visit that URL with your web browser.
  
 
=== SSH Setup ===
 
=== SSH Setup ===
  
For ssh access, you need an account on the server. So this is only of interest for the core developers and SoC students.
+
For ssh access, you need an [[Setting up an account on hg.geeklog.net|account]] on the server. So this is only of interest for the core developers and SoC students.
  
The repository can also be checked out via ssh. Since Mercurial is currently only installed in a user's directory on the server, this requires the following entry in your local(!) <tt>~/.hgrc</tt> file:
+
You can clone the repository via SSH like so:
  
<pre>[ui]
+
<pre>hg clone ssh://username@hg.geeklog.net//cvsroot/hg/geeklog geeklog</pre>
remotecmd = /usr/home/geeklog2/hg/mercurial/hg</pre>
 
 
 
Now you should be able to clone the repository like so:
 
 
 
<pre>hg clone ssh://username@cvs.geeklog.net//cvsroot/geeklog/Geeklog-SoC geeklog</pre>
 
  
 
Where "username" is your login name and the "geeklog" at the end of the command line is again simply a name for your local directory.
 
Where "username" is your login name and the "geeklog" at the end of the command line is again simply a name for your local directory.
  
Please note the slightly odd path syntax with the two slashes after <tt>cvs.geeklog.net</tt> - those are required.
+
Please note the slightly odd path syntax with the two slashes after <tt>hg.geeklog.net</tt> - those are required.
  
  
Line 48: Line 48:
 
Being able to push changes back to the repository again requires an account on the server. You can either do
 
Being able to push changes back to the repository again requires an account on the server. You can either do
  
<pre>hg push ssh://username@cvs.geeklog.net//cvsroot/geeklog/Geeklog-SoC</pre>
+
<pre>hg push ssh://username@hg.geeklog.net//cvsroot/hg/geeklog</pre>
  
 
or, to make your life easier, set the <tt>default-push</tt> repository in the <tt>.hg/hgrc</tt> file of your local repository like so:
 
or, to make your life easier, set the <tt>default-push</tt> repository in the <tt>.hg/hgrc</tt> file of your local repository like so:
  
<pre>default-push = ssh://username@cvs.geeklog.net//cvsroot/geeklog/Geeklog-SoC</pre>
+
<pre>[paths]
 +
default-push = ssh://username@hg.geeklog.net//cvsroot/hg/geeklog</pre>
  
 
(Again, in the ssh: URLs above, replace "username" with your login name)
 
(Again, in the ssh: URLs above, replace "username" with your login name)
 +
 +
=== Trust and Notifications ===
 +
 +
Changes pushed back into the central repository will trigger an email sent to the geeklog-cvs mailing list. However, that email will only be sent after the following additional steps:
 +
 +
# log into your account on hg.geeklog.net
 +
# in your home directory, create a file named <tt>.hgrc</tt>
 +
# enter this as the file's content:
 +
<pre>[trusted]
 +
users = geeklog2
 +
groups = users</pre>
 +
 +
This will also get rid of warnings like
 +
: remote: Not trusting file (...) from untrusted user geeklog2, group users
 +
when pushing back changes.
  
  
Line 60: Line 76:
  
 
Since we're all new to Mercurial, this is something we will have to establish as we go along. For starters, the [http://www.selenic.com/mercurial/wiki/ Mercurial Wiki] has a page on [http://www.selenic.com/mercurial/wiki/index.cgi/WorkingPractices Working Practices] that we may want to adopt.
 
Since we're all new to Mercurial, this is something we will have to establish as we go along. For starters, the [http://www.selenic.com/mercurial/wiki/ Mercurial Wiki] has a page on [http://www.selenic.com/mercurial/wiki/index.cgi/WorkingPractices Working Practices] that we may want to adopt.
 +
 +
=== Use a clean incoming repository ===
 +
 +
Pull changes to a local "incoming" repository but don't work on that repository. Cloning that repository locally is a cheap operation and allows you to easily create multiple copies if necessary, e.g. when working on different features in parallel.
 +
 +
Push directly from your working repositories, then sync back by pulling the changes back down via your incoming repository.
 +
 +
=== Merging ===
 +
 +
If you attempt to push changes to the main repository and receive the error:
 +
pushing to ssh://username@hg.geeklog.net//cvsroot/geeklog/Geeklog-SoC
 +
searching for changes
 +
abort: push creates new remote heads!
 +
(did you forget to merge? use push -f to force)
 +
Simply pull from the main repository, "hg heads" to see the revision numbers, "hg merge [rev number]" to merge your changes, then commit the changes, and push back to the main repository.
 +
 +
Also: Don't try to push newly added files while you still have uncommited changes lying around (or you will end up with the above). In that case, it may make sense to make a fresh clone (fast + cheap if you use an "incoming" repository!), add the new files there, then push from the fresh copy.
 +
 +
More information: [[Merging a Feature Branch]]
 +
 +
=== Username ===
 +
 +
When committing a change, the username associated with that change will be your local username (login, etc.) - ''not'' the name of your account on the server.
 +
 +
For a consistent username, add your preferred username to your local <tt>.hgrc</tt> file:
 +
<pre>username = John Doe <john@example.com></pre>
 +
The email address is optional.
  
 
''(More tips and tricks to be added here)''
 
''(More tips and tricks to be added here)''
 +
 +
 +
== Undoing Changes ==
 +
 +
To undo changes you made, use one of the following, depending on circumstances:
 +
 +
* <tt>hg revert</tt><br>to revert changes made before a commit. This will also undo <tt>hg add</tt> and <tt>hg remove</tt>.
 +
* <tt>hg rollback</tt><br>to revert changes that have been commited to the local repository but not been pushed to another repository yet. You can only rollback the last hg command.
 +
* <tt>hg backout</tt><br>to revert changes after they have been commited ''and'' pushed.
 +
 +
Note that <tt>hg backout</tt> will actually add a new change to the current branch that reverts your previous change. I.e. your change will ''not'' be removed from the repository. Unless you've accidentally committed something super-secret, that's usually fine. Mistakes happen - no need to sweat it.
 +
 +
 +
== Documentation ==
 +
 +
* The book [http://hgbook.red-bean.com/ Distributed revision control with Mercurial] aka "the hg book" is probably the best available documentation for Mercurial. It is available for download under the Open Publication License.
 +
* The [http://www.selenic.com/mercurial/wiki/ Mercurial Wiki] is a good place to search for more information.
 +
* [http://www.lunch.org.uk/wiki/articles Inside a distributed version control system] by Jim Hague provides a good introduction into the workings of DVCS in general and Mercurial in particular.
 +
* [http://hginit.com/ HgInit] by Joel Spolsky is a nice tutorial website for Mercurial.
 +
* Another good introduction: [http://bpse.ifs.tuwien.ac.at/technology/tech-scm-mercurial.html Technology: Sourcecode Management (SCM)]
 +
* Mercurial lets you choose between a variety of workflows. [http://hg-scm.org/workflow_guide Learning Mercurial in Workflows] discusses the most commonly used ones.
 +
* Those already familiar with a non-distributed VCS may find [[Mercurial for SVN Users]] useful.
 +
* Advanced topic: [http://blog.experimentalworks.net/2009/03/merge-vs-rebase-a-deep-dive-into-the-mysteries-of-revision-control/ Merge vs. Rebase]. Rebasing is a way to push commits from a branch on top of another branch.
 +
 +
 +
=== The Impatient's Guide to the HG Book ===
 +
 +
''(an entirely subjective view)''
 +
 +
* Chapter 1: Introduction<br>Skip if you already know about VCS and DVCS
 +
* Chapter 2: A tour of Mercurial: the basics<br>Everything from section 2.2 on is '''recommended reading'''. The essential things you need to know to use Mercurial.
 +
* Chapter 3: A tour of Mercurial: merging work<br>Title says it all - '''recommended reading'''
 +
* Chapter 4: Behind the scenes<br>Feel free to skip
 +
* Chapter 5: Mercurial in daily use<br>Despite the title, this chapter seems more confusing than helpful - skip
 +
* Chapter 6: Collaborating with other people<br>Section 6.2 is '''recommended reading''' once you've mastered the basics
 +
* Chapter 7: File names and pattern matching<br>Nothing surprising here - skip
 +
* Chapter 8: Managing releases and branchy development<br>Advanced topic but useful
 +
* Chapter 9: Finding and fixing your mistakes<br>Very useful (but skip sections 9.5 and 9.6)
 +
* You can effectively stop reading after Chapter 9.
 +
* Appendix A may be useful as a reference.
 +
 +
 +
== Windows Users - Secret Sauce (if you have commit rights) ==
 +
 +
I'm using command line Mercurial (I don't like the windows explorer performance hit of the tortoise system). But this works for me, after much messing around.
 +
 +
# Clone the main Geeklog repository, as above. (geeklog-hg)
 +
# Clone your local copy of Geeklog to give yourself a clean working environment. (geeklog-hg-mine)
 +
# Clone your clean working environment ;-) (geeklog-hg-dev)
 +
# Update /path/to/geeklog-hg/.hg/hgrc to match below
 +
# Update /documents and settings/[your user]/mercurial.ini to match the other below
 +
 +
And that works.
 +
 +
For hgrc:
 +
 +
<pre>[paths]
 +
default = ssh://[your username]@hg.geeklog.net//cvsroot/hg/geeklog
 +
</pre>
 +
 +
For mercurial.ini:
 +
 +
<pre>[ui]
 +
ssh = c:/path/to/putty/plink.exe -ssh -v -l [your username] -pw [your password]
 +
username = [your name] <[your email address]>
 +
</pre>
 +
 +
* No quotes are used in defining the .ini paramaters
 +
* Path to plink.exe can not have any spaces in the actual directory names
 +
* Commit will just commit the change to your local repository
 +
* Use the synchronize (Tortoise client term) to push the local committed changes up to the remote repository
 +
* When doing the synchronize, in the pop-up dialog, the remote path is: ssh://username@hg.geeklog.net//cvsroot/hg/geeklog
 +
 +
So I develop in geeklog-hg-dev, then I winmerge my changes back into geeklog-hg-mine to make sure I never accidentally commit local settings (paths etc) or hacks, debugs. Then I commit to geeklog-hg-mine, then back to geeklog-hg when that's ready, then push up to master. Complex hey? ;-)
 +
 +
== Windows vs. Unix Line Endings ==
 +
 +
[[Coding Guidelines#File_Formats|Per convention]], all of Geeklog's source files should use Unix-like line endings (LF only). Windows users please make sure that you configure your editor to write Unix-style line endings (instead of the Windows-style CR+LF line endings).
 +
 +
To prevent accidentally committing a file with Windows line endings, you can add the following snippet to your global <tt>.hgrc</tt> or <tt>mercurial.ini</tt> file:
 +
 +
<pre>[hooks]
 +
pretxncommit.crlf = python:hgext.win32text.forbidcrlf</pre>
 +
 +
For automatic conversion between Unix and Windows line endings, you can also try and use the [http://www.selenic.com/mercurial/wiki/Win32TextExtension Win32text extension] that ships with Mercurial.
 +
 +
== Also See ==
 +
 +
* [[Tags and Branches]]
 +
* [[Mercurial Use in GSoC]]
 +
  
 
[[Category:Development]]
 
[[Category:Development]]

Latest revision as of 19:02, 14 May 2012

Introduction

Mercurial is a distributed version control system (DVCS). The differences to a "traditional" centralized VCS (like CVS or Subversion) include:

  • Users get a self-contained repository that they can commit changes to, even when being offline.
  • Changes can be pushed back to the parent repository or even to other repositories.

Having used CVS since its inception, Geeklog switched to Mercurial after the release of Geeklog 1.5.1. This switch was preceded by a successful experiment using Mercurial during the 2008 Google Summer of Code.

Installing Mercurial

Installation instructions are provided for Windows, Mac OS X, and Linux

On the server, we are currently using Mercurial 1.5.1. While Mercurial is pretty good at being both backward and forward compatible, we recommend that you use the same version locally.


Setup

Geeklog's Mercurial repository is available from this URL:

http://project.geeklog.net/cgi-bin/hgwebdir.cgi/geeklog/

This repository was converted from the CVS repository right after the release of Geeklog 1.5.1.

To create a copy of that repository, simply do

hg clone http://project.geeklog.net/cgi-bin/hgwebdir.cgi/geeklog/ geeklog

Where the last "geeklog" is just a directory name for the local copy (and can be changed at will). This will give you a fully working local repository that you can commit changes to.

Note: The same URL can also be used to browse the repository online. Simply visit that URL with your web browser.

SSH Setup

For ssh access, you need an account on the server. So this is only of interest for the core developers and SoC students.

You can clone the repository via SSH like so:

hg clone ssh://username@hg.geeklog.net//cvsroot/hg/geeklog geeklog

Where "username" is your login name and the "geeklog" at the end of the command line is again simply a name for your local directory.

Please note the slightly odd path syntax with the two slashes after hg.geeklog.net - those are required.


Pushing back

Being able to push changes back to the repository again requires an account on the server. You can either do

hg push ssh://username@hg.geeklog.net//cvsroot/hg/geeklog

or, to make your life easier, set the default-push repository in the .hg/hgrc file of your local repository like so:

[paths]
default-push = ssh://username@hg.geeklog.net//cvsroot/hg/geeklog

(Again, in the ssh: URLs above, replace "username" with your login name)

Trust and Notifications

Changes pushed back into the central repository will trigger an email sent to the geeklog-cvs mailing list. However, that email will only be sent after the following additional steps:

  1. log into your account on hg.geeklog.net
  2. in your home directory, create a file named .hgrc
  3. enter this as the file's content:
[trusted]
users = geeklog2
groups = users

This will also get rid of warnings like

remote: Not trusting file (...) from untrusted user geeklog2, group users

when pushing back changes.


Best practices

Since we're all new to Mercurial, this is something we will have to establish as we go along. For starters, the Mercurial Wiki has a page on Working Practices that we may want to adopt.

Use a clean incoming repository

Pull changes to a local "incoming" repository but don't work on that repository. Cloning that repository locally is a cheap operation and allows you to easily create multiple copies if necessary, e.g. when working on different features in parallel.

Push directly from your working repositories, then sync back by pulling the changes back down via your incoming repository.

Merging

If you attempt to push changes to the main repository and receive the error:

pushing to ssh://username@hg.geeklog.net//cvsroot/geeklog/Geeklog-SoC
searching for changes
abort: push creates new remote heads!
(did you forget to merge? use push -f to force)

Simply pull from the main repository, "hg heads" to see the revision numbers, "hg merge [rev number]" to merge your changes, then commit the changes, and push back to the main repository.

Also: Don't try to push newly added files while you still have uncommited changes lying around (or you will end up with the above). In that case, it may make sense to make a fresh clone (fast + cheap if you use an "incoming" repository!), add the new files there, then push from the fresh copy.

More information: Merging a Feature Branch

Username

When committing a change, the username associated with that change will be your local username (login, etc.) - not the name of your account on the server.

For a consistent username, add your preferred username to your local .hgrc file:

username = John Doe <john@example.com>

The email address is optional.

(More tips and tricks to be added here)


Undoing Changes

To undo changes you made, use one of the following, depending on circumstances:

  • hg revert
    to revert changes made before a commit. This will also undo hg add and hg remove.
  • hg rollback
    to revert changes that have been commited to the local repository but not been pushed to another repository yet. You can only rollback the last hg command.
  • hg backout
    to revert changes after they have been commited and pushed.

Note that hg backout will actually add a new change to the current branch that reverts your previous change. I.e. your change will not be removed from the repository. Unless you've accidentally committed something super-secret, that's usually fine. Mistakes happen - no need to sweat it.


Documentation


The Impatient's Guide to the HG Book

(an entirely subjective view)

  • Chapter 1: Introduction
    Skip if you already know about VCS and DVCS
  • Chapter 2: A tour of Mercurial: the basics
    Everything from section 2.2 on is recommended reading. The essential things you need to know to use Mercurial.
  • Chapter 3: A tour of Mercurial: merging work
    Title says it all - recommended reading
  • Chapter 4: Behind the scenes
    Feel free to skip
  • Chapter 5: Mercurial in daily use
    Despite the title, this chapter seems more confusing than helpful - skip
  • Chapter 6: Collaborating with other people
    Section 6.2 is recommended reading once you've mastered the basics
  • Chapter 7: File names and pattern matching
    Nothing surprising here - skip
  • Chapter 8: Managing releases and branchy development
    Advanced topic but useful
  • Chapter 9: Finding and fixing your mistakes
    Very useful (but skip sections 9.5 and 9.6)
  • You can effectively stop reading after Chapter 9.
  • Appendix A may be useful as a reference.


Windows Users - Secret Sauce (if you have commit rights)

I'm using command line Mercurial (I don't like the windows explorer performance hit of the tortoise system). But this works for me, after much messing around.

  1. Clone the main Geeklog repository, as above. (geeklog-hg)
  2. Clone your local copy of Geeklog to give yourself a clean working environment. (geeklog-hg-mine)
  3. Clone your clean working environment ;-) (geeklog-hg-dev)
  4. Update /path/to/geeklog-hg/.hg/hgrc to match below
  5. Update /documents and settings/[your user]/mercurial.ini to match the other below

And that works.

For hgrc:

[paths]
default = ssh://[your username]@hg.geeklog.net//cvsroot/hg/geeklog

For mercurial.ini:

[ui]
ssh = c:/path/to/putty/plink.exe -ssh -v -l [your username] -pw [your password]
username = [your name] <[your email address]>
  • No quotes are used in defining the .ini paramaters
  • Path to plink.exe can not have any spaces in the actual directory names
  • Commit will just commit the change to your local repository
  • Use the synchronize (Tortoise client term) to push the local committed changes up to the remote repository
  • When doing the synchronize, in the pop-up dialog, the remote path is: ssh://username@hg.geeklog.net//cvsroot/hg/geeklog

So I develop in geeklog-hg-dev, then I winmerge my changes back into geeklog-hg-mine to make sure I never accidentally commit local settings (paths etc) or hacks, debugs. Then I commit to geeklog-hg-mine, then back to geeklog-hg when that's ready, then push up to master. Complex hey? ;-)

Windows vs. Unix Line Endings

Per convention, all of Geeklog's source files should use Unix-like line endings (LF only). Windows users please make sure that you configure your editor to write Unix-style line endings (instead of the Windows-style CR+LF line endings).

To prevent accidentally committing a file with Windows line endings, you can add the following snippet to your global .hgrc or mercurial.ini file:

[hooks]
pretxncommit.crlf = python:hgext.win32text.forbidcrlf

For automatic conversion between Unix and Windows line endings, you can also try and use the Win32text extension that ships with Mercurial.

Also See