hgbook
changeset 553:863a82f13901
Basic progress on XML.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Thu Feb 05 22:45:48 2009 -0800 (2009-02-05) |
parents | cf006cabe489 |
children | b08f6a61bf15 |
files | en/00book.xml en/ch01-intro.xml en/ch02-tour-basic.xml |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/en/00book.xml Thu Feb 05 22:45:48 2009 -0800 1.3 @@ -0,0 +1,43 @@ 1.4 +<?xml version="1.0" encoding="UTF-8"?> 1.5 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 1.6 +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" 1.7 + "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" 1.8 +[ 1.9 +<!-- Below are references to files in this directory. --> 1.10 + 1.11 +<!-- Chapters. --> 1.12 + 1.13 +<!ENTITY ch01 SYSTEM "ch01-intro.xml"> 1.14 +<!ENTITY ch02 SYSTEM "ch02-tour-basic.xml"> 1.15 + 1.16 +<!-- Include our standard shortcuts. --> 1.17 + 1.18 +<!ENTITY % SHORTCUTS SYSTEM "book-shortcuts.xml"> 1.19 +%SHORTCUTS; 1.20 +]> 1.21 + 1.22 +<book id="hg"> 1.23 + <title>Mercurial: The Definitive Guide</title> 1.24 + <bookinfo> 1.25 + <authorgroup> 1.26 + <author> 1.27 + <firstname>Bryan</firstname> 1.28 + <surname>O'Sullivan</surname> 1.29 + </author> 1.30 + </authorgroup> 1.31 + 1.32 + <editor> 1.33 + <firstname>Mike</firstname> 1.34 + <surname>Loukides</surname> 1.35 + </editor> 1.36 + 1.37 + <copyright> 1.38 + <year>2007</year> 1.39 + <year>2008</year> 1.40 + <holder>Bryan O'Sullivan</holder> 1.41 + </copyright> 1.42 + </bookinfo> 1.43 + 1.44 + &ch01; 1.45 + &ch02; 1.46 +</book>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/en/ch01-intro.xml Thu Feb 05 22:45:48 2009 -0800 2.3 @@ -0,0 +1,680 @@ 2.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 2.5 + 2.6 +<chapter> 2.7 + <title>Introduction</title> 2.8 + <para>\label{chap:intro}</para> 2.9 + 2.10 + <sect1> 2.11 + <title>About revision control</title> 2.12 + 2.13 + <para>Revision control is the process of managing multiple 2.14 + versions of a piece of information. In its simplest form, this 2.15 + is something that many people do by hand: every time you modify 2.16 + a file, save it under a new name that contains a number, each 2.17 + one higher than the number of the preceding version.</para> 2.18 + 2.19 + <para>Manually managing multiple versions of even a single file is 2.20 + an error-prone task, though, so software tools to help automate 2.21 + this process have long been available. The earliest automated 2.22 + revision control tools were intended to help a single user to 2.23 + manage revisions of a single file. Over the past few decades, 2.24 + the scope of revision control tools has expanded greatly; they 2.25 + now manage multiple files, and help multiple people to work 2.26 + together. The best modern revision control tools have no 2.27 + problem coping with thousands of people working together on 2.28 + projects that consist of hundreds of thousands of files.</para> 2.29 + 2.30 + <sect2> 2.31 + <title>Why use revision control?</title> 2.32 + 2.33 + <para>There are a number of reasons why you or your team might 2.34 + want to use an automated revision control tool for a 2.35 + project.</para> 2.36 + <itemizedlist> 2.37 + <listitem><para>It will track the history and evolution of 2.38 + your project, so you don't have to. For every change, 2.39 + you'll have a log of <emphasis>who</emphasis> made it; 2.40 + <emphasis>why</emphasis> they made it; 2.41 + <emphasis>when</emphasis> they made it; and 2.42 + <emphasis>what</emphasis> the change 2.43 + was.</para></listitem> 2.44 + <listitem><para>When you're working with other people, 2.45 + revision control software makes it easier for you to 2.46 + collaborate. For example, when people more or less 2.47 + simultaneously make potentially incompatible changes, the 2.48 + software will help you to identify and resolve those 2.49 + conflicts.</para></listitem> 2.50 + <listitem><para>It can help you to recover from mistakes. If 2.51 + you make a change that later turns out to be in error, you 2.52 + can revert to an earlier version of one or more files. In 2.53 + fact, a <emphasis>really</emphasis> good revision control 2.54 + tool will even help you to efficiently figure out exactly 2.55 + when a problem was introduced (see section <xref 2.56 + id="sec:undo:bisect"/> for details).</para></listitem> 2.57 + <listitem><para>It will help you to work simultaneously on, 2.58 + and manage the drift between, multiple versions of your 2.59 + project.</para></listitem></itemizedlist> 2.60 + <para>Most of these reasons are equally valid---at least in 2.61 + theory---whether you're working on a project by yourself, or 2.62 + with a hundred other people.</para> 2.63 + 2.64 + <para>A key question about the practicality of revision control 2.65 + at these two different scales (<quote>lone hacker</quote> and 2.66 + <quote>huge team</quote>) is how its 2.67 + <emphasis>benefits</emphasis> compare to its 2.68 + <emphasis>costs</emphasis>. A revision control tool that's 2.69 + difficult to understand or use is going to impose a high 2.70 + cost.</para> 2.71 + 2.72 + <para>A five-hundred-person project is likely to collapse under 2.73 + its own weight almost immediately without a revision control 2.74 + tool and process. In this case, the cost of using revision 2.75 + control might hardly seem worth considering, since 2.76 + <emphasis>without</emphasis> it, failure is almost 2.77 + guaranteed.</para> 2.78 + 2.79 + <para>On the other hand, a one-person <quote>quick hack</quote> 2.80 + might seem like a poor place to use a revision control tool, 2.81 + because surely the cost of using one must be close to the 2.82 + overall cost of the project. Right?</para> 2.83 + 2.84 + <para>Mercurial uniquely supports <emphasis>both</emphasis> of 2.85 + these scales of development. You can learn the basics in just 2.86 + a few minutes, and due to its low overhead, you can apply 2.87 + revision control to the smallest of projects with ease. Its 2.88 + simplicity means you won't have a lot of abstruse concepts or 2.89 + command sequences competing for mental space with whatever 2.90 + you're <emphasis>really</emphasis> trying to do. At the same 2.91 + time, Mercurial's high performance and peer-to-peer nature let 2.92 + you scale painlessly to handle large projects.</para> 2.93 + 2.94 + <para>No revision control tool can rescue a poorly run project, 2.95 + but a good choice of tools can make a huge difference to the 2.96 + fluidity with which you can work on a project.</para> 2.97 + 2.98 + </sect2> 2.99 + <sect2> 2.100 + <title>The many names of revision control</title> 2.101 + 2.102 + <para>Revision control is a diverse field, so much so that it 2.103 + doesn't actually have a single name or acronym. Here are a 2.104 + few of the more common names and acronyms you'll 2.105 + encounter:</para> 2.106 + <itemizedlist> 2.107 + <listitem><para>Revision control (RCS)</para></listitem> 2.108 + <listitem><para>Software configuration management (SCM), or 2.109 + configuration management</para></listitem> 2.110 + <listitem><para>Source code management</para></listitem> 2.111 + <listitem><para>Source code control, or source 2.112 + control</para></listitem> 2.113 + <listitem><para>Version control 2.114 + (VCS)</para></listitem></itemizedlist> 2.115 + <para>Some people claim that these terms actually have different 2.116 + meanings, but in practice they overlap so much that there's no 2.117 + agreed or even useful way to tease them apart.</para> 2.118 + 2.119 + </sect2> 2.120 + </sect1> 2.121 + <sect1> 2.122 + <title>A short history of revision control</title> 2.123 + 2.124 + <para>The best known of the old-time revision control tools is 2.125 + SCCS (Source Code Control System), which Marc Rochkind wrote at 2.126 + Bell Labs, in the early 1970s. SCCS operated on individual 2.127 + files, and required every person working on a project to have 2.128 + access to a shared workspace on a single system. Only one 2.129 + person could modify a file at any time; arbitration for access 2.130 + to files was via locks. It was common for people to lock files, 2.131 + and later forget to unlock them, preventing anyone else from 2.132 + modifying those files without the help of an 2.133 + administrator.</para> 2.134 + 2.135 + <para>Walter Tichy developed a free alternative to SCCS in the 2.136 + early 1980s; he called his program RCS (Revison Control System). 2.137 + Like SCCS, RCS required developers to work in a single shared 2.138 + workspace, and to lock files to prevent multiple people from 2.139 + modifying them simultaneously.</para> 2.140 + 2.141 + <para>Later in the 1980s, Dick Grune used RCS as a building block 2.142 + for a set of shell scripts he initially called cmt, but then 2.143 + renamed to CVS (Concurrent Versions System). The big innovation 2.144 + of CVS was that it let developers work simultaneously and 2.145 + somewhat independently in their own personal workspaces. The 2.146 + personal workspaces prevented developers from stepping on each 2.147 + other's toes all the time, as was common with SCCS and RCS. Each 2.148 + developer had a copy of every project file, and could modify 2.149 + their copies independently. They had to merge their edits prior 2.150 + to committing changes to the central repository.</para> 2.151 + 2.152 + <para>Brian Berliner took Grune's original scripts and rewrote 2.153 + them in C, releasing in 1989 the code that has since developed 2.154 + into the modern version of CVS. CVS subsequently acquired the 2.155 + ability to operate over a network connection, giving it a 2.156 + client/server architecture. CVS's architecture is centralised; 2.157 + only the server has a copy of the history of the project. Client 2.158 + workspaces just contain copies of recent versions of the 2.159 + project's files, and a little metadata to tell them where the 2.160 + server is. CVS has been enormously successful; it is probably 2.161 + the world's most widely used revision control system.</para> 2.162 + 2.163 + <para>In the early 1990s, Sun Microsystems developed an early 2.164 + distributed revision control system, called TeamWare. A 2.165 + TeamWare workspace contains a complete copy of the project's 2.166 + history. TeamWare has no notion of a central repository. (CVS 2.167 + relied upon RCS for its history storage; TeamWare used 2.168 + SCCS.)</para> 2.169 + 2.170 + <para>As the 1990s progressed, awareness grew of a number of 2.171 + problems with CVS. It records simultaneous changes to multiple 2.172 + files individually, instead of grouping them together as a 2.173 + single logically atomic operation. It does not manage its file 2.174 + hierarchy well; it is easy to make a mess of a repository by 2.175 + renaming files and directories. Worse, its source code is 2.176 + difficult to read and maintain, which made the <quote>pain 2.177 + level</quote> of fixing these architectural problems 2.178 + prohibitive.</para> 2.179 + 2.180 + <para>In 2001, Jim Blandy and Karl Fogel, two developers who had 2.181 + worked on CVS, started a project to replace it with a tool that 2.182 + would have a better architecture and cleaner code. The result, 2.183 + Subversion, does not stray from CVS's centralised client/server 2.184 + model, but it adds multi-file atomic commits, better namespace 2.185 + management, and a number of other features that make it a 2.186 + generally better tool than CVS. Since its initial release, it 2.187 + has rapidly grown in popularity.</para> 2.188 + 2.189 + <para>More or less simultaneously, Graydon Hoare began working on 2.190 + an ambitious distributed revision control system that he named 2.191 + Monotone. While Monotone addresses many of CVS's design flaws 2.192 + and has a peer-to-peer architecture, it goes beyond earlier (and 2.193 + subsequent) revision control tools in a number of innovative 2.194 + ways. It uses cryptographic hashes as identifiers, and has an 2.195 + integral notion of <quote>trust</quote> for code from different 2.196 + sources.</para> 2.197 + 2.198 + <para>Mercurial began life in 2005. While a few aspects of its 2.199 + design are influenced by Monotone, Mercurial focuses on ease of 2.200 + use, high performance, and scalability to very large 2.201 + projects.</para> 2.202 + 2.203 + </sect1> 2.204 + <sect1> 2.205 + <title>Trends in revision control</title> 2.206 + 2.207 + <para>There has been an unmistakable trend in the development and 2.208 + use of revision control tools over the past four decades, as 2.209 + people have become familiar with the capabilities of their tools 2.210 + and constrained by their limitations.</para> 2.211 + 2.212 + <para>The first generation began by managing single files on 2.213 + individual computers. Although these tools represented a huge 2.214 + advance over ad-hoc manual revision control, their locking model 2.215 + and reliance on a single computer limited them to small, 2.216 + tightly-knit teams.</para> 2.217 + 2.218 + <para>The second generation loosened these constraints by moving 2.219 + to network-centered architectures, and managing entire projects 2.220 + at a time. As projects grew larger, they ran into new problems. 2.221 + With clients needing to talk to servers very frequently, server 2.222 + scaling became an issue for large projects. An unreliable 2.223 + network connection could prevent remote users from being able to 2.224 + talk to the server at all. As open source projects started 2.225 + making read-only access available anonymously to anyone, people 2.226 + without commit privileges found that they could not use the 2.227 + tools to interact with a project in a natural way, as they could 2.228 + not record their changes.</para> 2.229 + 2.230 + <para>The current generation of revision control tools is 2.231 + peer-to-peer in nature. All of these systems have dropped the 2.232 + dependency on a single central server, and allow people to 2.233 + distribute their revision control data to where it's actually 2.234 + needed. Collaboration over the Internet has moved from 2.235 + constrained by technology to a matter of choice and consensus. 2.236 + Modern tools can operate offline indefinitely and autonomously, 2.237 + with a network connection only needed when syncing changes with 2.238 + another repository.</para> 2.239 + 2.240 + </sect1> 2.241 + <sect1> 2.242 + <title>A few of the advantages of distributed revision 2.243 + control</title> 2.244 + 2.245 + <para>Even though distributed revision control tools have for 2.246 + several years been as robust and usable as their 2.247 + previous-generation counterparts, people using older tools have 2.248 + not yet necessarily woken up to their advantages. There are a 2.249 + number of ways in which distributed tools shine relative to 2.250 + centralised ones.</para> 2.251 + 2.252 + <para>For an individual developer, distributed tools are almost 2.253 + always much faster than centralised tools. This is for a simple 2.254 + reason: a centralised tool needs to talk over the network for 2.255 + many common operations, because most metadata is stored in a 2.256 + single copy on the central server. A distributed tool stores 2.257 + all of its metadata locally. All else being equal, talking over 2.258 + the network adds overhead to a centralised tool. Don't 2.259 + underestimate the value of a snappy, responsive tool: you're 2.260 + going to spend a lot of time interacting with your revision 2.261 + control software.</para> 2.262 + 2.263 + <para>Distributed tools are indifferent to the vagaries of your 2.264 + server infrastructure, again because they replicate metadata to 2.265 + so many locations. If you use a centralised system and your 2.266 + server catches fire, you'd better hope that your backup media 2.267 + are reliable, and that your last backup was recent and actually 2.268 + worked. With a distributed tool, you have many backups 2.269 + available on every contributor's computer.</para> 2.270 + 2.271 + <para>The reliability of your network will affect distributed 2.272 + tools far less than it will centralised tools. You can't even 2.273 + use a centralised tool without a network connection, except for 2.274 + a few highly constrained commands. With a distributed tool, if 2.275 + your network connection goes down while you're working, you may 2.276 + not even notice. The only thing you won't be able to do is talk 2.277 + to repositories on other computers, something that is relatively 2.278 + rare compared with local operations. If you have a far-flung 2.279 + team of collaborators, this may be significant.</para> 2.280 + 2.281 + <sect2> 2.282 + <title>Advantages for open source projects</title> 2.283 + 2.284 + <para>If you take a shine to an open source project and decide 2.285 + that you would like to start hacking on it, and that project 2.286 + uses a distributed revision control tool, you are at once a 2.287 + peer with the people who consider themselves the 2.288 + <quote>core</quote> of that project. If they publish their 2.289 + repositories, you can immediately copy their project history, 2.290 + start making changes, and record your work, using the same 2.291 + tools in the same ways as insiders. By contrast, with a 2.292 + centralised tool, you must use the software in a <quote>read 2.293 + only</quote> mode unless someone grants you permission to 2.294 + commit changes to their central server. Until then, you won't 2.295 + be able to record changes, and your local modifications will 2.296 + be at risk of corruption any time you try to update your 2.297 + client's view of the repository.</para> 2.298 + 2.299 + <sect3> 2.300 + <title>The forking non-problem</title> 2.301 + 2.302 + <para>It has been suggested that distributed revision control 2.303 + tools pose some sort of risk to open source projects because 2.304 + they make it easy to <quote>fork</quote> the development of 2.305 + a project. A fork happens when there are differences in 2.306 + opinion or attitude between groups of developers that cause 2.307 + them to decide that they can't work together any longer. 2.308 + Each side takes a more or less complete copy of the 2.309 + project's source code, and goes off in its own 2.310 + direction.</para> 2.311 + 2.312 + <para>Sometimes the camps in a fork decide to reconcile their 2.313 + differences. With a centralised revision control system, the 2.314 + <emphasis>technical</emphasis> process of reconciliation is 2.315 + painful, and has to be performed largely by hand. You have 2.316 + to decide whose revision history is going to 2.317 + <quote>win</quote>, and graft the other team's changes into 2.318 + the tree somehow. This usually loses some or all of one 2.319 + side's revision history.</para> 2.320 + 2.321 + <para>What distributed tools do with respect to forking is 2.322 + they make forking the <emphasis>only</emphasis> way to 2.323 + develop a project. Every single change that you make is 2.324 + potentially a fork point. The great strength of this 2.325 + approach is that a distributed revision control tool has to 2.326 + be really good at <emphasis>merging</emphasis> forks, 2.327 + because forks are absolutely fundamental: they happen all 2.328 + the time.</para> 2.329 + 2.330 + <para>If every piece of work that everybody does, all the 2.331 + time, is framed in terms of forking and merging, then what 2.332 + the open source world refers to as a <quote>fork</quote> 2.333 + becomes <emphasis>purely</emphasis> a social issue. If 2.334 + anything, distributed tools <emphasis>lower</emphasis> the 2.335 + likelihood of a fork:</para> 2.336 + <itemizedlist> 2.337 + <listitem><para>They eliminate the social distinction that 2.338 + centralised tools impose: that between insiders (people 2.339 + with commit access) and outsiders (people 2.340 + without).</para></listitem> 2.341 + <listitem><para>They make it easier to reconcile after a 2.342 + social fork, because all that's involved from the 2.343 + perspective of the revision control software is just 2.344 + another merge.</para></listitem></itemizedlist> 2.345 + 2.346 + <para>Some people resist distributed tools because they want 2.347 + to retain tight control over their projects, and they 2.348 + believe that centralised tools give them this control. 2.349 + However, if you're of this belief, and you publish your CVS 2.350 + or Subversion repositories publically, there are plenty of 2.351 + tools available that can pull out your entire project's 2.352 + history (albeit slowly) and recreate it somewhere that you 2.353 + don't control. So while your control in this case is 2.354 + illusory, you are forgoing the ability to fluidly 2.355 + collaborate with whatever people feel compelled to mirror 2.356 + and fork your history.</para> 2.357 + 2.358 + </sect3> 2.359 + </sect2> 2.360 + <sect2> 2.361 + <title>Advantages for commercial projects</title> 2.362 + 2.363 + <para>Many commercial projects are undertaken by teams that are 2.364 + scattered across the globe. Contributors who are far from a 2.365 + central server will see slower command execution and perhaps 2.366 + less reliability. Commercial revision control systems attempt 2.367 + to ameliorate these problems with remote-site replication 2.368 + add-ons that are typically expensive to buy and cantankerous 2.369 + to administer. A distributed system doesn't suffer from these 2.370 + problems in the first place. Better yet, you can easily set 2.371 + up multiple authoritative servers, say one per site, so that 2.372 + there's no redundant communication between repositories over 2.373 + expensive long-haul network links.</para> 2.374 + 2.375 + <para>Centralised revision control systems tend to have 2.376 + relatively low scalability. It's not unusual for an expensive 2.377 + centralised system to fall over under the combined load of 2.378 + just a few dozen concurrent users. Once again, the typical 2.379 + response tends to be an expensive and clunky replication 2.380 + facility. Since the load on a central server---if you have 2.381 + one at all---is many times lower with a distributed tool 2.382 + (because all of the data is replicated everywhere), a single 2.383 + cheap server can handle the needs of a much larger team, and 2.384 + replication to balance load becomes a simple matter of 2.385 + scripting.</para> 2.386 + 2.387 + <para>If you have an employee in the field, troubleshooting a 2.388 + problem at a customer's site, they'll benefit from distributed 2.389 + revision control. The tool will let them generate custom 2.390 + builds, try different fixes in isolation from each other, and 2.391 + search efficiently through history for the sources of bugs and 2.392 + regressions in the customer's environment, all without needing 2.393 + to connect to your company's network.</para> 2.394 + 2.395 + </sect2> 2.396 + </sect1> 2.397 + <sect1> 2.398 + <title>Why choose Mercurial?</title> 2.399 + 2.400 + <para>Mercurial has a unique set of properties that make it a 2.401 + particularly good choice as a revision control system.</para> 2.402 + <itemizedlist> 2.403 + <listitem><para>It is easy to learn and use.</para></listitem> 2.404 + <listitem><para>It is lightweight.</para></listitem> 2.405 + <listitem><para>It scales excellently.</para></listitem> 2.406 + <listitem><para>It is easy to 2.407 + customise.</para></listitem></itemizedlist> 2.408 + 2.409 + <para>If you are at all familiar with revision control systems, 2.410 + you should be able to get up and running with Mercurial in less 2.411 + than five minutes. Even if not, it will take no more than a few 2.412 + minutes longer. Mercurial's command and feature sets are 2.413 + generally uniform and consistent, so you can keep track of a few 2.414 + general rules instead of a host of exceptions.</para> 2.415 + 2.416 + <para>On a small project, you can start working with Mercurial in 2.417 + moments. Creating new changes and branches; transferring changes 2.418 + around (whether locally or over a network); and history and 2.419 + status operations are all fast. Mercurial attempts to stay 2.420 + nimble and largely out of your way by combining low cognitive 2.421 + overhead with blazingly fast operations.</para> 2.422 + 2.423 + <para>The usefulness of Mercurial is not limited to small 2.424 + projects: it is used by projects with hundreds to thousands of 2.425 + contributors, each containing tens of thousands of files and 2.426 + hundreds of megabytes of source code.</para> 2.427 + 2.428 + <para>If the core functionality of Mercurial is not enough for 2.429 + you, it's easy to build on. Mercurial is well suited to 2.430 + scripting tasks, and its clean internals and implementation in 2.431 + Python make it easy to add features in the form of extensions. 2.432 + There are a number of popular and useful extensions already 2.433 + available, ranging from helping to identify bugs to improving 2.434 + performance.</para> 2.435 + 2.436 + </sect1> 2.437 + <sect1> 2.438 + <title>Mercurial compared with other tools</title> 2.439 + 2.440 + <para>Before you read on, please understand that this section 2.441 + necessarily reflects my own experiences, interests, and (dare I 2.442 + say it) biases. I have used every one of the revision control 2.443 + tools listed below, in most cases for several years at a 2.444 + time.</para> 2.445 + 2.446 + 2.447 + <sect2> 2.448 + <title>Subversion</title> 2.449 + 2.450 + <para>Subversion is a popular revision control tool, developed 2.451 + to replace CVS. It has a centralised client/server 2.452 + architecture.</para> 2.453 + 2.454 + <para>Subversion and Mercurial have similarly named commands for 2.455 + performing the same operations, so if you're familiar with 2.456 + one, it is easy to learn to use the other. Both tools are 2.457 + portable to all popular operating systems.</para> 2.458 + 2.459 + <para>Prior to version 1.5, Subversion had no useful support for 2.460 + merges. At the time of writing, its merge tracking capability 2.461 + is new, and known to be <ulink 2.462 + url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 2.463 + and buggy</ulink>.</para> 2.464 + 2.465 + <para>Mercurial has a substantial performance advantage over 2.466 + Subversion on every revision control operation I have 2.467 + benchmarked. I have measured its advantage as ranging from a 2.468 + factor of two to a factor of six when compared with Subversion 2.469 + 1.4.3's <emphasis>ra_local</emphasis> file store, which is the 2.470 + fastest access method available. In more realistic 2.471 + deployments involving a network-based store, Subversion will 2.472 + be at a substantially larger disadvantage. Because many 2.473 + Subversion commands must talk to the server and Subversion 2.474 + does not have useful replication facilities, server capacity 2.475 + and network bandwidth become bottlenecks for modestly large 2.476 + projects.</para> 2.477 + 2.478 + <para>Additionally, Subversion incurs substantial storage 2.479 + overhead to avoid network transactions for a few common 2.480 + operations, such as finding modified files 2.481 + (<literal>status</literal>) and displaying modifications 2.482 + against the current revision (<literal>diff</literal>). As a 2.483 + result, a Subversion working copy is often the same size as, 2.484 + or larger than, a Mercurial repository and working directory, 2.485 + even though the Mercurial repository contains a complete 2.486 + history of the project.</para> 2.487 + 2.488 + <para>Subversion is widely supported by third party tools. 2.489 + Mercurial currently lags considerably in this area. This gap 2.490 + is closing, however, and indeed some of Mercurial's GUI tools 2.491 + now outshine their Subversion equivalents. Like Mercurial, 2.492 + Subversion has an excellent user manual.</para> 2.493 + 2.494 + <para>Because Subversion doesn't store revision history on the 2.495 + client, it is well suited to managing projects that deal with 2.496 + lots of large, opaque binary files. If you check in fifty 2.497 + revisions to an incompressible 10MB file, Subversion's 2.498 + client-side space usage stays constant The space used by any 2.499 + distributed SCM will grow rapidly in proportion to the number 2.500 + of revisions, because the differences between each revision 2.501 + are large.</para> 2.502 + 2.503 + <para>In addition, it's often difficult or, more usually, 2.504 + impossible to merge different versions of a binary file. 2.505 + Subversion's ability to let a user lock a file, so that they 2.506 + temporarily have the exclusive right to commit changes to it, 2.507 + can be a significant advantage to a project where binary files 2.508 + are widely used.</para> 2.509 + 2.510 + <para>Mercurial can import revision history from a Subversion 2.511 + repository. It can also export revision history to a 2.512 + Subversion repository. This makes it easy to <quote>test the 2.513 + waters</quote> and use Mercurial and Subversion in parallel 2.514 + before deciding to switch. History conversion is incremental, 2.515 + so you can perform an initial conversion, then small 2.516 + additional conversions afterwards to bring in new 2.517 + changes.</para> 2.518 + 2.519 + 2.520 + </sect2> 2.521 + <sect2> 2.522 + <title>Git</title> 2.523 + 2.524 + <para>Git is a distributed revision control tool that was 2.525 + developed for managing the Linux kernel source tree. Like 2.526 + Mercurial, its early design was somewhat influenced by 2.527 + Monotone.</para> 2.528 + 2.529 + <para>Git has a very large command set, with version 1.5.0 2.530 + providing 139 individual commands. It has something of a 2.531 + reputation for being difficult to learn. Compared to Git, 2.532 + Mercurial has a strong focus on simplicity.</para> 2.533 + 2.534 + <para>In terms of performance, Git is extremely fast. In 2.535 + several cases, it is faster than Mercurial, at least on Linux, 2.536 + while Mercurial performs better on other operations. However, 2.537 + on Windows, the performance and general level of support that 2.538 + Git provides is, at the time of writing, far behind that of 2.539 + Mercurial.</para> 2.540 + 2.541 + <para>While a Mercurial repository needs no maintenance, a Git 2.542 + repository requires frequent manual <quote>repacks</quote> of 2.543 + its metadata. Without these, performance degrades, while 2.544 + space usage grows rapidly. A server that contains many Git 2.545 + repositories that are not rigorously and frequently repacked 2.546 + will become heavily disk-bound during backups, and there have 2.547 + been instances of daily backups taking far longer than 24 2.548 + hours as a result. A freshly packed Git repository is 2.549 + slightly smaller than a Mercurial repository, but an unpacked 2.550 + repository is several orders of magnitude larger.</para> 2.551 + 2.552 + <para>The core of Git is written in C. Many Git commands are 2.553 + implemented as shell or Perl scripts, and the quality of these 2.554 + scripts varies widely. I have encountered several instances 2.555 + where scripts charged along blindly in the presence of errors 2.556 + that should have been fatal.</para> 2.557 + 2.558 + <para>Mercurial can import revision history from a Git 2.559 + repository.</para> 2.560 + 2.561 + 2.562 + </sect2> 2.563 + <sect2> 2.564 + <title>CVS</title> 2.565 + 2.566 + <para>CVS is probably the most widely used revision control tool 2.567 + in the world. Due to its age and internal untidiness, it has 2.568 + been only lightly maintained for many years.</para> 2.569 + 2.570 + <para>It has a centralised client/server architecture. It does 2.571 + not group related file changes into atomic commits, making it 2.572 + easy for people to <quote>break the build</quote>: one person 2.573 + can successfully commit part of a change and then be blocked 2.574 + by the need for a merge, causing other people to see only a 2.575 + portion of the work they intended to do. This also affects 2.576 + how you work with project history. If you want to see all of 2.577 + the modifications someone made as part of a task, you will 2.578 + need to manually inspect the descriptions and timestamps of 2.579 + the changes made to each file involved (if you even know what 2.580 + those files were).</para> 2.581 + 2.582 + <para>CVS has a muddled notion of tags and branches that I will 2.583 + not attempt to even describe. It does not support renaming of 2.584 + files or directories well, making it easy to corrupt a 2.585 + repository. It has almost no internal consistency checking 2.586 + capabilities, so it is usually not even possible to tell 2.587 + whether or how a repository is corrupt. I would not recommend 2.588 + CVS for any project, existing or new.</para> 2.589 + 2.590 + <para>Mercurial can import CVS revision history. However, there 2.591 + are a few caveats that apply; these are true of every other 2.592 + revision control tool's CVS importer, too. Due to CVS's lack 2.593 + of atomic changes and unversioned filesystem hierarchy, it is 2.594 + not possible to reconstruct CVS history completely accurately; 2.595 + some guesswork is involved, and renames will usually not show 2.596 + up. Because a lot of advanced CVS administration has to be 2.597 + done by hand and is hence error-prone, it's common for CVS 2.598 + importers to run into multiple problems with corrupted 2.599 + repositories (completely bogus revision timestamps and files 2.600 + that have remained locked for over a decade are just two of 2.601 + the less interesting problems I can recall from personal 2.602 + experience).</para> 2.603 + 2.604 + <para>Mercurial can import revision history from a CVS 2.605 + repository.</para> 2.606 + 2.607 + 2.608 + </sect2> 2.609 + <sect2> 2.610 + <title>Commercial tools</title> 2.611 + 2.612 + <para>Perforce has a centralised client/server architecture, 2.613 + with no client-side caching of any data. Unlike modern 2.614 + revision control tools, Perforce requires that a user run a 2.615 + command to inform the server about every file they intend to 2.616 + edit.</para> 2.617 + 2.618 + <para>The performance of Perforce is quite good for small teams, 2.619 + but it falls off rapidly as the number of users grows beyond a 2.620 + few dozen. Modestly large Perforce installations require the 2.621 + deployment of proxies to cope with the load their users 2.622 + generate.</para> 2.623 + 2.624 + 2.625 + </sect2> 2.626 + <sect2> 2.627 + <title>Choosing a revision control tool</title> 2.628 + 2.629 + <para>With the exception of CVS, all of the tools listed above 2.630 + have unique strengths that suit them to particular styles of 2.631 + work. There is no single revision control tool that is best 2.632 + in all situations.</para> 2.633 + 2.634 + <para>As an example, Subversion is a good choice for working 2.635 + with frequently edited binary files, due to its centralised 2.636 + nature and support for file locking.</para> 2.637 + 2.638 + <para>I personally find Mercurial's properties of simplicity, 2.639 + performance, and good merge support to be a compelling 2.640 + combination that has served me well for several years.</para> 2.641 + 2.642 + 2.643 + </sect2> 2.644 + </sect1> 2.645 + <sect1> 2.646 + <title>Switching from another tool to Mercurial</title> 2.647 + 2.648 + <para>Mercurial is bundled with an extension named <literal 2.649 + role="hg-ext">convert</literal>, which can incrementally 2.650 + import revision history from several other revision control 2.651 + tools. By <quote>incremental</quote>, I mean that you can 2.652 + convert all of a project's history to date in one go, then rerun 2.653 + the conversion later to obtain new changes that happened after 2.654 + the initial conversion.</para> 2.655 + 2.656 + <para>The revision control tools supported by <literal 2.657 + role="hg-ext">convert</literal> are as follows:</para> 2.658 + <itemizedlist> 2.659 + <listitem><para>Subversion</para></listitem> 2.660 + <listitem><para>CVS</para></listitem> 2.661 + <listitem><para>Git</para></listitem> 2.662 + <listitem><para>Darcs</para></listitem></itemizedlist> 2.663 + 2.664 + <para>In addition, <literal role="hg-ext">convert</literal> can 2.665 + export changes from Mercurial to Subversion. This makes it 2.666 + possible to try Subversion and Mercurial in parallel before 2.667 + committing to a switchover, without risking the loss of any 2.668 + work.</para> 2.669 + 2.670 + <para>The <command role="hg-ext-conver">convert</command> command 2.671 + is easy to use. Simply point it at the path or URL of the 2.672 + source repository, optionally give it the name of the 2.673 + destination repository, and it will start working. After the 2.674 + initial conversion, just run the same command again to import 2.675 + new changes.</para> 2.676 + </sect1> 2.677 +</chapter> 2.678 + 2.679 +<!-- 2.680 +local variables: 2.681 +sgml-parent-document: ("00book.xml" "book" "chapter") 2.682 +end: 2.683 +-->
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/en/ch02-tour-basic.xml Thu Feb 05 22:45:48 2009 -0800 3.3 @@ -0,0 +1,787 @@ 3.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 3.5 + 3.6 +<chapter> 3.7 + <title>A tour of Mercurial: the basics</title> 3.8 + <para>\label{chap:tour-basic}</para> 3.9 + 3.10 + <sect1> 3.11 + <title>Installing Mercurial on your system</title> 3.12 + <para>\label{sec:tour:install}</para> 3.13 + 3.14 + <para>Prebuilt binary packages of Mercurial are available for 3.15 + every popular operating system. These make it easy to start 3.16 + using Mercurial on your computer immediately.</para> 3.17 + 3.18 + <sect2> 3.19 + <title>Linux</title> 3.20 + 3.21 + <para>Because each Linux distribution has its own packaging 3.22 + tools, policies, and rate of development, it's difficult to 3.23 + give a comprehensive set of instructions on how to install 3.24 + Mercurial binaries. The version of Mercurial that you will 3.25 + end up with can vary depending on how active the person is who 3.26 + maintains the package for your distribution.</para> 3.27 + 3.28 + <para>To keep things simple, I will focus on installing 3.29 + Mercurial from the command line under the most popular Linux 3.30 + distributions. Most of these distributions provide graphical 3.31 + package managers that will let you install Mercurial with a 3.32 + single click; the package name to look for is 3.33 + <literal>mercurial</literal>.</para> 3.34 + 3.35 + <itemizedlist> 3.36 + <listitem><para>Debian:</para> 3.37 + <programlisting>apt-get install 3.38 + mercurial</programlisting></listitem> 3.39 + <listitem><para>Fedora Core:</para> 3.40 + <programlisting>yum install 3.41 + mercurial</programlisting></listitem> 3.42 + <listitem><para>Gentoo:</para> 3.43 + <programlisting>emerge mercurial</programlisting></listitem> 3.44 + <listitem><para>OpenSUSE:</para> 3.45 + <programlisting>yum install 3.46 + mercurial</programlisting></listitem> 3.47 + <listitem><para>Ubuntu: Ubuntu's Mercurial package is based on 3.48 + Debian's. To install it, run the following 3.49 + command.</para> 3.50 + <programlisting>apt-get install 3.51 + mercurial</programlisting></listitem> 3.52 + </itemizedlist> 3.53 + 3.54 + </sect2> 3.55 + <sect2> 3.56 + <title>Solaris</title> 3.57 + 3.58 + <para>SunFreeWare, at <ulink 3.59 + url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 3.60 + is a good source for a large number of pre-built Solaris 3.61 + packages for 32 and 64 bit Intel and Sparc architectures, 3.62 + including current versions of Mercurial.</para> 3.63 + 3.64 + </sect2> 3.65 + <sect2> 3.66 + <title>Mac OS X</title> 3.67 + 3.68 + <para>Lee Cantey publishes an installer of Mercurial for Mac OS 3.69 + X at <ulink 3.70 + url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 3.71 + This package works on both Intel- and Power-based Macs. 3.72 + Before you can use it, you must install a compatible version 3.73 + of Universal MacPython <citation>web:macpython</citation>. 3.74 + This is easy to do; simply follow the instructions on Lee's 3.75 + site.</para> 3.76 + 3.77 + <para>It's also possible to install Mercurial using Fink or 3.78 + MacPorts, two popular free package managers for Mac OS X. If 3.79 + you have Fink, use <command>sudo apt-get install 3.80 + mercurial-py25</command>. If MacPorts, <command>sudo port 3.81 + install mercurial</command>.</para> 3.82 + 3.83 + </sect2> 3.84 + <sect2> 3.85 + <title>Windows</title> 3.86 + 3.87 + <para>Lee Cantey publishes an installer of Mercurial for Windows 3.88 + at <ulink 3.89 + url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 3.90 + This package has no external dependencies; it <quote>just 3.91 + works</quote>.</para> 3.92 + 3.93 + <note> 3.94 + <para> The Windows version of Mercurial does not 3.95 + automatically convert line endings between Windows and Unix 3.96 + styles. If you want to share work with Unix users, you must 3.97 + do a little additional configuration work. XXX Flesh this 3.98 + out.</para> 3.99 + </note> 3.100 + 3.101 + </sect2> 3.102 + </sect1> 3.103 + <sect1> 3.104 + <title>Getting started</title> 3.105 + 3.106 + <para>To begin, we'll use the <command role="hg-cmd">hg 3.107 + version</command> command to find out whether Mercurial is 3.108 + actually installed properly. The actual version information 3.109 + that it prints isn't so important; it's whether it prints 3.110 + anything at all that we care about. <!-- 3.111 + &interaction.tour.version; --></para> 3.112 + 3.113 + <sect2> 3.114 + <title>Built-in help</title> 3.115 + 3.116 + <para>Mercurial provides a built-in help system. This is 3.117 + invaluable for those times when you find yourself stuck trying 3.118 + to remember how to run a command. If you are completely 3.119 + stuck, simply run <command role="hg-cmd">hg help</command>; it 3.120 + will print a brief list of commands, along with a description 3.121 + of what each does. If you ask for help on a specific command 3.122 + (as below), it prints more detailed information. <!-- 3.123 + &interaction.tour.help; --> For a more impressive level of 3.124 + detail (which you won't usually need) run <command 3.125 + role="hg-cmd">hg help <option 3.126 + role="hg-opt-global">-v</option></command>. The <option 3.127 + role="hg-opt-global">-v</option> option is short for <option 3.128 + role="hg-opt-global">--verbose</option>, and tells Mercurial 3.129 + to print more information than it usually would.</para> 3.130 + 3.131 + </sect2> 3.132 + </sect1> 3.133 + <sect1> 3.134 + <title>Working with a repository</title> 3.135 + 3.136 + <para>In Mercurial, everything happens inside a 3.137 + <emphasis>repository</emphasis>. The repository for a project 3.138 + contains all of the files that <quote>belong to</quote> that 3.139 + project, along with a historical record of the project's 3.140 + files.</para> 3.141 + 3.142 + <para>There's nothing particularly magical about a repository; it 3.143 + is simply a directory tree in your filesystem that Mercurial 3.144 + treats as special. You can rename or delete a repository any 3.145 + time you like, using either the command line or your file 3.146 + browser.</para> 3.147 + 3.148 + <sect2> 3.149 + <title>Making a local copy of a repository</title> 3.150 + 3.151 + <para><emphasis>Copying</emphasis> a repository is just a little 3.152 + bit special. While you could use a normal file copying 3.153 + command to make a copy of a repository, it's best to use a 3.154 + built-in command that Mercurial provides. This command is 3.155 + called <command role="hg-cmd">hg clone</command>, because it 3.156 + creates an identical copy of an existing repository. <!-- 3.157 + &interaction.tour.clone; --> If our clone succeeded, we should 3.158 + now have a local directory called <filename 3.159 + class="directory">hello</filename>. This directory will 3.160 + contain some files. <!-- &interaction.tour.ls; --> These files 3.161 + have the same contents and history in our repository as they 3.162 + do in the repository we cloned.</para> 3.163 + 3.164 + <para>Every Mercurial repository is complete, self-contained, 3.165 + and independent. It contains its own private copy of a 3.166 + project's files and history. A cloned repository remembers 3.167 + the location of the repository it was cloned from, but it does 3.168 + not communicate with that repository, or any other, unless you 3.169 + tell it to.</para> 3.170 + 3.171 + <para>What this means for now is that we're free to experiment 3.172 + with our repository, safe in the knowledge that it's a private 3.173 + <quote>sandbox</quote> that won't affect anyone else.</para> 3.174 + 3.175 + </sect2> 3.176 + <sect2> 3.177 + <title>What's in a repository?</title> 3.178 + 3.179 + <para>When we take a more detailed look inside a repository, we 3.180 + can see that it contains a directory named <filename 3.181 + class="directory">.hg</filename>. This is where Mercurial 3.182 + keeps all of its metadata for the repository. <!-- 3.183 + &interaction.tour.ls-a; --></para> 3.184 + 3.185 + <para>The contents of the <filename 3.186 + class="directory">.hg</filename> directory and its 3.187 + subdirectories are private to Mercurial. Every other file and 3.188 + directory in the repository is yours to do with as you 3.189 + please.</para> 3.190 + 3.191 + <para>To introduce a little terminology, the <filename 3.192 + class="directory">.hg</filename> directory is the 3.193 + <quote>real</quote> repository, and all of the files and 3.194 + directories that coexist with it are said to live in the 3.195 + <emphasis>working directory</emphasis>. An easy way to 3.196 + remember the distinction is that the 3.197 + <emphasis>repository</emphasis> contains the 3.198 + <emphasis>history</emphasis> of your project, while the 3.199 + <emphasis>working directory</emphasis> contains a 3.200 + <emphasis>snapshot</emphasis> of your project at a particular 3.201 + point in history.</para> 3.202 + 3.203 + </sect2> 3.204 + </sect1> 3.205 + <sect1> 3.206 + <title>A tour through history</title> 3.207 + 3.208 + <para>One of the first things we might want to do with a new, 3.209 + unfamiliar repository is understand its history. The <command 3.210 + role="hg-cmd">hg log</command> command gives us a view of 3.211 + history. <!-- &interaction.tour.log; --> By default, this 3.212 + command prints a brief paragraph of output for each change to 3.213 + the project that was recorded. In Mercurial terminology, we 3.214 + call each of these recorded events a 3.215 + <emphasis>changeset</emphasis>, because it can contain a record 3.216 + of changes to several files.</para> 3.217 + 3.218 + <para>The fields in a record of output from <command 3.219 + role="hg-cmd">hg log</command> are as follows.</para> 3.220 + <itemizedlist> 3.221 + <listitem><para><literal>changeset</literal>: This field has the 3.222 + format of a number, followed by a colon, followed by a 3.223 + hexadecimal string. These are 3.224 + <emphasis>identifiers</emphasis> for the changeset. There 3.225 + are two identifiers because the number is shorter and easier 3.226 + to type than the hex string.</para></listitem> 3.227 + <listitem><para><literal>user</literal>: The identity of the 3.228 + person who created the changeset. This is a free-form 3.229 + field, but it most often contains a person's name and email 3.230 + address.</para></listitem> 3.231 + <listitem><para><literal>date</literal>: The date and time on 3.232 + which the changeset was created, and the timezone in which 3.233 + it was created. (The date and time are local to that 3.234 + timezone; they display what time and date it was for the 3.235 + person who created the changeset.)</para></listitem> 3.236 + <listitem><para><literal>summary</literal>: The first line of 3.237 + the text message that the creator of the changeset entered 3.238 + to describe the changeset.</para></listitem></itemizedlist> 3.239 + <para>The default output printed by <command role="hg-cmd">hg 3.240 + log</command> is purely a summary; it is missing a lot of 3.241 + detail.</para> 3.242 + 3.243 + <para>Figure <xref id="fig:tour-basic:history"/> provides a 3.244 + graphical representation of the history of the <filename 3.245 + class="directory">hello</filename> repository, to make it a 3.246 + little easier to see which direction history is 3.247 + <quote>flowing</quote> in. We'll be returning to this figure 3.248 + several times in this chapter and the chapter that 3.249 + follows.</para> 3.250 + 3.251 + <figure> 3.252 + 3.253 + <para> <mediaobject><imageobject><imagedata 3.254 + fileref="tour-history"/></imageobject><textobject><phrase>XXX 3.255 + add text</phrase></textobject></mediaobject> 3.256 + <caption>Graphical history of the <filename 3.257 + class="directory">hello</filename> repository</caption> 3.258 + \label{fig:tour-basic:history}</para> 3.259 + </figure> 3.260 + 3.261 + <sect2> 3.262 + <title>Changesets, revisions, and talking to other 3.263 + people</title> 3.264 + 3.265 + <para>As English is a notoriously sloppy language, and computer 3.266 + science has a hallowed history of terminological confusion 3.267 + (why use one term when four will do?), revision control has a 3.268 + variety of words and phrases that mean the same thing. If you 3.269 + are talking about Mercurial history with other people, you 3.270 + will find that the word <quote>changeset</quote> is often 3.271 + compressed to <quote>change</quote> or (when written) 3.272 + <quote>cset</quote>, and sometimes a changeset is referred to 3.273 + as a <quote>revision</quote> or a <quote>rev</quote>.</para> 3.274 + 3.275 + <para>While it doesn't matter what <emphasis>word</emphasis> you 3.276 + use to refer to the concept of <quote>a changeset</quote>, the 3.277 + <emphasis>identifier</emphasis> that you use to refer to 3.278 + <quote>a <emphasis>specific</emphasis> changeset</quote> is of 3.279 + great importance. Recall that the <literal>changeset</literal> 3.280 + field in the output from <command role="hg-cmd">hg 3.281 + log</command> identifies a changeset using both a number and 3.282 + a hexadecimal string.</para> 3.283 + <itemizedlist> 3.284 + <listitem><para>The revision number is <emphasis>only valid in 3.285 + that repository</emphasis>,</para></listitem> 3.286 + <listitem><para>while the hex string is the 3.287 + <emphasis>permanent, unchanging identifier</emphasis> that 3.288 + will always identify that exact changeset in 3.289 + <emphasis>every</emphasis> copy of the 3.290 + repository.</para></listitem></itemizedlist> 3.291 + <para>This distinction is important. If you send someone an 3.292 + email talking about <quote>revision 33</quote>, there's a high 3.293 + likelihood that their revision 33 will <emphasis>not be the 3.294 + same</emphasis> as yours. The reason for this is that a 3.295 + revision number depends on the order in which changes arrived 3.296 + in a repository, and there is no guarantee that the same 3.297 + changes will happen in the same order in different 3.298 + repositories. Three changes $a,b,c$ can easily appear in one 3.299 + repository as $0,1,2$, while in another as $1,0,2$.</para> 3.300 + 3.301 + <para>Mercurial uses revision numbers purely as a convenient 3.302 + shorthand. If you need to discuss a changeset with someone, 3.303 + or make a record of a changeset for some other reason (for 3.304 + example, in a bug report), use the hexadecimal 3.305 + identifier.</para> 3.306 + 3.307 + </sect2> 3.308 + <sect2> 3.309 + <title>Viewing specific revisions</title> 3.310 + 3.311 + <para>To narrow the output of <command role="hg-cmd">hg 3.312 + log</command> down to a single revision, use the <option 3.313 + role="hg-opt-log">-r</option> (or <option 3.314 + role="hg-opt-log">--rev</option>) option. You can use 3.315 + either a revision number or a long-form changeset identifier, 3.316 + and you can provide as many revisions as you want. <!-- 3.317 + &interaction.tour.log-r; --></para> 3.318 + 3.319 + <para>If you want to see the history of several revisions 3.320 + without having to list each one, you can use <emphasis>range 3.321 + notation</emphasis>; this lets you express the idea <quote>I 3.322 + want all revisions between $a$ and $b$, inclusive</quote>. 3.323 + <!-- &interaction.tour.log.range; --> Mercurial also honours 3.324 + the order in which you specify revisions, so <command 3.325 + role="hg-cmd">hg log -r 2:4</command> prints $2,3,4$ while 3.326 + <command role="hg-cmd">hg log -r 4:2</command> prints 3.327 + $4,3,2$.</para> 3.328 + 3.329 + </sect2> 3.330 + <sect2> 3.331 + <title>More detailed information</title> 3.332 + 3.333 + <para>While the summary information printed by <command 3.334 + role="hg-cmd">hg log</command> is useful if you already know 3.335 + what you're looking for, you may need to see a complete 3.336 + description of the change, or a list of the files changed, if 3.337 + you're trying to decide whether a changeset is the one you're 3.338 + looking for. The <command role="hg-cmd">hg log</command> 3.339 + command's <option role="hg-opt-global">-v</option> (or <option 3.340 + role="hg-opt-global">--verbose</option>) option gives you 3.341 + this extra detail. <!-- &interaction.tour.log-v; --></para> 3.342 + 3.343 + <para>If you want to see both the description and content of a 3.344 + change, add the <option role="hg-opt-log">-p</option> (or 3.345 + <option role="hg-opt-log">--patch</option>) option. This 3.346 + displays the content of a change as a <emphasis>unified 3.347 + diff</emphasis> (if you've never seen a unified diff before, 3.348 + see section <xref id="sec:mq:patch"/> for an 3.349 + overview). <!-- &interaction.tour.log-vp; --></para> 3.350 + 3.351 + </sect2> 3.352 + </sect1> 3.353 + <sect1> 3.354 + <title>All about command options</title> 3.355 + 3.356 + <para>Let's take a brief break from exploring Mercurial commands 3.357 + to discuss a pattern in the way that they work; you may find 3.358 + this useful to keep in mind as we continue our tour.</para> 3.359 + 3.360 + <para>Mercurial has a consistent and straightforward approach to 3.361 + dealing with the options that you can pass to commands. It 3.362 + follows the conventions for options that are common to modern 3.363 + Linux and Unix systems.</para> 3.364 + <itemizedlist> 3.365 + <listitem><para>Every option has a long name. For example, as 3.366 + we've already seen, the <command role="hg-cmd">hg 3.367 + log</command> command accepts a <option 3.368 + role="hg-opt-log">--rev</option> option.</para></listitem> 3.369 + <listitem><para>Most options have short names, too. Instead of 3.370 + <option role="hg-opt-log">--rev</option>, we can use <option 3.371 + role="hg-opt-log">-r</option>. (The reason that some 3.372 + options don't have short names is that the options in 3.373 + question are rarely used.)</para></listitem> 3.374 + <listitem><para>Long options start with two dashes (e.g. <option 3.375 + role="hg-opt-log">--rev</option>), while short options 3.376 + start with one (e.g. <option 3.377 + role="hg-opt-log">-r</option>).</para></listitem> 3.378 + <listitem><para>Option naming and usage is consistent across 3.379 + commands. For example, every command that lets you specify 3.380 + a changeset ID or revision number accepts both <option 3.381 + role="hg-opt-log">-r</option> and <option 3.382 + role="hg-opt-log">--rev</option> 3.383 + arguments.</para></listitem></itemizedlist> 3.384 + <para>In the examples throughout this book, I use short options 3.385 + instead of long. This just reflects my own preference, so don't 3.386 + read anything significant into it.</para> 3.387 + 3.388 + <para>Most commands that print output of some kind will print more 3.389 + output when passed a <option role="hg-opt-global">-v</option> 3.390 + (or <option role="hg-opt-global">--verbose</option>) option, and 3.391 + less when passed <option role="hg-opt-global">-q</option> (or 3.392 + <option role="hg-opt-global">--quiet</option>).</para> 3.393 + 3.394 + </sect1> 3.395 + <sect1> 3.396 + <title>Making and reviewing changes</title> 3.397 + 3.398 + <para>Now that we have a grasp of viewing history in Mercurial, 3.399 + let's take a look at making some changes and examining 3.400 + them.</para> 3.401 + 3.402 + <para>The first thing we'll do is isolate our experiment in a 3.403 + repository of its own. We use the <command role="hg-cmd">hg 3.404 + clone</command> command, but we don't need to clone a copy of 3.405 + the remote repository. Since we already have a copy of it 3.406 + locally, we can just clone that instead. This is much faster 3.407 + than cloning over the network, and cloning a local repository 3.408 + uses less disk space in most cases, too. <!-- 3.409 + &interaction.tour.reclone; --> As an aside, it's often good 3.410 + practice to keep a <quote>pristine</quote> copy of a remote 3.411 + repository around, which you can then make temporary clones of 3.412 + to create sandboxes for each task you want to work on. This 3.413 + lets you work on multiple tasks in parallel, each isolated from 3.414 + the others until it's complete and you're ready to integrate it 3.415 + back. Because local clones are so cheap, there's almost no 3.416 + overhead to cloning and destroying repositories whenever you 3.417 + want.</para> 3.418 + 3.419 + <para>In our <filename class="directory">my-hello</filename> 3.420 + repository, we have a file <filename>hello.c</filename> that 3.421 + contains the classic <quote>hello, world</quote> program. Let's 3.422 + use the ancient and venerable <command>sed</command> command to 3.423 + edit this file so that it prints a second line of output. (I'm 3.424 + only using <command>sed</command> to do this because it's easy 3.425 + to write a scripted example this way. Since you're not under 3.426 + the same constraint, you probably won't want to use 3.427 + <command>sed</command>; simply use your preferred text editor to 3.428 + do the same thing.) <!-- &interaction.tour.sed; --></para> 3.429 + 3.430 + <para>Mercurial's <command role="hg-cmd">hg status</command> 3.431 + command will tell us what Mercurial knows about the files in the 3.432 + repository. <!-- &interaction.tour.status; --> The <command 3.433 + role="hg-cmd">hg status</command> command prints no output for 3.434 + some files, but a line starting with 3.435 + <quote><literal>M</literal></quote> for 3.436 + <filename>hello.c</filename>. Unless you tell it to, <command 3.437 + role="hg-cmd">hg status</command> will not print any output 3.438 + for files that have not been modified.</para> 3.439 + 3.440 + <para>The <quote><literal>M</literal></quote> indicates that 3.441 + Mercurial has noticed that we modified 3.442 + <filename>hello.c</filename>. We didn't need to 3.443 + <emphasis>inform</emphasis> Mercurial that we were going to 3.444 + modify the file before we started, or that we had modified the 3.445 + file after we were done; it was able to figure this out 3.446 + itself.</para> 3.447 + 3.448 + <para>It's a little bit helpful to know that we've modified 3.449 + <filename>hello.c</filename>, but we might prefer to know 3.450 + exactly <emphasis>what</emphasis> changes we've made to it. To 3.451 + do this, we use the <command role="hg-cmd">hg diff</command> 3.452 + command. <!-- &interaction.tour.diff; --></para> 3.453 + 3.454 + </sect1> 3.455 + <sect1> 3.456 + <title>Recording changes in a new changeset</title> 3.457 + 3.458 + <para>We can modify files, build and test our changes, and use 3.459 + <command role="hg-cmd">hg status</command> and <command 3.460 + role="hg-cmd">hg diff</command> to review our changes, until 3.461 + we're satisfied with what we've done and arrive at a natural 3.462 + stopping point where we want to record our work in a new 3.463 + changeset.</para> 3.464 + 3.465 + <para>The <command role="hg-cmd">hg commit</command> command lets 3.466 + us create a new changeset; we'll usually refer to this as 3.467 + <quote>making a commit</quote> or 3.468 + <quote>committing</quote>.</para> 3.469 + 3.470 + <sect2> 3.471 + <title>Setting up a username</title> 3.472 + 3.473 + <para>When you try to run <command role="hg-cmd">hg 3.474 + commit</command> for the first time, it is not guaranteed to 3.475 + succeed. Mercurial records your name and address with each 3.476 + change that you commit, so that you and others will later be 3.477 + able to tell who made each change. Mercurial tries to 3.478 + automatically figure out a sensible username to commit the 3.479 + change with. It will attempt each of the following methods, 3.480 + in order:</para> 3.481 + <orderedlist> 3.482 + <listitem><para>If you specify a <option 3.483 + role="hg-opt-commit">-u</option> option to the <command 3.484 + role="hg-cmd">hg commit</command> command on the command 3.485 + line, followed by a username, this is always given the 3.486 + highest precedence.</para></listitem> 3.487 + <listitem><para>If you have set the <envar>HGUSER</envar> 3.488 + environment variable, this is checked 3.489 + next.</para></listitem> 3.490 + <listitem><para>If you create a file in your home directory 3.491 + called <filename role="special">.hgrc</filename>, with a 3.492 + <envar role="rc-item-ui">username</envar> entry, that will 3.493 + be used next. To see what the contents of this file 3.494 + should look like, refer to section <xref 3.495 + id="sec:tour-basic:username"/> 3.496 + below.</para></listitem> 3.497 + <listitem><para>If you have set the <envar>EMAIL</envar> 3.498 + environment variable, this will be used 3.499 + next.</para></listitem> 3.500 + <listitem><para>Mercurial will query your system to find out 3.501 + your local user name and host name, and construct a 3.502 + username from these components. Since this often results 3.503 + in a username that is not very useful, it will print a 3.504 + warning if it has to do 3.505 + this.</para></listitem></orderedlist> 3.506 + <listitem><para>If all of these mechanisms fail, Mercurial will 3.507 + fail, printing an error message. In this case, it will not 3.508 + let you commit until you set up a 3.509 + username.</para></listitem> 3.510 + <listitem><para>You should think of the <envar>HGUSER</envar> 3.511 + environment variable and the <option 3.512 + role="hg-opt-commit">-u</option> option to the <command 3.513 + role="hg-cmd">hg commit</command> command as ways to 3.514 + <emphasis>override</emphasis> Mercurial's default selection 3.515 + of username. For normal use, the simplest and most robust 3.516 + way to set a username for yourself is by creating a 3.517 + <filename role="special">.hgrc</filename> file; see below 3.518 + for details.</para></listitem> 3.519 + <sect3> 3.520 + <title>Creating a Mercurial configuration file</title> 3.521 + <listitem><para>\label{sec:tour-basic:username}</para></listitem> 3.522 + <listitem><para>To set a user name, use your favourite editor 3.523 + to create a file called <filename 3.524 + role="special">.hgrc</filename> in your home directory. 3.525 + Mercurial will use this file to look up your personalised 3.526 + configuration settings. The initial contents of your 3.527 + <filename role="special">.hgrc</filename> should look like 3.528 + this.</para></listitem><programlisting> 3.529 + <listitem><para> # This is a Mercurial configuration file. 3.530 + [ui] username = Firstname Lastname 3.531 + <email.address@domain.net></para></listitem></programlisting> 3.532 + <listitem><para>The <quote><literal>[ui]</literal></quote> 3.533 + line begins a <emphasis>section</emphasis> of the config 3.534 + file, so you can read the <quote><literal>username = 3.535 + ...</literal></quote> line as meaning <quote>set the 3.536 + value of the <literal>username</literal> item in the 3.537 + <literal>ui</literal> section</quote>. A section 3.538 + continues until a new section begins, or the end of the 3.539 + file. Mercurial ignores empty lines and treats any text 3.540 + from <quote><literal>#</literal></quote> to the end of a 3.541 + line as a comment.</para></listitem> 3.542 + </sect3> 3.543 + <sect3> 3.544 + <title>Choosing a user name</title> 3.545 + 3.546 + <listitem><para>You can use any text you like as the value of 3.547 + the <literal>username</literal> config item, since this 3.548 + information is for reading by other people, but for 3.549 + interpreting by Mercurial. The convention that most 3.550 + people follow is to use their name and email address, as 3.551 + in the example above.</para></listitem> 3.552 + <note> 3.553 + <listitem><para> Mercurial's built-in web server obfuscates 3.554 + email addresses, to make it more difficult for the email 3.555 + harvesting tools that spammers use. This reduces the 3.556 + likelihood that you'll start receiving more junk email 3.557 + if you publish a Mercurial repository on the 3.558 + web.</para></listitem></note> 3.559 + 3.560 + </sect3> 3.561 + </sect2> 3.562 + <sect2> 3.563 + <title>Writing a commit message</title> 3.564 + 3.565 + <listitem><para>When we commit a change, Mercurial drops us into 3.566 + a text editor, to enter a message that will describe the 3.567 + modifications we've made in this changeset. This is called 3.568 + the <emphasis>commit message</emphasis>. It will be a 3.569 + record for readers of what we did and why, and it will be 3.570 + printed by <command role="hg-cmd">hg log</command> after 3.571 + we've finished committing. <!-- &interaction.tour.commit; 3.572 + --></para></listitem> 3.573 + <listitem><para>The editor that the <command role="hg-cmd">hg 3.574 + commit</command> command drops us into will contain an 3.575 + empty line, followed by a number of lines starting with 3.576 + <quote><literal>HG:</literal></quote>.</para></listitem><programlisting> 3.577 + <listitem><para> <emphasis>empty line</emphasis> HG: changed 3.578 + hello.c</para></listitem></programlisting> 3.579 + <listitem><para>Mercurial ignores the lines that start with 3.580 + <quote><literal>HG:</literal></quote>; it uses them only to 3.581 + tell us which files it's recording changes to. Modifying or 3.582 + deleting these lines has no effect.</para></listitem> 3.583 + </sect2> 3.584 + <sect2> 3.585 + <title>Writing a good commit message</title> 3.586 + 3.587 + <listitem><para>Since <command role="hg-cmd">hg log</command> 3.588 + only prints the first line of a commit message by default, 3.589 + it's best to write a commit message whose first line stands 3.590 + alone. Here's a real example of a commit message that 3.591 + <emphasis>doesn't</emphasis> follow this guideline, and 3.592 + hence has a summary that is not 3.593 + readable.</para></listitem><programlisting> 3.594 + <listitem><para> changeset: 73:584af0e231be user: Censored 3.595 + Person <censored.person@example.org> date: Tue Sep 3.596 + 26 21:37:07 2006 -0700 summary: include 3.597 + buildmeister/commondefs. Add an exports and 3.598 + install</para></listitem></programlisting> 3.599 + 3.600 + <listitem><para>As far as the remainder of the contents of the 3.601 + commit message are concerned, there are no hard-and-fast 3.602 + rules. Mercurial itself doesn't interpret or care about the 3.603 + contents of the commit message, though your project may have 3.604 + policies that dictate a certain kind of 3.605 + formatting.</para></listitem> 3.606 + <listitem><para>My personal preference is for short, but 3.607 + informative, commit messages that tell me something that I 3.608 + can't figure out with a quick glance at the output of 3.609 + <command role="hg-cmd">hg log 3.610 + --patch</command>.</para></listitem> 3.611 + </sect2> 3.612 + <sect2> 3.613 + <title>Aborting a commit</title> 3.614 + 3.615 + <listitem><para>If you decide that you don't want to commit 3.616 + while in the middle of editing a commit message, simply exit 3.617 + from your editor without saving the file that it's editing. 3.618 + This will cause nothing to happen to either the repository 3.619 + or the working directory.</para></listitem> 3.620 + <listitem><para>If we run the <command role="hg-cmd">hg 3.621 + commit</command> command without any arguments, it records 3.622 + all of the changes we've made, as reported by <command 3.623 + role="hg-cmd">hg status</command> and <command 3.624 + role="hg-cmd">hg diff</command>.</para></listitem> 3.625 + </sect2> 3.626 + <sect2> 3.627 + <title>Admiring our new handiwork</title> 3.628 + 3.629 + <listitem><para>Once we've finished the commit, we can use the 3.630 + <command role="hg-cmd">hg tip</command> command to display 3.631 + the changeset we just created. This command produces output 3.632 + that is identical to <command role="hg-cmd">hg 3.633 + log</command>, but it only displays the newest revision in 3.634 + the repository. <!-- &interaction.tour.tip; --> We refer to 3.635 + the newest revision in the repository as the tip revision, 3.636 + or simply the tip.</para></listitem> 3.637 + </sect2> 3.638 + </sect1> 3.639 + <sect1> 3.640 + <title>Sharing changes</title> 3.641 + 3.642 + <listitem><para>We mentioned earlier that repositories in 3.643 + Mercurial are self-contained. This means that the changeset 3.644 + we just created exists only in our <filename 3.645 + class="directory">my-hello</filename> repository. Let's 3.646 + look at a few ways that we can propagate this change into 3.647 + other repositories.</para></listitem> 3.648 + <sect2> 3.649 + <title>Pulling changes from another repository</title> 3.650 + <listitem><para>\label{sec:tour:pull}</para></listitem> 3.651 + <listitem><para>To get started, let's clone our original 3.652 + <filename class="directory">hello</filename> repository, 3.653 + which does not contain the change we just committed. We'll 3.654 + call our temporary repository <filename 3.655 + class="directory">hello-pull</filename>. <!-- 3.656 + &interaction.tour.clone-pull; --></para></listitem> 3.657 + <listitem><para>We'll use the <command role="hg-cmd">hg 3.658 + pull</command> command to bring changes from <filename 3.659 + class="directory">my-hello</filename> into <filename 3.660 + class="directory">hello-pull</filename>. However, blindly 3.661 + pulling unknown changes into a repository is a somewhat 3.662 + scary prospect. Mercurial provides the <command 3.663 + role="hg-cmd">hg incoming</command> command to tell us 3.664 + what changes the <command role="hg-cmd">hg pull</command> 3.665 + command <emphasis>would</emphasis> pull into the repository, 3.666 + without actually pulling the changes in. <!-- 3.667 + &interaction.tour.incoming; --> (Of course, someone could 3.668 + cause more changesets to appear in the repository that we 3.669 + ran <command role="hg-cmd">hg incoming</command> in, before 3.670 + we get a chance to <command role="hg-cmd">hg pull</command> 3.671 + the changes, so that we could end up pulling changes that we 3.672 + didn't expect.)</para></listitem> 3.673 + <listitem><para>Bringing changes into a repository is a simple 3.674 + matter of running the <command role="hg-cmd">hg 3.675 + pull</command> command, and telling it which repository to 3.676 + pull from. <!-- &interaction.tour.pull; --> As you can see 3.677 + from the before-and-after output of <command 3.678 + role="hg-cmd">hg tip</command>, we have successfully 3.679 + pulled changes into our repository. There remains one step 3.680 + before we can see these changes in the working 3.681 + directory.</para></listitem> 3.682 + </sect2> 3.683 + <sect2> 3.684 + <title>Updating the working directory</title> 3.685 + 3.686 + <listitem><para>We have so far glossed over the relationship 3.687 + between a repository and its working directory. The 3.688 + <command role="hg-cmd">hg pull</command> command that we ran 3.689 + in section <xref id="sec:tour:pull"/> brought changes into 3.690 + the 3.691 + repository, but if we check, there's no sign of those 3.692 + changes in the working directory. This is because <command 3.693 + role="hg-cmd">hg pull</command> does not (by default) 3.694 + touch the working directory. Instead, we use the <command 3.695 + role="hg-cmd">hg update</command> command to do this. <!-- 3.696 + &interaction.tour.update; --></para></listitem> 3.697 + <listitem><para>It might seem a bit strange that <command 3.698 + role="hg-cmd">hg pull</command> doesn't update the working 3.699 + directory automatically. There's actually a good reason for 3.700 + this: you can use <command role="hg-cmd">hg update</command> 3.701 + to update the working directory to the state it was in at 3.702 + <emphasis>any revision</emphasis> in the history of the 3.703 + repository. If you had the working directory updated to an 3.704 + old revision---to hunt down the origin of a bug, say---and 3.705 + ran a <command role="hg-cmd">hg pull</command> which 3.706 + automatically updated the working directory to a new 3.707 + revision, you might not be terribly happy.</para></listitem> 3.708 + <listitem><para>However, since pull-then-update is such a common 3.709 + thing to do, Mercurial lets you combine the two by passing 3.710 + the <option role="hg-opt-pull">-u</option> option to 3.711 + <command role="hg-cmd">hg 3.712 + pull</command>.</para></listitem><programlisting> 3.713 + <listitem><para> hg pull 3.714 + -u</para></listitem></programlisting> 3.715 + <listitem><para>If you look back at the output of <command 3.716 + role="hg-cmd">hg pull</command> in section <xref 3.717 + id="sec:tour:pull"/> when we ran it without <option 3.718 + role="hg-opt-pull">-u</option>, you can see that it 3.719 + printed a helpful reminder that we'd have to take an 3.720 + explicit step to update the working 3.721 + directory:</para></listitem><programlisting> 3.722 + <listitem><para> (run 'hg update' to get a working 3.723 + copy)</para></listitem></programlisting> 3.724 + 3.725 + <listitem><para>To find out what revision the working directory 3.726 + is at, use the <command role="hg-cmd">hg parents</command> 3.727 + command. <!-- &interaction.tour.parents; --> If you look 3.728 + back at figure <xref id="fig:tour-basic:history"/>, you'll 3.729 + see arrows connecting each changeset. The node that the 3.730 + arrow leads <emphasis>from</emphasis> in each case is a 3.731 + parent, and the node that the arrow leads 3.732 + <emphasis>to</emphasis> is its child. The working directory 3.733 + has a parent in just the same way; this is the changeset 3.734 + that the working directory currently 3.735 + contains.</para></listitem> 3.736 + <listitem><para>To update the working directory to a particular 3.737 + revision, give a revision number or changeset ID to the 3.738 + <command role="hg-cmd">hg update</command> command. <!-- 3.739 + &interaction.tour.older; --> If you omit an explicit 3.740 + revision, <command role="hg-cmd">hg update</command> will 3.741 + update to the tip revision, as shown by the second call to 3.742 + <command role="hg-cmd">hg update</command> in the example 3.743 + above.</para></listitem> 3.744 + </sect2> 3.745 + <sect2> 3.746 + <title>Pushing changes to another repository</title> 3.747 + 3.748 + <listitem><para>Mercurial lets us push changes to another 3.749 + repository, from the repository we're currently visiting. 3.750 + As with the example of <command role="hg-cmd">hg 3.751 + pull</command> above, we'll create a temporary repository 3.752 + to push our changes into. <!-- &interaction.tour.clone-push; 3.753 + --> The <command role="hg-cmd">hg outgoing</command> command 3.754 + tells us what changes would be pushed into another 3.755 + repository. <!-- &interaction.tour.outgoing; --> And the 3.756 + <command role="hg-cmd">hg push</command> command does the 3.757 + actual push. <!-- &interaction.tour.push; --> As with 3.758 + <command role="hg-cmd">hg pull</command>, the <command 3.759 + role="hg-cmd">hg push</command> command does not update 3.760 + the working directory in the repository that it's pushing 3.761 + changes into. (Unlike <command role="hg-cmd">hg 3.762 + pull</command>, <command role="hg-cmd">hg push</command> 3.763 + does not provide a <literal>-u</literal> option that updates 3.764 + the other repository's working directory.)</para></listitem> 3.765 + <listitem><para>What happens if we try to pull or push changes 3.766 + and the receiving repository already has those changes? 3.767 + Nothing too exciting. <!-- &interaction.tour.push.nothing; 3.768 + --></para></listitem> 3.769 + </sect2> 3.770 + <sect2> 3.771 + <title>Sharing changes over a network</title> 3.772 + 3.773 + <listitem><para>The commands we have covered in the previous few 3.774 + sections are not limited to working with local repositories. 3.775 + Each works in exactly the same fashion over a network 3.776 + connection; simply pass in a URL instead of a local path. 3.777 + <!-- &interaction.tour.outgoing.net; --> In this example, we 3.778 + can see what changes we could push to the remote repository, 3.779 + but the repository is understandably not set up to let 3.780 + anonymous users push to it. <!-- &interaction.tour.push.net; 3.781 + --></para></listitem> 3.782 + </sect2> 3.783 + </sect1> 3.784 +</chapter> 3.785 + 3.786 +<!-- 3.787 +local variables: 3.788 +sgml-parent-document: ("00book.xml" "book" "chapter") 3.789 +end: 3.790 +-->