@ -0,0 +1,119 @@ | |||
<!-- -*- html -*- --> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |||
<html> | |||
<head> | |||
<title>Mercurial: The Definitive Guide</title> | |||
<link rel="stylesheet" href="/support/styles.css" type="text/css"/> | |||
<link rel="alternate" type="application/atom+xml" title="Comments" | |||
href="/feeds/comments/"/> | |||
<link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"/> | |||
<script type="text/javascript" src="/support/jquery.js"></script> | |||
<script type="text/javascript" src="/support/form.js"></script> | |||
<script type="text/javascript" src="/support/hsbook.js"></script> | |||
</head> | |||
<body> | |||
<div class="navheader"><h1 class="booktitle">Mercurial: The Definitive Guide<div class="authors">by Bryan O'Sullivan</div></h1></div> | |||
<div class="book"> | |||
<h2>Welcome to Mercurial: The Definitive Guide</h2> | |||
<p>This is the online home of the book “Mercurial: The | |||
Definitive Guide”. | |||
It was published in 2009 by O'Reilly Media.</p> | |||
<p><a href="http://www.selenic.com/mercurial">Mercurial</a> is a | |||
fast, lightweight source control management system | |||
designed for easy and efficient handling of very large distributed | |||
projects. My book tells you what it is, why you should care, and | |||
how you can use it effectively.</p> | |||
<h2>Read it online</h2> | |||
<p>I make the content freely available online: you | |||
can <a href="/read/"><i>read it here</i></a>. If you like it, | |||
please <a href="#buy">buy a copy</a>!</p> | |||
<p>For news updates, please | |||
visit <a href="http://www.serpentine.com/blog/">my blog</a>. You | |||
should follow me on | |||
Twitter <a href="http://twitter.com/bos31337">here</a>.</p> | |||
<h2><a name="#buy">How</a> to buy</h2> | |||
<p>If you like the book, please support the work of the Software | |||
Freedom Conservancy (<a href="#sfc">see below</a>) by buying a | |||
copy.</p> | |||
<ul> | |||
<li><a href="http://www.amazon.com/gp/product/0596800673?ie=UTF8&tag=reaworhas-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0596800673">Amazon.com</a><img src="http://www.assoc-amazon.com/e/ir?t=reaworhas-20&l=as2&o=1&a=0596800673" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></li> | |||
<li><a href="http://oreilly.com/catalog/9780596800673/">O'Reilly Media</a></li> | |||
</ul> | |||
<h2>You should contribute!</h2> | |||
<p>I publish the source code for this book | |||
as <a href="http://bitbucket.org/bos/hgbook">a | |||
Mercurial repository</a>. Please feel | |||
welcome to clone it, make modifications to your copy, and send me | |||
changes. Getting a copy of the source takes just a few seconds if | |||
you have Mercurial installed:</p> | |||
<pre class="screen">hg clone http://bitbucket.org/bos/hgbook</pre> | |||
<p>The online version of the book includes a comment system | |||
that you can use to send feedback involving errors, omissions, and | |||
suggestions.</p> | |||
<p>(If you would like to adapt the comment system for a | |||
publishing project of your own, the source for the web application | |||
is included with the book source at the link above.)</p> | |||
<h2><a name="sfc">How</a> I help Mercurial and free software, and | |||
you can too</h2> | |||
<p>Mercurial is a member of the <a href="http://conservancy.softwarefreedom.org/">Software Freedom Conservancy</a>, a | |||
wonderful non-profit organisation that offers its member projects | |||
legal and administrative advice.</p> | |||
<p>I donate my royalties from the sales of this book to the | |||
Software Freedom Conservancy, and I encourage you to support their | |||
work, too.</p> | |||
<p>The SFC can | |||
accept <a href="http://conservancy.softwarefreedom.org/?donate">accept | |||
donations</a> (tax-free under IRS 501(c)(3), within the United | |||
States) on behalf of its member projects. If you would like to | |||
support Mercurial directly, please consider making a donation to | |||
the SFC on its behalf.</p> | |||
<p>If you would like to help free software developers to provide | |||
their important public services without being impeded by legal | |||
issues, please consider donating to the SFC's sister organisation, | |||
the <a href="http://www.softwarefreedom.org/">Software Freedom Law | |||
Center</a>.</p> | |||
</div> | |||
<div class="hgbookfooter"> <p><img src="/support/figs/rss.png"> Want to stay | |||
up to date? Subscribe to comment feeds for any chapter, or | |||
the <a class="feed" | |||
href="/feeds/comments/">entire book</a>.</p> <p>Copyright | |||
2006, 2007, 2008, 2009 Bryan O'Sullivan. | |||
Icons by | |||
<a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a | |||
href="http://mattahan.deviantart.com/">Mattahan</a>.</p> | |||
</div> | |||
<script type="text/javascript"> | |||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); | |||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); | |||
</script> | |||
<script type="text/javascript"> | |||
try { | |||
var pageTracker = _gat._getTracker("UA-1805907-5"); | |||
pageTracker._trackPageview(); | |||
} catch(err) {}</script> | |||
</body> | |||
</html> |
@ -0,0 +1,61 @@ | |||
<!-- -*- html -*- --> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |||
<html> | |||
<head> | |||
<title>Mercurial: The Definitive Guide</title> | |||
<link rel="stylesheet" href="/support/styles.css" type="text/css"/> | |||
<link rel="alternate" type="application/atom+xml" title="Comments" | |||
href="/feeds/comments/"/> | |||
<link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"/> | |||
<script type="text/javascript" src="/support/jquery.js"></script> | |||
<script type="text/javascript" src="/support/form.js"></script> | |||
<script type="text/javascript" src="/support/hsbook.js"></script> | |||
</head> | |||
<body> | |||
<div class="navheader"><h1 class="booktitle">Mercurial: The Definitive Guide<div class="authors">by Bryan O'Sullivan</div></h1></div> | |||
<div class="book"><ul class="booktoc"> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:preface/"><img src="/support/figs/rss.png"/></a></span>0. <a href="preface.html">Preface</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:intro/"><img src="/support/figs/rss.png"/></a></span>1. <a href="how-did-we-get-here.html">How did we get here?</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:tour-basic/"><img src="/support/figs/rss.png"/></a></span>2. <a href="a-tour-of-mercurial-the-basics.html">A tour of Mercurial: the basics</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:tour-merge/"><img src="/support/figs/rss.png"/></a></span>3. <a href="a-tour-of-mercurial-merging-work.html">A tour of Mercurial: merging work</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:concepts/"><img src="/support/figs/rss.png"/></a></span>4. <a href="behind-the-scenes.html">Behind the scenes</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:daily/"><img src="/support/figs/rss.png"/></a></span>5. <a href="mercurial-in-daily-use.html">Mercurial in daily use</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/cha:collab/"><img src="/support/figs/rss.png"/></a></span>6. <a href="collaborating-with-other-people.html">Collaborating with other people</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:names/"><img src="/support/figs/rss.png"/></a></span>7. <a href="file-names-and-pattern-matching.html">File names and pattern matching</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:branch/"><img src="/support/figs/rss.png"/></a></span>8. <a href="managing-releases-and-branchy-development.html">Managing releases and branchy development</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:undo/"><img src="/support/figs/rss.png"/></a></span>9. <a href="finding-and-fixing-mistakes.html">Finding and fixing mistakes</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:hook/"><img src="/support/figs/rss.png"/></a></span>10. <a href="handling-repository-events-with-hooks.html">Handling repository events with hooks</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:template/"><img src="/support/figs/rss.png"/></a></span>11. <a href="customizing-the-output-of-mercurial.html">Customizing the output of Mercurial</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:mq/"><img src="/support/figs/rss.png"/></a></span>12. <a href="managing-change-with-mercurial-queues.html">Managing change with Mercurial Queues</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:mq-collab/"><img src="/support/figs/rss.png"/></a></span>13. <a href="advanced-uses-of-mercurial-queues.html">Advanced uses of Mercurial Queues</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-07<a href="/feeds/comments/chap:hgext/"><img src="/support/figs/rss.png"/></a></span>14. <a href="adding-functionality-with-extensions.html">Adding functionality with extensions</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-04-28<a href="/feeds/comments/svn/"><img src="/support/figs/rss.png"/></a></span>A. <a href="migrating-to-mercurial.html">Migrating to Mercurial</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-05-04<a href="/feeds/comments/chap:mqref/"><img src="/support/figs/rss.png"/></a></span>B. <a href="mercurial-queues-reference.html">Mercurial Queues reference</a></li> | |||
<li class="zebra_a"><span class="chapinfo">2009-03-30<a href="/feeds/comments/chap:srcinstall/"><img src="/support/figs/rss.png"/></a></span>C. <a href="installing-mercurial-from-source.html">Installing Mercurial from source</a></li> | |||
<li class="zebra_b"><span class="chapinfo">2009-03-30<a href="/feeds/comments/cha:opl/"><img src="/support/figs/rss.png"/></a></span>D. <a href="open-publication-license.html">Open Publication License</a></li> | |||
</ul></div> | |||
<div class="hgbookfooter"> <p><img src="/support/figs/rss.png"> Want to stay | |||
up to date? Subscribe to comment feeds for any chapter, or | |||
the <a class="feed" | |||
href="/feeds/comments/">entire book</a>.</p> <p>Copyright | |||
2006, 2007, 2008, 2009 Bryan O'Sullivan. | |||
Icons by | |||
<a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a | |||
href="http://mattahan.deviantart.com/">Mattahan</a>.</p> | |||
</div> | |||
<script type="text/javascript"> | |||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); | |||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); | |||
</script> | |||
<script type="text/javascript"> | |||
try { | |||
var pageTracker = _gat._getTracker("UA-1805907-5"); | |||
pageTracker._trackPageview(); | |||
} catch(err) {}</script> | |||
</body> | |||
</html> |
@ -0,0 +1,384 @@ | |||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Chapter 3. A tour of Mercurial: merging work</title><link rel="stylesheet" href="/support/styles.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.3"><link rel="home" href="index.html" title="Mercurial: The Definitive Guide"><link rel="up" href="index.html" title="Mercurial: The Definitive Guide"><link rel="prev" href="a-tour-of-mercurial-the-basics.html" title="Chapter 2. A tour of Mercurial: the basics"><link rel="next" href="behind-the-scenes.html" title="Chapter 4. Behind the scenes"><link rel="alternate" type="application/atom+xml" title="Comments" href="/feeds/comments/"><link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"><script type="text/javascript" src="/support/jquery-min.js"></script><script type="text/javascript" src="/support/form.js"></script><script type="text/javascript" src="/support/hsbook.js"></script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><h2 class="booktitle"><a href="/">Mercurial: The Definitive Guide</a><span class="authors">by Bryan O'Sullivan</span></h2></div><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 3. A tour of Mercurial: merging work</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="a-tour-of-mercurial-the-basics.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="behind-the-scenes.html">Next</a></td></tr></table></div><div class="chapter" lang="en" id="chap:tour-merge"><div class="titlepage"><div><div><h2 class="title">Chapter 3. A tour of Mercurial: merging work</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="a-tour-of-mercurial-merging-work.html#id352947">Merging streams of work</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-merging-work.html#id353683">Head changesets</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-merging-work.html#id353830">Performing the merge</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-merging-work.html#id353997">Committing the results of the merge</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-merging-work.html#id354262">Merging conflicting changes</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-merging-work.html#id354379">Using a graphical merge tool</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-merging-work.html#id354524">A worked example</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-merging-work.html#sec:tour-merge:fetch">Simplifying the pull-merge-commit sequence</a></span></dt><dt><span class="sect1"><a href="a-tour-of-mercurial-merging-work.html#id355904">Renaming, copying, and merging</a></span></dt></dl></div><p id="x_338"><a name="x_338"></a>We've now covered cloning a repository, making changes in a | |||
repository, and pulling or pushing changes from one repository | |||
into another. Our next step is <span class="emphasis"><em>merging</em></span> | |||
changes from separate repositories.</p><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id352947">Merging streams of work</h2></div></div></div><p id="x_339"><a name="x_339"></a>Merging is a fundamental part of working with a distributed | |||
revision control tool. Here are a few cases in which the need | |||
to merge work arises.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_33a"><a name="x_33a"></a>Alice and Bob each have a personal copy of a | |||
repository for a project they're collaborating on. Alice | |||
fixes a bug in her repository; Bob adds a new feature in | |||
his. They want the shared repository to contain both the | |||
bug fix and the new feature.</p></li><li><p id="x_33b"><a name="x_33b"></a>Cynthia frequently works on several different | |||
tasks for a single project at once, each safely isolated in | |||
its own repository. Working this way means that she often | |||
needs to merge one piece of her own work with | |||
another.</p></li></ul></div><p id="x_33c"><a name="x_33c"></a>Because we need to merge often, Mercurial makes | |||
the process easy. Let's walk through a merge. We'll begin by | |||
cloning yet another repository (see how often they spring up?) | |||
and making a change in it.</p><pre id="id353643" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg clone hello my-new-hello</code></strong> | |||
updating working directory | |||
2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
<code class="prompt">$</code> <strong class="userinput"><code>cd my-new-hello</code></strong> | |||
# Make some simple edits to hello.c. | |||
<code class="prompt">$</code> <strong class="userinput"><code>my-text-editor hello.c</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'A new hello for a new day.'</code></strong> | |||
</pre><p id="x_33d"><a name="x_33d"></a>We should now have two copies of | |||
<code class="filename">hello.c</code> with different contents. The | |||
histories of the two repositories have also diverged, as | |||
illustrated in <a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:sep-repos" title="Figure 3.1. Divergent recent histories of the my-hello and my-new-hello repositories">Figure 3.1, “Divergent recent histories of the my-hello and my-new-hello | |||
repositories”</a>. Here is a copy of our | |||
file from one repository.</p><pre id="id353616" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat hello.c</code></strong> | |||
/* | |||
* Placed in the public domain by Bryan O'Sullivan. This program is | |||
* not covered by patents in the United States or other countries. | |||
*/ | |||
#include <stdio.h> | |||
int main(int argc, char **argv) | |||
{ | |||
printf("once more, hello.\n"); | |||
printf("hello, world!\"); | |||
printf("hello again!\n"); | |||
return 0; | |||
} | |||
</pre><p id="x_722"><a name="x_722"></a>And here is our slightly different version from the other | |||
repository.</p><pre id="id353585" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat ../my-hello/hello.c</code></strong> | |||
/* | |||
* Placed in the public domain by Bryan O'Sullivan. This program is | |||
* not covered by patents in the United States or other countries. | |||
*/ | |||
#include <stdio.h> | |||
int main(int argc, char **argv) | |||
{ | |||
printf("hello, world!\"); | |||
printf("hello again!\n"); | |||
return 0; | |||
} | |||
</pre><div class="figure"><a name="fig:tour-merge:sep-repos"></a><p class="title"><b>Figure 3.1. Divergent recent histories of the <code class="filename">my-hello</code> and <code class="filename">my-new-hello</code> | |||
repositories</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/tour-merge-sep-repos.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_33f"><a name="x_33f"></a>We already know that pulling changes from our <code class="filename">my-hello</code> repository will have no | |||
effect on the working directory.</p><pre id="id353533" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg pull ../my-hello</code></strong> | |||
pulling from ../my-hello | |||
searching for changes | |||
adding changesets | |||
adding manifests | |||
adding file changes | |||
added 1 changesets with 1 changes to 1 files (+1 heads) | |||
(run 'hg heads' to see heads, 'hg merge' to merge) | |||
</pre><p id="x_340"><a name="x_340"></a>However, the <span class="command"><strong>hg pull</strong></span> | |||
command says something about “<span class="quote">heads</span>”.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id353683">Head changesets</h3></div></div></div><p id="x_341"><a name="x_341"></a>Remember that Mercurial records what the parent | |||
of each change is. If a change has a parent, we call it a | |||
child or descendant of the parent. A head is a change that | |||
has no children. The tip revision is thus a head, because the | |||
newest revision in a repository doesn't have any children. | |||
There are times when a repository can contain more than one | |||
head.</p><div class="figure"><a name="fig:tour-merge:pull"></a><p class="title"><b>Figure 3.2. Repository contents after pulling from <code class="filename">my-hello</code> into <code class="filename">my-new-hello</code></b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/tour-merge-pull.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_343"><a name="x_343"></a>In <a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:pull" title="Figure 3.2. Repository contents after pulling from my-hello into my-new-hello">Figure 3.2, “Repository contents after pulling from my-hello into my-new-hello”</a>, you can | |||
see the effect of the pull from <code class="filename">my-hello</code> into <code class="filename">my-new-hello</code>. The history that | |||
was already present in <code class="filename">my-new-hello</code> is untouched, but | |||
a new revision has been added. By referring to <a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:sep-repos" title="Figure 3.1. Divergent recent histories of the my-hello and my-new-hello repositories">Figure 3.1, “Divergent recent histories of the my-hello and my-new-hello | |||
repositories”</a>, we can see that the | |||
<span class="emphasis"><em>changeset ID</em></span> remains the same in the new | |||
repository, but the <span class="emphasis"><em>revision number</em></span> has | |||
changed. (This, incidentally, is a fine example of why it's | |||
not safe to use revision numbers when discussing changesets.) | |||
We can view the heads in a repository using the <span class="command"><strong>hg heads</strong></span> command.</p><pre id="id354126" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg heads</code></strong> | |||
changeset: 6:b6fed4f21233 | |||
tag: tip | |||
parent: 4:2278160e78d4 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Tue May 05 06:55:53 2009 +0000 | |||
summary: Added an extra line of output | |||
changeset: 5:5218ee8aecf3 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Tue May 05 06:55:55 2009 +0000 | |||
summary: A new hello for a new day. | |||
</pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id353830">Performing the merge</h3></div></div></div><p id="x_344"><a name="x_344"></a>What happens if we try to use the normal <span class="command"><strong>hg update</strong></span> command to update to the | |||
new tip?</p><pre id="id354203" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg update</code></strong> | |||
abort: crosses branches (use 'hg merge' or 'hg update -C') | |||
</pre><p id="x_345"><a name="x_345"></a>Mercurial is telling us that the <span class="command"><strong>hg update</strong></span> command won't do a merge; | |||
it won't update the working directory when it thinks we might | |||
want to do a merge, unless we force it to do so. | |||
(Incidentally, forcing the update with <span class="command"><strong>hg update | |||
-C</strong></span> would revert any uncommitted changes in the | |||
working directory.)</p><p id="x_723"><a name="x_723"></a>To start a merge between the two heads, we use the | |||
<span class="command"><strong>hg merge</strong></span> command.</p><pre id="id354163" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg merge</code></strong> | |||
merging hello.c | |||
0 files updated, 1 files merged, 0 files removed, 0 files unresolved | |||
(branch merge, don't forget to commit) | |||
</pre><p id="x_347"><a name="x_347"></a>We resolve the contents of <code class="filename">hello.c</code> | |||
This updates the working directory so that it | |||
contains changes from <span class="emphasis"><em>both</em></span> heads, which | |||
is reflected in both the output of <span class="command"><strong>hg | |||
parents</strong></span> and the contents of | |||
<code class="filename">hello.c</code>.</p><pre id="id354360" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg parents</code></strong> | |||
changeset: 5:5218ee8aecf3 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Tue May 05 06:55:55 2009 +0000 | |||
summary: A new hello for a new day. | |||
changeset: 6:b6fed4f21233 | |||
tag: tip | |||
parent: 4:2278160e78d4 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Tue May 05 06:55:53 2009 +0000 | |||
summary: Added an extra line of output | |||
<code class="prompt">$</code> <strong class="userinput"><code>cat hello.c</code></strong> | |||
/* | |||
* Placed in the public domain by Bryan O'Sullivan. This program is | |||
* not covered by patents in the United States or other countries. | |||
*/ | |||
#include <stdio.h> | |||
int main(int argc, char **argv) | |||
{ | |||
printf("once more, hello.\n"); | |||
printf("hello, world!\"); | |||
printf("hello again!\n"); | |||
return 0; | |||
} | |||
</pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id353997">Committing the results of the merge</h3></div></div></div><p id="x_348"><a name="x_348"></a>Whenever we've done a merge, <span class="command"><strong>hg | |||
parents</strong></span> will display two parents until we <span class="command"><strong>hg commit</strong></span> the results of the | |||
merge.</p><pre id="id354037" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'Merged changes'</code></strong> | |||
</pre><p id="x_349"><a name="x_349"></a>We now have a new tip revision; notice that it has | |||
<span class="emphasis"><em>both</em></span> of our former heads as its parents. | |||
These are the same revisions that were previously displayed by | |||
<span class="command"><strong>hg parents</strong></span>.</p><pre id="id354110" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg tip</code></strong> | |||
changeset: 7:ecb0e17b2a4e | |||
tag: tip | |||
parent: 5:5218ee8aecf3 | |||
parent: 6:b6fed4f21233 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Tue May 05 06:55:56 2009 +0000 | |||
summary: Merged changes | |||
</pre><p id="x_34a"><a name="x_34a"></a>In <a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:merge" title="Figure 3.3. Working directory and repository during merge, and following commit">Figure 3.3, “Working directory and repository during merge, and | |||
following commit”</a>, you can see a | |||
representation of what happens to the working directory during | |||
the merge, and how this affects the repository when the commit | |||
happens. During the merge, the working directory has two | |||
parent changesets, and these become the parents of the new | |||
changeset.</p><div class="figure"><a name="fig:tour-merge:merge"></a><p class="title"><b>Figure 3.3. Working directory and repository during merge, and | |||
following commit</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/tour-merge-merge.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_69c"><a name="x_69c"></a>We sometimes talk about a merge having | |||
<span class="emphasis"><em>sides</em></span>: the left side is the first parent | |||
in the output of <span class="command"><strong>hg parents</strong></span>, | |||
and the right side is the second. If the working directory | |||
was at e.g. revision 5 before we began a merge, that revision | |||
will become the left side of the merge.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id354262">Merging conflicting changes</h2></div></div></div><p id="x_34b"><a name="x_34b"></a>Most merges are simple affairs, but sometimes you'll find | |||
yourself merging changes where each side modifies the same portions | |||
of the same files. Unless both modifications are identical, | |||
this results in a <span class="emphasis"><em>conflict</em></span>, where you have | |||
to decide how to reconcile the different changes into something | |||
coherent.</p><div class="figure"><a name="fig:tour-merge:conflict"></a><p class="title"><b>Figure 3.4. Conflicting changes to a document</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/tour-merge-conflict.png" alt="XXX add text"></div></div></div><br class="figure-break"><p id="x_34d"><a name="x_34d"></a><a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:conflict" title="Figure 3.4. Conflicting changes to a document">Figure 3.4, “Conflicting changes to a document”</a> illustrates | |||
an instance of two conflicting changes to a document. We | |||
started with a single version of the file; then we made some | |||
changes; while someone else made different changes to the same | |||
text. Our task in resolving the conflicting changes is to | |||
decide what the file should look like.</p><p id="x_34e"><a name="x_34e"></a>Mercurial doesn't have a built-in facility for handling | |||
conflicts. Instead, it runs an external program, usually one | |||
that displays some kind of graphical conflict resolution | |||
interface. By default, Mercurial tries to find one of several | |||
different merging tools that are likely to be installed on your | |||
system. It first tries a few fully automatic merging tools; if | |||
these don't succeed (because the resolution process requires | |||
human guidance) or aren't present, it tries a few | |||
different graphical merging tools.</p><p id="x_34f"><a name="x_34f"></a>It's also possible to get Mercurial to run a | |||
specific program or script, by setting the | |||
<code class="envar">HGMERGE</code> environment variable to the name of your | |||
preferred program.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id354379">Using a graphical merge tool</h3></div></div></div><p id="x_350"><a name="x_350"></a>My preferred graphical merge tool is | |||
<span class="command"><strong>kdiff3</strong></span>, which I'll use to describe the | |||
features that are common to graphical file merging tools. You | |||
can see a screenshot of <span class="command"><strong>kdiff3</strong></span> in action in | |||
<a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:kdiff3" title="Figure 3.5. Using kdiff3 to merge versions of a file">Figure 3.5, “Using kdiff3 to merge versions of a | |||
file”</a>. The kind of | |||
merge it is performing is called a <span class="emphasis"><em>three-way | |||
merge</em></span>, because there are three different versions | |||
of the file of interest to us. The tool thus splits the upper | |||
portion of the window into three panes:</p><div class="itemizedlist"><ul type="disc"><li><p id="x_351"><a name="x_351"></a>At the left is the <span class="emphasis"><em>base</em></span> | |||
version of the file, i.e. the most recent version from | |||
which the two versions we're trying to merge are | |||
descended.</p></li><li><p id="x_352"><a name="x_352"></a>In the middle is “<span class="quote">our</span>” version of | |||
the file, with the contents that we modified.</p></li><li><p id="x_353"><a name="x_353"></a>On the right is “<span class="quote">their</span>” version | |||
of the file, the one that from the changeset that we're | |||
trying to merge with.</p></li></ul></div><p id="x_354"><a name="x_354"></a>In the pane below these is the current | |||
<span class="emphasis"><em>result</em></span> of the merge. Our task is to | |||
replace all of the red text, which indicates unresolved | |||
conflicts, with some sensible merger of the | |||
“<span class="quote">ours</span>” and “<span class="quote">theirs</span>” versions of the | |||
file.</p><p id="x_355"><a name="x_355"></a>All four of these panes are <span class="emphasis"><em>locked | |||
together</em></span>; if we scroll vertically or horizontally | |||
in any of them, the others are updated to display the | |||
corresponding sections of their respective files.</p><div class="figure"><a name="fig:tour-merge:kdiff3"></a><p class="title"><b>Figure 3.5. Using <span class="command">kdiff3</span> to merge versions of a | |||
file</b></p><div class="figure-contents"><div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" cellspacing="0" cellpadding="0" width="100%"><tr><td><img src="figs/kdiff3.png" width="100%" alt="XXX add text"></td></tr></table></div></div></div><br class="figure-break"><p id="x_357"><a name="x_357"></a>For each conflicting portion of the file, we can choose to | |||
resolve the conflict using some combination of text from the | |||
base version, ours, or theirs. We can also manually edit the | |||
merged file at any time, in case we need to make further | |||
modifications.</p><p id="x_358"><a name="x_358"></a>There are <span class="emphasis"><em>many</em></span> file merging tools | |||
available, too many to cover here. They vary in which | |||
platforms they are available for, and in their particular | |||
strengths and weaknesses. Most are tuned for merging files | |||
containing plain text, while a few are aimed at specialised | |||
file formats (generally XML).</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id354524">A worked example</h3></div></div></div><p id="x_359"><a name="x_359"></a>In this example, we will reproduce the file modification | |||
history of <a class="xref" href="a-tour-of-mercurial-merging-work.html#fig:tour-merge:conflict" title="Figure 3.4. Conflicting changes to a document">Figure 3.4, “Conflicting changes to a document”</a> | |||
above. Let's begin by creating a repository with a base | |||
version of our document.</p><pre id="id354880" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat > letter.txt <<EOF</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Greetings!</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>I am Mariam Abacha, the wife of former</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Nigerian dictator Sani Abacha.</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>EOF</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg add letter.txt</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m '419 scam, first draft'</code></strong> | |||
</pre><p id="x_35a"><a name="x_35a"></a>We'll clone the repository and make a change to the | |||
file.</p><pre id="id354860" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg clone scam scam-cousin</code></strong> | |||
updating working directory | |||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
<code class="prompt">$</code> <strong class="userinput"><code>cd scam-cousin</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>cat > letter.txt <<EOF</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Greetings!</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>I am Shehu Musa Abacha, cousin to the former</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Nigerian dictator Sani Abacha.</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>EOF</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m '419 scam, with cousin'</code></strong> | |||
</pre><p id="x_35b"><a name="x_35b"></a>And another clone, to simulate someone else making a | |||
change to the file. (This hints at the idea that it's not all | |||
that unusual to merge with yourself when you isolate tasks in | |||
separate repositories, and indeed to find and resolve | |||
conflicts while doing so.)</p><pre id="id354843" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg clone scam scam-son</code></strong> | |||
updating working directory | |||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
<code class="prompt">$</code> <strong class="userinput"><code>cd scam-son</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>cat > letter.txt <<EOF</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Greetings!</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>I am Alhaji Abba Abacha, son of the former</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Nigerian dictator Sani Abacha.</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>EOF</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m '419 scam, with son'</code></strong> | |||
</pre><p id="x_35c"><a name="x_35c"></a>Having created two | |||
different versions of the file, we'll set up an environment | |||
suitable for running our merge.</p><pre id="id355540" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg clone scam-cousin scam-merge</code></strong> | |||
updating working directory | |||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
<code class="prompt">$</code> <strong class="userinput"><code>cd scam-merge</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg pull -u ../scam-son</code></strong> | |||
pulling from ../scam-son | |||
searching for changes | |||
adding changesets | |||
adding manifests | |||
adding file changes | |||
added 1 changesets with 1 changes to 1 files (+1 heads) | |||
not updating, since new heads added | |||
(run 'hg heads' to see heads, 'hg merge' to merge) | |||
</pre><p id="x_35d"><a name="x_35d"></a>In this example, I'll set | |||
<code class="envar">HGMERGE</code> to tell Mercurial to use the | |||
non-interactive <span class="command"><strong>merge</strong></span> command. This is | |||
bundled with many Unix-like systems. (If you're following this | |||
example on your computer, don't bother setting | |||
<code class="envar">HGMERGE</code>. You'll get dropped into a GUI file | |||
merge tool instead, which is much preferable.)</p><pre id="id355530" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>export HGMERGE=merge</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg merge</code></strong> | |||
merging letter.txt | |||
merge: warning: conflicts during merge | |||
merging letter.txt failed! | |||
0 files updated, 0 files merged, 0 files removed, 1 files unresolved | |||
use 'hg resolve' to retry unresolved file merges or 'hg up --clean' to abandon | |||
<code class="prompt">$</code> <strong class="userinput"><code>cat letter.txt</code></strong> | |||
Greetings! | |||
<<<<<<< /tmp/tour-merge-conflictgW7-1Z/scam-merge/letter.txt | |||
I am Shehu Musa Abacha, cousin to the former | |||
======= | |||
I am Alhaji Abba Abacha, son of the former | |||
>>>>>>> /tmp/letter.txt~other.c6Rq0s | |||
Nigerian dictator Sani Abacha. | |||
</pre><p id="x_35f"><a name="x_35f"></a>Because <span class="command"><strong>merge</strong></span> can't resolve the | |||
conflicting changes, it leaves <span class="emphasis"><em>merge | |||
markers</em></span> inside the file that has conflicts, | |||
indicating which lines have conflicts, and whether they came | |||
from our version of the file or theirs.</p><p id="x_360"><a name="x_360"></a>Mercurial can tell from the way <span class="command"><strong>merge</strong></span> | |||
exits that it wasn't able to merge successfully, so it tells | |||
us what commands we'll need to run if we want to redo the | |||
merging operation. This could be useful if, for example, we | |||
were running a graphical merge tool and quit because we were | |||
confused or realised we had made a mistake.</p><p id="x_361"><a name="x_361"></a>If automatic or manual merges fail, there's nothing to | |||
prevent us from “<span class="quote">fixing up</span>” the affected files | |||
ourselves, and committing the results of our merge:</p><pre id="id355496" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat > letter.txt <<EOF</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Greetings!</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>I am Bryan O'Sullivan, no relation of the former</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>Nigerian dictator Sani Abacha.</code></strong> | |||
<code class="prompt">></code> <strong class="userinput"><code>EOF</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg resolve -m letter.txt</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg commit -m 'Send me your money'</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg tip</code></strong> | |||
changeset: 3:6f17ad930bf5 | |||
tag: tip | |||
parent: 1:cef8fbca9a6f | |||
parent: 2:dc8f64391590 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Tue May 05 06:55:57 2009 +0000 | |||
summary: Send me your money | |||
</pre><div class="note"><table border="0" summary="Note: Where is the hg resolve command?"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="/support/figs/note.png"></td><th align="left">Where is the hg resolve command?</th></tr><tr><td align="left" valign="top"><p id="x_724"><a name="x_724"></a>The <span class="command"><strong>hg resolve</strong></span> command was introduced | |||
in Mercurial 1.1, which was released in December 2008. If | |||
you are using an older version of Mercurial (run <span class="command"><strong>hg | |||
version</strong></span> to see), this command will not be | |||
present. If your version of Mercurial is older than 1.1, | |||
you should strongly consider upgrading to a newer version | |||
before trying to tackle complicated merges.</p></td></tr></table></div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="sec:tour-merge:fetch">Simplifying the pull-merge-commit sequence</h2></div></div></div><p id="x_362"><a name="x_362"></a>The process of merging changes as outlined above is | |||
straightforward, but requires running three commands in | |||
sequence.</p><pre id="id355698" class="programlisting">hg pull -u | |||
hg merge | |||
hg commit -m 'Merged remote changes'</pre><p id="x_363"><a name="x_363"></a>In the case of the final commit, you also need to enter a | |||
commit message, which is almost always going to be a piece of | |||
uninteresting “<span class="quote">boilerplate</span>” text.</p><p id="x_364"><a name="x_364"></a>It would be nice to reduce the number of steps needed, if | |||
this were possible. Indeed, Mercurial is distributed with an | |||
extension called <code class="literal">fetch</code> that | |||
does just this.</p><p id="x_365"><a name="x_365"></a>Mercurial provides a flexible extension mechanism that lets | |||
people extend its functionality, while keeping the core of | |||
Mercurial small and easy to deal with. Some extensions add new | |||
commands that you can use from the command line, while others | |||
work “<span class="quote">behind the scenes,</span>” for example adding | |||
capabilities to Mercurial's built-in server mode.</p><p id="x_366"><a name="x_366"></a>The <code class="literal">fetch</code> | |||
extension adds a new command called, not surprisingly, <span class="command"><strong>hg fetch</strong></span>. This extension acts as a | |||
combination of <span class="command"><strong>hg pull -u</strong></span>, | |||
<span class="command"><strong>hg merge</strong></span> and <span class="command"><strong>hg commit</strong></span>. It begins by pulling | |||
changes from another repository into the current repository. If | |||
it finds that the changes added a new head to the repository, it | |||
updates to the new head, begins a merge, then (if the merge | |||
succeeded) commits the result of the merge with an | |||
automatically-generated commit message. If no new heads were | |||
added, it updates the working directory to the new tip | |||
changeset.</p><p id="x_367"><a name="x_367"></a>Enabling the <code class="literal">fetch</code> extension is easy. Edit the | |||
<code class="filename">.hgrc</code> file in your home | |||
directory, and either go to the <code class="literal">extensions</code> section or create an | |||
<code class="literal">extensions</code> section. Then | |||
add a line that simply reads | |||
“<span class="quote"><code class="literal">fetch=</code></span>”.</p><pre id="id355838" class="programlisting">[extensions] | |||
fetch =</pre><p id="x_368"><a name="x_368"></a>(Normally, the right-hand side of the | |||
“<span class="quote"><code class="literal">=</code></span>” would indicate where to find | |||
the extension, but since the <code class="literal">fetch</code> extension is in the standard | |||
distribution, Mercurial knows where to search for it.)</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id355904">Renaming, copying, and merging</h2></div></div></div><p id="x_729"><a name="x_729"></a>During the life of a project, we will often want to change | |||
the layout of its files and directories. This can be as simple | |||
as renaming a single file, or as complex as restructuring the | |||
entire hierarchy of files within the project.</p><p id="x_72a"><a name="x_72a"></a>Mercurial supports these kinds of complex changes fluently, | |||
provided we tell it what we're doing. If we want to rename a | |||
file, we should use the <span class="command"><strong>hg rename</strong></span><sup>[<a name="id355926" href="#ftn.id355926" class="footnote">2</a>]</sup> command to rename it, so that Mercurial can do the | |||
right thing later when we merge.</p><p id="x_72c"><a name="x_72c"></a>We will cover the use of these commands in more detail in | |||
<a class="xref" href="mercurial-in-daily-use.html#chap:daily.copy" title="Copying files">the section called “Copying files”</a>.</p></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.id355926" href="#id355926" class="para">2</a>] </sup>If you're a Unix user, you'll be glad to know that the | |||
<span class="command"><strong>hg rename</strong></span> command can be abbreviated as | |||
<span class="command"><strong>hg mv</strong></span>.</p></div></div></div><div class="hgfooter"><p><img src="/support/figs/rss.png"> Want to stay up to date? Subscribe to the comment feed for <a id="chapterfeed" class="feed" href="/feeds/comments/">this chapter</a>, or the <a class="feed" href="/feeds/comments/">entire book</a>.</p><p>Copyright 2006, 2007, 2008, 2009 Bryan O'Sullivan. | |||
Icons by <a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a href="http://mattahan.deviantart.com/">Mattahan</a>.</p></div><div class="navfooter"><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="a-tour-of-mercurial-the-basics.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="behind-the-scenes.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. A tour of Mercurial: the basics </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. Behind the scenes</td></tr></table></div><script type="text/javascript"> | |||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); | |||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); | |||
</script><script type="text/javascript"> | |||
try { | |||
var pageTracker = _gat._getTracker("UA-1805907-5"); | |||
pageTracker._trackPageview(); | |||
} catch(err) {}</script></body></html> |
@ -0,0 +1,826 @@ | |||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Chapter 2. A tour of Mercurial: the basics</title><link rel="stylesheet" href="/support/styles.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.3"><link rel="home" href="index.html" title="Mercurial: The Definitive Guide"><link rel="up" href="index.html" title="Mercurial: The Definitive Guide"><link rel="prev" href="how-did-we-get-here.html" title="Chapter 1. How did we get here?"><link rel="next" href="a-tour-of-mercurial-merging-work.html" title="Chapter 3. A tour of Mercurial: merging work"><link rel="alternate" type="application/atom+xml" title="Comments" href="/feeds/comments/"><link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"><script type="text/javascript" src="/support/jquery-min.js"></script><script type="text/javascript" src="/support/form.js"></script><script type="text/javascript" src="/support/hsbook.js"></script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><h2 class="booktitle"><a href="/">Mercurial: The Definitive Guide</a><span class="authors">by Bryan O'Sullivan</span></h2></div><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 2. A tour of Mercurial: the basics</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="how-did-we-get-here.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="a-tour-of-mercurial-merging-work.html">Next</a></td></tr></table></div><div class="chapter" lang="en" id="chap:tour-basic"><div class="titlepage"><div><div><h2 class="title">Chapter 2. A tour of Mercurial: the basics</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#sec:tour:install">Installing Mercurial on your system</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id344575">Windows</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id344904">Mac OS X</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id344922">Linux</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id344998">Solaris</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id345016">Getting started</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id345318">Built-in help</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id345120">Working with a repository</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id345147">Making a local copy of a repository</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id345415">What's in a repository?</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id345536">A tour through history</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id345833">Changesets, revisions, and talking to other | |||
people</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id345980">Viewing specific revisions</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id346082">More detailed information</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id346408">All about command options</a></span></dt><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id346595">Making and reviewing changes</a></span></dt><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id347157">Recording changes in a new changeset</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id347208">Setting up a username</a></span></dt><dd><dl><dt><span class="sect3"><a href="a-tour-of-mercurial-the-basics.html#sec:tour-basic:username">Creating a Mercurial configuration file</a></span></dt><dt><span class="sect3"><a href="a-tour-of-mercurial-the-basics.html#id347496">Choosing a user name</a></span></dt></dl></dd><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id347526">Writing a commit message</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id347874">Writing a good commit message</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id347674">Aborting a commit</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id347689">Admiring our new handiwork</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id347917">Sharing changes</a></span></dt><dd><dl><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#sec:tour:pull">Pulling changes from another repository</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id348343">Updating the working directory</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id348825">Pushing changes to another repository</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id349161">Default locations</a></span></dt><dt><span class="sect2"><a href="a-tour-of-mercurial-the-basics.html#id349277">Sharing changes over a network</a></span></dt></dl></dd><dt><span class="sect1"><a href="a-tour-of-mercurial-the-basics.html#id349357">Starting a new project</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="sec:tour:install">Installing Mercurial on your system</h2></div></div></div><p id="x_1"><a name="x_1"></a>Prebuilt binary packages of Mercurial are available for | |||
every popular operating system. These make it easy to start | |||
using Mercurial on your computer immediately.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id344575">Windows</h3></div></div></div><p id="x_c"><a name="x_c"></a>The best version of Mercurial for Windows is | |||
TortoiseHg, which can be found at <a class="ulink" href="http://bitbucket.org/tortoisehg/stable/wiki/Home" target="_top">http://bitbucket.org/tortoisehg/stable/wiki/Home</a>. | |||
This package has no external dependencies; it “<span class="quote">just | |||
works</span>”. It provides both command line and graphical | |||
user interfaces.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id344904">Mac OS X</h3></div></div></div><p id="x_a"><a name="x_a"></a>Lee Cantey publishes an installer of Mercurial | |||
for Mac OS X at <a class="ulink" href="http://mercurial.berkwood.com" target="_top">http://mercurial.berkwood.com</a>.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id344922">Linux</h3></div></div></div><p id="x_2"><a name="x_2"></a>Because each Linux distribution has its own packaging | |||
tools, policies, and rate of development, it's difficult to | |||
give a comprehensive set of instructions on how to install | |||
Mercurial binaries. The version of Mercurial that you will | |||
end up with can vary depending on how active the person is who | |||
maintains the package for your distribution.</p><p id="x_3"><a name="x_3"></a>To keep things simple, I will focus on installing | |||
Mercurial from the command line under the most popular Linux | |||
distributions. Most of these distributions provide graphical | |||
package managers that will let you install Mercurial with a | |||
single click; the package name to look for is | |||
<code class="literal">mercurial</code>.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_4"><a name="x_4"></a>Ubuntu and Debian:</p><pre id="id344957" class="programlisting">apt-get install mercurial</pre></li><li><p id="x_5"><a name="x_5"></a>Fedora:</p><pre id="id344968" class="programlisting">yum install mercurial</pre></li><li><p id="x_715"><a name="x_715"></a>OpenSUSE:</p><pre id="id344980" class="programlisting">zypper install mercurial</pre></li><li><p id="x_6"><a name="x_6"></a>Gentoo:</p><pre id="id344991" class="programlisting">emerge mercurial</pre></li></ul></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id344998">Solaris</h3></div></div></div><p id="x_9"><a name="x_9"></a>SunFreeWare, at <a class="ulink" href="http://www.sunfreeware.com" target="_top">http://www.sunfreeware.com</a>, | |||
provides prebuilt packages of Mercurial.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id345016">Getting started</h2></div></div></div><p id="x_e"><a name="x_e"></a>To begin, we'll use the <span class="command"><strong>hg | |||
version</strong></span> command to find out whether Mercurial is | |||
installed properly. The actual version information that it | |||
prints isn't so important; we simply care whether the command | |||
runs and prints anything at all.</p><pre id="id345379" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg version</code></strong> | |||
Mercurial Distributed SCM (version 1.2) | |||
Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others | |||
This is free software; see the source for copying conditions. There is NO | |||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |||
</pre><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id345318">Built-in help</h3></div></div></div><p id="x_f"><a name="x_f"></a>Mercurial provides a built-in help system. This is | |||
invaluable for those times when you find yourself stuck | |||
trying to remember how to run a command. If you are | |||
completely stuck, simply run <span class="command"><strong>hg | |||
help</strong></span>; it will print a brief list of commands, | |||
along with a description of what each does. If you ask for | |||
help on a specific command (as below), it prints more | |||
detailed information.</p><pre id="id345368" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg help init</code></strong> | |||
hg init [-e CMD] [--remotecmd CMD] [DEST] | |||
create a new repository in the given directory | |||
Initialize a new repository in the given directory. If the given | |||
directory does not exist, it is created. | |||
If no directory is given, the current directory is used. | |||
It is possible to specify an ssh:// URL as the destination. | |||
See 'hg help urls' for more information. | |||
options: | |||
-e --ssh specify ssh command to use | |||
--remotecmd specify hg command to run on the remote side | |||
use "hg -v help init" to show global options | |||
</pre><p id="x_10"><a name="x_10"></a>For a more impressive level of detail (which you won't | |||
usually need) run <span class="command"><strong>hg help <code class="option">-v</code></strong></span>. The <code class="option">-v</code> option is short for | |||
<code class="option">--verbose</code>, and tells | |||
Mercurial to print more information than it usually | |||
would.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id345120">Working with a repository</h2></div></div></div><p id="x_11"><a name="x_11"></a>In Mercurial, everything happens inside a | |||
<span class="emphasis"><em>repository</em></span>. The repository for a project | |||
contains all of the files that “<span class="quote">belong to</span>” that | |||
project, along with a historical record of the project's | |||
files.</p><p id="x_12"><a name="x_12"></a>There's nothing particularly magical about a repository; it | |||
is simply a directory tree in your filesystem that Mercurial | |||
treats as special. You can rename or delete a repository any | |||
time you like, using either the command line or your file | |||
browser.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id345147">Making a local copy of a repository</h3></div></div></div><p id="x_13"><a name="x_13"></a><span class="emphasis"><em>Copying</em></span> a repository is just a little | |||
bit special. While you could use a normal file copying | |||
command to make a copy of a repository, it's best to use a | |||
built-in command that Mercurial provides. This command is | |||
called <span class="command"><strong>hg clone</strong></span>, because it | |||
makes an identical copy of an existing repository.</p><pre id="id345593" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg clone https://bitbucket.org/bos/hg-tutorial-hello</code></strong> | |||
destination directory: hello | |||
requesting all changes | |||
adding changesets | |||
adding manifests | |||
adding file changes | |||
added 5 changesets with 5 changes to 2 files | |||
updating working directory | |||
2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
</pre><p id="x_67c"><a name="x_67c"></a>One advantage of using <span class="command"><strong>hg | |||
clone</strong></span> is that, as we can see above, it lets us clone | |||
repositories over the network. Another is that it remembers | |||
where we cloned from, which we'll find useful soon when we | |||
want to fetch new changes from another repository.</p><p id="x_14"><a name="x_14"></a>If our clone succeeded, we should now have a local | |||
directory called <code class="filename">hello</code>. | |||
This directory will contain some files.</p><pre id="id345299" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>ls -l</code></strong> | |||
total 4 | |||
drwxrwxr-x 3 bos bos 4096 May 5 06:55 hello | |||
<code class="prompt">$</code> <strong class="userinput"><code>ls hello</code></strong> | |||
Makefile hello.c | |||
</pre><p id="x_15"><a name="x_15"></a>These files have the same contents and history in our | |||
repository as they do in the repository we cloned.</p><p id="x_16"><a name="x_16"></a>Every Mercurial repository is complete, | |||
self-contained, and independent. It contains its own private | |||
copy of a project's files and history. As we just mentioned, | |||
a cloned repository remembers the location of the repository | |||
it was cloned from, but Mercurial will not communicate with | |||
that repository, or any other, unless you tell it to.</p><p id="x_17"><a name="x_17"></a>What this means for now is that we're free to experiment | |||
with our repository, safe in the knowledge that it's a private | |||
“<span class="quote">sandbox</span>” that won't affect anyone else.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id345415">What's in a repository?</h3></div></div></div><p id="x_18"><a name="x_18"></a>When we take a more detailed look inside a repository, we | |||
can see that it contains a directory named <code class="filename">.hg</code>. This is where Mercurial | |||
keeps all of its metadata for the repository.</p><pre id="id345568" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd hello</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>ls -a</code></strong> | |||
. .. .hg Makefile hello.c | |||
</pre><p id="x_19"><a name="x_19"></a>The contents of the <code class="filename">.hg</code> directory and its | |||
subdirectories are private to Mercurial. Every other file and | |||
directory in the repository is yours to do with as you | |||
please.</p><p id="x_1a"><a name="x_1a"></a>To introduce a little terminology, the <code class="filename">.hg</code> directory is the | |||
“<span class="quote">real</span>” repository, and all of the files and | |||
directories that coexist with it are said to live in the | |||
<span class="emphasis"><em>working directory</em></span>. An easy way to | |||
remember the distinction is that the | |||
<span class="emphasis"><em>repository</em></span> contains the | |||
<span class="emphasis"><em>history</em></span> of your project, while the | |||
<span class="emphasis"><em>working directory</em></span> contains a | |||
<span class="emphasis"><em>snapshot</em></span> of your project at a particular | |||
point in history.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id345536">A tour through history</h2></div></div></div><p id="x_1b"><a name="x_1b"></a>One of the first things we might want to do with a new, | |||
unfamiliar repository is understand its history. The <span class="command"><strong>hg log</strong></span> command gives us a view of | |||
the history of changes in the repository.</p><pre id="id345930" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log</code></strong> | |||
changeset: 4:2278160e78d4 | |||
tag: tip | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:16:53 2008 +0200 | |||
summary: Trim comments. | |||
changeset: 3:0272e0d5a517 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:08:02 2008 +0200 | |||
summary: Get make to generate the final binary from a .o file. | |||
changeset: 2:fef857204a0c | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:05:04 2008 +0200 | |||
summary: Introduce a typo into hello.c. | |||
changeset: 1:82e55d328c8c | |||
user: mpm@selenic.com | |||
date: Fri Aug 26 01:21:28 2005 -0700 | |||
summary: Create a makefile | |||
changeset: 0:0a04b987be5a | |||
user: mpm@selenic.com | |||
date: Fri Aug 26 01:20:50 2005 -0700 | |||
summary: Create a standard "hello, world" program | |||
</pre><p id="x_1c"><a name="x_1c"></a>By default, this command prints a brief paragraph of output | |||
for each change to the project that was recorded. In Mercurial | |||
terminology, we call each of these recorded events a | |||
<span class="emphasis"><em>changeset</em></span>, because it can contain a record | |||
of changes to several files.</p><p id="x_1d"><a name="x_1d"></a>The fields in a record of output from <span class="command"><strong>hg log</strong></span> are as follows.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_1e"><a name="x_1e"></a><code class="literal">changeset</code>: This | |||
field has the format of a number, followed by a colon, | |||
followed by a hexadecimal (or <span class="emphasis"><em>hex</em></span>) | |||
string. These are <span class="emphasis"><em>identifiers</em></span> for the | |||
changeset. The hex string is a unique identifier: the same | |||
hex string will always refer to the same changeset in every | |||
copy of this repository. The | |||
number is shorter and easier to type than the hex string, | |||
but it isn't unique: the same number in two different clones | |||
of a repository may identify different changesets.</p></li><li><p id="x_1f"><a name="x_1f"></a><code class="literal">user</code>: The identity of the | |||
person who created the changeset. This is a free-form | |||
field, but it most often contains a person's name and email | |||
address.</p></li><li><p id="x_20"><a name="x_20"></a><code class="literal">date</code>: The date and time on | |||
which the changeset was created, and the timezone in which | |||
it was created. (The date and time are local to that | |||
timezone; they display what time and date it was for the | |||
person who created the changeset.)</p></li><li><p id="x_21"><a name="x_21"></a><code class="literal">summary</code>: The first line of | |||
the text message that the creator of the changeset entered | |||
to describe the changeset.</p></li><li><p id="x_67d"><a name="x_67d"></a>Some changesets, such as the first in the list above, | |||
have a <code class="literal">tag</code> field. A tag is another way | |||
to identify a changeset, by giving it an easy-to-remember | |||
name. (The tag named <code class="literal">tip</code> is special: it | |||
always refers to the newest change in a repository.)</p></li></ul></div><p id="x_22"><a name="x_22"></a>The default output printed by <span class="command"><strong>hg log</strong></span> is purely a summary; it is | |||
missing a lot of detail.</p><p id="x_23"><a name="x_23"></a><a class="xref" href="a-tour-of-mercurial-the-basics.html#fig:tour-basic:history" title="Figure 2.1. Graphical history of the hello repository">Figure 2.1, “Graphical history of the hello repository”</a> provides | |||
a graphical representation of the history of the <code class="filename">hello</code> repository, to make it a | |||
little easier to see which direction history is | |||
“<span class="quote">flowing</span>” in. We'll be returning to this figure | |||
several times in this chapter and the chapter that | |||
follows.</p><div class="figure"><a name="fig:tour-basic:history"></a><p class="title"><b>Figure 2.1. Graphical history of the <code class="filename">hello</code> repository</b></p><div class="figure-contents"><div class="mediaobject"><img src="figs/tour-history.png" alt="XXX add text"></div></div></div><br class="figure-break"><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id345833">Changesets, revisions, and talking to other | |||
people</h3></div></div></div><p id="x_25"><a name="x_25"></a>As English is a notoriously sloppy language, and computer | |||
science has a hallowed history of terminological confusion | |||
(why use one term when four will do?), revision control has a | |||
variety of words and phrases that mean the same thing. If you | |||
are talking about Mercurial history with other people, you | |||
will find that the word “<span class="quote">changeset</span>” is often | |||
compressed to “<span class="quote">change</span>” or (when written) | |||
“<span class="quote">cset</span>”, and sometimes a changeset is referred to | |||
as a “<span class="quote">revision</span>” or a “<span class="quote">rev</span>”.</p><p id="x_26"><a name="x_26"></a>While it doesn't matter what <span class="emphasis"><em>word</em></span> you | |||
use to refer to the concept of “<span class="quote">a changeset</span>”, the | |||
<span class="emphasis"><em>identifier</em></span> that you use to refer to | |||
“<span class="quote">a <span class="emphasis"><em>specific</em></span> changeset</span>” is of | |||
great importance. Recall that the <code class="literal">changeset</code> | |||
field in the output from <span class="command"><strong>hg | |||
log</strong></span> identifies a changeset using both a number and | |||
a hexadecimal string.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_27"><a name="x_27"></a>The revision number is a handy | |||
notation that is <span class="emphasis"><em>only valid in that | |||
repository</em></span>.</p></li><li><p id="x_28"><a name="x_28"></a>The hexadecimal string is the | |||
<span class="emphasis"><em>permanent, unchanging identifier</em></span> that | |||
will always identify that exact changeset in | |||
<span class="emphasis"><em>every</em></span> copy of the | |||
repository.</p></li></ul></div><p id="x_29"><a name="x_29"></a>This distinction is important. If you send | |||
someone an email talking about “<span class="quote">revision 33</span>”, | |||
there's a high likelihood that their revision 33 will | |||
<span class="emphasis"><em>not be the same</em></span> as yours. The reason for | |||
this is that a revision number depends on the order in which | |||
changes arrived in a repository, and there is no guarantee | |||
that the same changes will happen in the same order in | |||
different repositories. Three changes <code class="literal">a,b,c</code> | |||
can easily appear in one repository as | |||
<code class="literal">0,1,2</code>, while in another as | |||
<code class="literal">0,2,1</code>.</p><p id="x_2a"><a name="x_2a"></a>Mercurial uses revision numbers purely as a convenient | |||
shorthand. If you need to discuss a changeset with someone, | |||
or make a record of a changeset for some other reason (for | |||
example, in a bug report), use the hexadecimal | |||
identifier.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id345980">Viewing specific revisions</h3></div></div></div><p id="x_2b"><a name="x_2b"></a>To narrow the output of <span class="command"><strong>hg | |||
log</strong></span> down to a single revision, use the <code class="option">-r</code> (or <code class="option">--rev</code>) option. You can use | |||
either a revision number or a hexadecimal identifier, | |||
and you can provide as many revisions as you want.</p><pre id="id346352" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log -r 3</code></strong> | |||
changeset: 3:0272e0d5a517 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:08:02 2008 +0200 | |||
summary: Get make to generate the final binary from a .o file. | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg log -r 0272e0d5a517</code></strong> | |||
changeset: 3:0272e0d5a517 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:08:02 2008 +0200 | |||
summary: Get make to generate the final binary from a .o file. | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg log -r 1 -r 4</code></strong> | |||
changeset: 1:82e55d328c8c | |||
user: mpm@selenic.com | |||
date: Fri Aug 26 01:21:28 2005 -0700 | |||
summary: Create a makefile | |||
changeset: 4:2278160e78d4 | |||
tag: tip | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:16:53 2008 +0200 | |||
summary: Trim comments. | |||
</pre><p id="x_2c"><a name="x_2c"></a>If you want to see the history of several revisions | |||
without having to list each one, you can use <span class="emphasis"><em>range | |||
notation</em></span>; this lets you express the idea “<span class="quote">I | |||
want all revisions between <code class="literal">abc</code> and | |||
<code class="literal">def</code>, inclusive</span>”.</p><pre id="id346245" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log -r 2:4</code></strong> | |||
changeset: 2:fef857204a0c | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:05:04 2008 +0200 | |||
summary: Introduce a typo into hello.c. | |||
changeset: 3:0272e0d5a517 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:08:02 2008 +0200 | |||
summary: Get make to generate the final binary from a .o file. | |||
changeset: 4:2278160e78d4 | |||
tag: tip | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:16:53 2008 +0200 | |||
summary: Trim comments. | |||
</pre><p id="x_2d"><a name="x_2d"></a>Mercurial also honours the order in which you specify | |||
revisions, so <span class="command"><strong>hg log -r 2:4</strong></span> | |||
prints 2, 3, and 4. while <span class="command"><strong>hg log -r | |||
4:2</strong></span> prints 4, 3, and 2.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id346082">More detailed information</h3></div></div></div><p id="x_2e"><a name="x_2e"></a>While the summary information printed by <span class="command"><strong>hg log</strong></span> is useful if you already know | |||
what you're looking for, you may need to see a complete | |||
description of the change, or a list of the files changed, if | |||
you're trying to decide whether a changeset is the one you're | |||
looking for. The <span class="command"><strong>hg log</strong></span> | |||
command's <code class="option">-v</code> (or <code class="option">--verbose</code>) option gives you | |||
this extra detail.</p><pre id="id346186" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log -v -r 3</code></strong> | |||
changeset: 3:0272e0d5a517 | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:08:02 2008 +0200 | |||
files: Makefile | |||
description: | |||
Get make to generate the final binary from a .o file. | |||
</pre><p id="x_2f"><a name="x_2f"></a>If you want to see both the description and | |||
content of a change, add the <code class="option">-p</code> (or <code class="option">--patch</code>) option. This displays | |||
the content of a change as a <span class="emphasis"><em>unified diff</em></span> | |||
(if you've never seen a unified diff before, see <a class="xref" href="managing-change-with-mercurial-queues.html#sec:mq:patch" title="Understanding patches">the section called “Understanding patches”</a> for an overview).</p><pre id="id346230" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg log -v -p -r 2</code></strong> | |||
changeset: 2:fef857204a0c | |||
user: Bryan O'Sullivan <bos@serpentine.com> | |||
date: Sat Aug 16 22:05:04 2008 +0200 | |||
files: hello.c | |||
description: | |||
Introduce a typo into hello.c. | |||
diff -r 82e55d328c8c -r fef857204a0c hello.c | |||
--- a/hello.c Fri Aug 26 01:21:28 2005 -0700 | |||
+++ b/hello.c Sat Aug 16 22:05:04 2008 +0200 | |||
@@ -11,6 +11,6 @@ | |||
int main(int argc, char **argv) | |||
{ | |||
- printf("hello, world!\n"); | |||
+ printf("hello, world!\"); | |||
return 0; | |||
} | |||
</pre><p id="x_67e"><a name="x_67e"></a>The <code class="option">-p</code> option is | |||
tremendously useful, so it's well worth remembering.</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id346408">All about command options</h2></div></div></div><p id="x_30"><a name="x_30"></a>Let's take a brief break from exploring Mercurial commands | |||
to discuss a pattern in the way that they work; you may find | |||
this useful to keep in mind as we continue our tour.</p><p id="x_31"><a name="x_31"></a>Mercurial has a consistent and straightforward approach to | |||
dealing with the options that you can pass to commands. It | |||
follows the conventions for options that are common to modern | |||
Linux and Unix systems.</p><div class="itemizedlist"><ul type="disc"><li><p id="x_32"><a name="x_32"></a>Every option has a long name. For example, as | |||
we've already seen, the <span class="command"><strong>hg | |||
log</strong></span> command accepts a <code class="option">--rev</code> option.</p></li><li><p id="x_33"><a name="x_33"></a>Most options have short names, too. Instead | |||
of <code class="option">--rev</code>, we can use | |||
<code class="option">-r</code>. (The reason that | |||
some options don't have short names is that the options in | |||
question are rarely used.)</p></li><li><p id="x_34"><a name="x_34"></a>Long options start with two dashes (e.g. | |||
<code class="option">--rev</code>), while short | |||
options start with one (e.g. <code class="option">-r</code>).</p></li><li><p id="x_35"><a name="x_35"></a>Option naming and usage is consistent across | |||
commands. For example, every command that lets you specify | |||
a changeset ID or revision number accepts both <code class="option">-r</code> and <code class="option">--rev</code> arguments.</p></li><li><p id="x_67f"><a name="x_67f"></a>If you are using short options, you can save typing by | |||
running them together. For example, the command <span class="command"><strong>hg log -v -p -r 2</strong></span> can be written | |||
as <span class="command"><strong>hg log -vpr2</strong></span>.</p></li></ul></div><p id="x_36"><a name="x_36"></a>In the examples throughout this book, I usually | |||
use short options instead of long. This simply reflects my own | |||
preference, so don't read anything significant into it.</p><p id="x_37"><a name="x_37"></a>Most commands that print output of some kind will print more | |||
output when passed a <code class="option">-v</code> | |||
(or <code class="option">--verbose</code>) option, and | |||
less when passed <code class="option">-q</code> (or | |||
<code class="option">--quiet</code>).</p><div class="note"><table border="0" summary="Note: Option naming consistency"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="/support/figs/note.png"></td><th align="left">Option naming consistency</th></tr><tr><td align="left" valign="top"><p id="x_680"><a name="x_680"></a>Almost always, Mercurial commands use consistent option | |||
names to refer to the same concepts. For instance, if a | |||
command deals with changesets, you'll always identify them | |||
with <code class="option">--rev</code> or <code class="option">-r</code>. This consistent use of | |||
option names makes it easier to remember what options a | |||
particular command takes.</p></td></tr></table></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id346595">Making and reviewing changes</h2></div></div></div><p id="x_38"><a name="x_38"></a>Now that we have a grasp of viewing history in Mercurial, | |||
let's take a look at making some changes and examining | |||
them.</p><p id="x_39"><a name="x_39"></a>The first thing we'll do is isolate our experiment in a | |||
repository of its own. We use the <span class="command"><strong>hg | |||
clone</strong></span> command, but we don't need to clone a copy of | |||
the remote repository. Since we already have a copy of it | |||
locally, we can just clone that instead. This is much faster | |||
than cloning over the network, and cloning a local repository | |||
uses less disk space in most cases, too<sup>[<a name="id346621" href="#ftn.id346621" class="footnote">1</a>]</sup>.</p><pre id="id344876" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cd ..</code></strong> | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg clone hello my-hello</code></strong> | |||
updating working directory | |||
2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
<code class="prompt">$</code> <strong class="userinput"><code>cd my-hello</code></strong> | |||
</pre><p id="x_3a"><a name="x_3a"></a>As an aside, it's often good practice to keep a | |||
“<span class="quote">pristine</span>” copy of a remote repository around, | |||
which you can then make temporary clones of to create sandboxes | |||
for each task you want to work on. This lets you work on | |||
multiple tasks in parallel, each isolated from the others until | |||
it's complete and you're ready to integrate it back. Because | |||
local clones are so cheap, there's almost no overhead to cloning | |||
and destroying repositories whenever you want.</p><p id="x_3b"><a name="x_3b"></a>In our <code class="filename">my-hello</code> | |||
repository, we have a file <code class="filename">hello.c</code> that | |||
contains the classic “<span class="quote">hello, world</span>” program.</p><pre id="id347024" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>cat hello.c</code></strong> | |||
/* | |||
* Placed in the public domain by Bryan O'Sullivan. This program is | |||
* not covered by patents in the United States or other countries. | |||
*/ | |||
#include <stdio.h> | |||
int main(int argc, char **argv) | |||
{ | |||
printf("hello, world!\"); | |||
return 0; | |||
} | |||
</pre><p id="x_682"><a name="x_682"></a>Let's edit this file so that it prints a second line of | |||
output.</p><pre id="id346984" class="screen"># ... edit edit edit ... | |||
<code class="prompt">$</code> <strong class="userinput"><code>cat hello.c</code></strong> | |||
/* | |||
* Placed in the public domain by Bryan O'Sullivan. This program is | |||
* not covered by patents in the United States or other countries. | |||
*/ | |||
#include <stdio.h> | |||
int main(int argc, char **argv) | |||
{ | |||
printf("hello, world!\"); | |||
printf("hello again!\n"); | |||
return 0; | |||
} | |||
</pre><p id="x_3c"><a name="x_3c"></a>Mercurial's <span class="command"><strong>hg status</strong></span> | |||
command will tell us what Mercurial knows about the files in the | |||
repository.</p><pre id="id346930" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>ls</code></strong> | |||
Makefile hello.c | |||
<code class="prompt">$</code> <strong class="userinput"><code>hg status</code></strong> | |||
M hello.c | |||
</pre><p id="x_3d"><a name="x_3d"></a>The <span class="command"><strong>hg status</strong></span> command | |||
prints no output for some files, but a line starting with | |||
“<span class="quote"><code class="literal">M</code></span>” for | |||
<code class="filename">hello.c</code>. Unless you tell it to, <span class="command"><strong>hg status</strong></span> will not print any output | |||
for files that have not been modified.</p><p id="x_3e"><a name="x_3e"></a>The “<span class="quote"><code class="literal">M</code></span>” indicates that | |||
Mercurial has noticed that we modified | |||
<code class="filename">hello.c</code>. We didn't need to | |||
<span class="emphasis"><em>inform</em></span> Mercurial that we were going to | |||
modify the file before we started, or that we had modified the | |||
file after we were done; it was able to figure this out | |||
itself.</p><p id="x_3f"><a name="x_3f"></a>It's somewhat helpful to know that we've modified | |||
<code class="filename">hello.c</code>, but we might prefer to know | |||
exactly <span class="emphasis"><em>what</em></span> changes we've made to it. To | |||
do this, we use the <span class="command"><strong>hg diff</strong></span> | |||
command.</p><pre id="id347442" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg diff</code></strong> | |||
diff -r 2278160e78d4 hello.c | |||
--- a/hello.c Sat Aug 16 22:16:53 2008 +0200 | |||
+++ b/hello.c Tue May 05 06:55:53 2009 +0000 | |||
@@ -8,5 +8,6 @@ | |||
int main(int argc, char **argv) | |||
{ | |||
printf("hello, world!\"); | |||
+ printf("hello again!\n"); | |||
return 0; | |||
} | |||
</pre><div class="tip"><table border="0" summary="Tip: Understanding patches"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="/support/figs/tip.png"></td><th align="left">Understanding patches</th></tr><tr><td align="left" valign="top"><p id="x_683"><a name="x_683"></a>Remember to take a look at <a class="xref" href="managing-change-with-mercurial-queues.html#sec:mq:patch" title="Understanding patches">the section called “Understanding patches”</a> if you don't know how to read | |||
output above.</p></td></tr></table></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="id347157">Recording changes in a new changeset</h2></div></div></div><p id="x_40"><a name="x_40"></a>We can modify files, build and test our changes, and use | |||
<span class="command"><strong>hg status</strong></span> and <span class="command"><strong>hg diff</strong></span> to review our changes, until | |||
we're satisfied with what we've done and arrive at a natural | |||
stopping point where we want to record our work in a new | |||
changeset.</p><p id="x_41"><a name="x_41"></a>The <span class="command"><strong>hg commit</strong></span> command lets | |||
us create a new changeset; we'll usually refer to this as | |||
“<span class="quote">making a commit</span>” or | |||
“<span class="quote">committing</span>”.</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id347208">Setting up a username</h3></div></div></div><p id="x_42"><a name="x_42"></a>When you try to run <span class="command"><strong>hg | |||
commit</strong></span> for the first time, it is not guaranteed to | |||
succeed. Mercurial records your name and address with each | |||
change that you commit, so that you and others will later be | |||
able to tell who made each change. Mercurial tries to | |||
automatically figure out a sensible username to commit the | |||
change with. It will attempt each of the following methods, | |||
in order:</p><div class="orderedlist"><ol type="1"><li><p id="x_43"><a name="x_43"></a>If you specify a <code class="option">-u</code> option to the <span class="command"><strong>hg commit</strong></span> command on the command | |||
line, followed by a username, this is always given the | |||
highest precedence.</p></li><li><p id="x_44"><a name="x_44"></a>If you have set the <code class="envar">HGUSER</code> | |||
environment variable, this is checked | |||
next.</p></li><li><p id="x_45"><a name="x_45"></a>If you create a file in your home | |||
directory called <code class="filename">.hgrc</code>, with a <code class="envar">username</code> entry, that will be | |||
used next. To see what the contents of this file should | |||
look like, refer to <a class="xref" href="a-tour-of-mercurial-the-basics.html#sec:tour-basic:username" title="Creating a Mercurial configuration file">the section called “Creating a Mercurial configuration file”</a> | |||
below.</p></li><li><p id="x_46"><a name="x_46"></a>If you have set the <code class="envar">EMAIL</code> | |||
environment variable, this will be used | |||
next.</p></li><li><p id="x_47"><a name="x_47"></a>Mercurial will query your system to find out | |||
your local user name and host name, and construct a | |||
username from these components. Since this often results | |||
in a username that is not very useful, it will print a | |||
warning if it has to do | |||
this.</p></li></ol></div><p id="x_48"><a name="x_48"></a>If all of these mechanisms fail, Mercurial will | |||
fail, printing an error message. In this case, it will not | |||
let you commit until you set up a | |||
username.</p><p id="x_49"><a name="x_49"></a>You should think of the <code class="envar">HGUSER</code> environment | |||
variable and the <code class="option">-u</code> | |||
option to the <span class="command"><strong>hg commit</strong></span> | |||
command as ways to <span class="emphasis"><em>override</em></span> Mercurial's | |||
default selection of username. For normal use, the simplest | |||
and most robust way to set a username for yourself is by | |||
creating a <code class="filename">.hgrc</code> file; see | |||
below for details.</p><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title" id="sec:tour-basic:username">Creating a Mercurial configuration file</h4></div></div></div><p id="x_4a"><a name="x_4a"></a>To set a user name, use your favorite editor | |||
to create a file called <code class="filename">.hgrc</code> in your home directory. | |||
Mercurial will use this file to look up your personalised | |||
configuration settings. The initial contents of your | |||
<code class="filename">.hgrc</code> should look like | |||
this.</p><div class="tip"><table border="0" summary="Tip: Home directory on Windows"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="/support/figs/tip.png"></td><th align="left">Home directory on Windows</th></tr><tr><td align="left" valign="top"><p id="x_716"><a name="x_716"></a>When we refer to your home directory, on an English | |||
language installation of Windows this will usually be a | |||
folder named after your user name in | |||
<code class="filename">C:\Documents and Settings</code>. You can | |||
find out the exact name of your home directory by opening | |||
a command prompt window and running the following | |||
command.</p><pre id="id347422" class="screen"><code class="prompt">C:\></code> <strong class="userinput"><code>echo %UserProfile%</code></strong></pre></td></tr></table></div><pre id="id347447" class="programlisting"># This is a Mercurial configuration file. | |||
[ui] | |||
username = Firstname Lastname <email.address@example.net></pre><p id="x_4b"><a name="x_4b"></a>The “<span class="quote"><code class="literal">[ui]</code></span>” line begins a | |||
<span class="emphasis"><em>section</em></span> of the config file, so you can | |||
read the “<span class="quote"><code class="literal">username = ...</code></span>” | |||
line as meaning “<span class="quote">set the value of the | |||
<code class="literal">username</code> item in the | |||
<code class="literal">ui</code> section</span>”. A section continues | |||
until a new section begins, or the end of the file. | |||
Mercurial ignores empty lines and treats any text from | |||
“<span class="quote"><code class="literal">#</code></span>” to the end of a line as | |||
a comment.</p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title" id="id347496">Choosing a user name</h4></div></div></div><p id="x_4c"><a name="x_4c"></a>You can use any text you like as the value of | |||
the <code class="literal">username</code> config item, since this | |||
information is for reading by other people, but will not be | |||
interpreted by Mercurial. The convention that most people | |||
follow is to use their name and email address, as in the | |||
example above.</p><div class="note"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="/support/figs/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p id="x_4d"><a name="x_4d"></a>Mercurial's built-in web server obfuscates | |||
email addresses, to make it more difficult for the email | |||
harvesting tools that spammers use. This reduces the | |||
likelihood that you'll start receiving more junk email if | |||
you publish a Mercurial repository on the | |||
web.</p></td></tr></table></div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title" id="id347526">Writing a commit message</h3></div></div></div><p id="x_4e"><a name="x_4e"></a>When we commit a change, Mercurial drops us into | |||
a text editor, to enter a message that will describe the | |||
modifications we've made in this changeset. This is called | |||
the <span class="emphasis"><em>commit message</em></span>. It will be a record | |||
for readers of what we did and why, and it will be printed by | |||
<span class="command"><strong>hg log</strong></span> after we've finished | |||
committing.</p><pre id="id347893" class="screen"><code class="prompt">$</code> <strong class="userinput"><code>hg commit</code></strong> | |||
</pre><p id="x_4f"><a name="x_4f"></a>The editor that the <span class="command"><strong>hg | |||
commit</strong></span> command drops us into will contain an empty | |||
line or two, followed by a number of lines starting with | |||
“<span class="quote"><code class="literal">HG:</code></span>”.</p><pre id="id347851" class="programlisting"> | |||
This is where I type my commit comment. | |||
HG: Enter commit message. Lines beginning with 'HG:' are removed. | |||
HG: -- | |||
HG: user: Bryan O'Sullivan <bos@serpentine.com> | |||
HG: branch 'default' | |||
HG: changed hello.c</pre><p id="x_50"><a name="x_50"></a>Mercurial ignores the lines that start with | |||
“<span class="quote"><code class="literal">HG:</code></span>”; it uses them only to | |||
tell us which files it's recording changes to. Modifying or | |||
deleting these lines has no effect.</p></div><div class=" |