hgbook
changeset 583:28b5a5befb08
Fold preface and intro into one
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Thu Mar 19 20:54:12 2009 -0700 (2009-03-19) |
parents | 5bfa0df6aaed |
children | c838b3975bc6 |
files | en/00book.xml en/ch00-preface.xml en/ch01-intro.xml en/ch01-tour-basic.xml en/ch02-tour-basic.xml en/ch02-tour-merge.xml en/ch03-concepts.xml en/ch03-tour-merge.xml en/ch04-concepts.xml en/ch04-daily.xml en/ch05-collab.xml en/ch05-daily.xml en/ch06-collab.xml en/ch06-filenames.xml en/ch07-branch.xml en/ch07-filenames.xml en/ch08-branch.xml en/ch08-undo.xml en/ch09-hook.xml en/ch09-undo.xml en/ch10-hook.xml en/ch10-template.xml en/ch11-mq.xml en/ch11-template.xml en/ch12-mq-collab.xml en/ch12-mq.xml en/ch13-hgext.xml en/ch13-mq-collab.xml en/ch14-hgext.xml |
line diff
1.1 --- a/en/00book.xml Wed Mar 18 00:08:22 2009 -0700 1.2 +++ b/en/00book.xml Thu Mar 19 20:54:12 2009 -0700 1.3 @@ -7,20 +7,20 @@ 1.4 1.5 <!-- Chapters. --> 1.6 1.7 -<!ENTITY ch01 SYSTEM "ch01-intro.xml"> 1.8 -<!ENTITY ch02 SYSTEM "ch02-tour-basic.xml"> 1.9 -<!ENTITY ch03 SYSTEM "ch03-tour-merge.xml"> 1.10 -<!ENTITY ch04 SYSTEM "ch04-concepts.xml"> 1.11 -<!ENTITY ch05 SYSTEM "ch05-daily.xml"> 1.12 -<!ENTITY ch06 SYSTEM "ch06-collab.xml"> 1.13 -<!ENTITY ch07 SYSTEM "ch07-filenames.xml"> 1.14 -<!ENTITY ch08 SYSTEM "ch08-branch.xml"> 1.15 -<!ENTITY ch09 SYSTEM "ch09-undo.xml"> 1.16 -<!ENTITY ch10 SYSTEM "ch10-hook.xml"> 1.17 -<!ENTITY ch11 SYSTEM "ch11-template.xml"> 1.18 -<!ENTITY ch12 SYSTEM "ch12-mq.xml"> 1.19 -<!ENTITY ch13 SYSTEM "ch13-mq-collab.xml"> 1.20 -<!ENTITY ch14 SYSTEM "ch14-hgext.xml"> 1.21 +<!ENTITY ch00 SYSTEM "ch00-preface.xml"> 1.22 +<!ENTITY ch01 SYSTEM "ch01-tour-basic.xml"> 1.23 +<!ENTITY ch02 SYSTEM "ch02-tour-merge.xml"> 1.24 +<!ENTITY ch03 SYSTEM "ch03-concepts.xml"> 1.25 +<!ENTITY ch04 SYSTEM "ch04-daily.xml"> 1.26 +<!ENTITY ch05 SYSTEM "ch05-collab.xml"> 1.27 +<!ENTITY ch06 SYSTEM "ch06-filenames.xml"> 1.28 +<!ENTITY ch07 SYSTEM "ch07-branch.xml"> 1.29 +<!ENTITY ch08 SYSTEM "ch08-undo.xml"> 1.30 +<!ENTITY ch09 SYSTEM "ch09-hook.xml"> 1.31 +<!ENTITY ch10 SYSTEM "ch10-template.xml"> 1.32 +<!ENTITY ch11 SYSTEM "ch11-mq.xml"> 1.33 +<!ENTITY ch12 SYSTEM "ch12-mq-collab.xml"> 1.34 +<!ENTITY ch13 SYSTEM "ch13-hgext.xml"> 1.35 <!ENTITY appA SYSTEM "appA-cmdref.xml"> 1.36 <!ENTITY appB SYSTEM "appB-mq-ref.xml"> 1.37 <!ENTITY appC SYSTEM "appC-srcinstall.xml"> 1.38 @@ -74,7 +74,6 @@ 1.39 &ch11; 1.40 &ch12; 1.41 &ch13; 1.42 - &ch14; 1.43 <!-- &appA; --> 1.44 &appB; 1.45 &appC;
2.1 --- a/en/ch00-preface.xml Wed Mar 18 00:08:22 2009 -0700 2.2 +++ b/en/ch00-preface.xml Thu Mar 19 20:54:12 2009 -0700 2.3 @@ -3,23 +3,139 @@ 2.4 <preface id="chap:preface"> 2.5 <title>Preface</title> 2.6 2.7 - <para>Distributed revision control is a relatively new territory, 2.8 - and has thus far grown due to people's willingness to strike out 2.9 - into ill-charted territory.</para> 2.10 - 2.11 - <para>I am writing a book about distributed revision control because 2.12 - I believe that it is an important subject that deserves a field 2.13 - guide. I chose to write about Mercurial because it is the easiest 2.14 - tool to learn the terrain with, and yet it scales to the demands 2.15 - of real, challenging environments where many other revision 2.16 - control tools fail.</para> 2.17 + <sect1> 2.18 + <title>Why revision control? Why Mercurial?</title> 2.19 + 2.20 + <para>Revision control is the process of managing multiple 2.21 + versions of a piece of information. In its simplest form, this 2.22 + is something that many people do by hand: every time you modify 2.23 + a file, save it under a new name that contains a number, each 2.24 + one higher than the number of the preceding version.</para> 2.25 + 2.26 + <para>Manually managing multiple versions of even a single file is 2.27 + an error-prone task, though, so software tools to help automate 2.28 + this process have long been available. The earliest automated 2.29 + revision control tools were intended to help a single user to 2.30 + manage revisions of a single file. Over the past few decades, 2.31 + the scope of revision control tools has expanded greatly; they 2.32 + now manage multiple files, and help multiple people to work 2.33 + together. The best modern revision control tools have no 2.34 + problem coping with thousands of people working together on 2.35 + projects that consist of hundreds of thousands of files.</para> 2.36 + 2.37 + <para>The arrival of distributed revision control is relatively 2.38 + recent, and so far this new field has grown due to people's 2.39 + willingness to explore ill-charted territory.</para> 2.40 + 2.41 + <para>I am writing a book about distributed revision control 2.42 + because I believe that it is an important subject that deserves 2.43 + a field guide. I chose to write about Mercurial because it is 2.44 + the easiest tool to learn the terrain with, and yet it scales to 2.45 + the demands of real, challenging environments where many other 2.46 + revision control tools buckle.</para> 2.47 + 2.48 + <sect2> 2.49 + <title>Why use revision control?</title> 2.50 + 2.51 + <para>There are a number of reasons why you or your team might 2.52 + want to use an automated revision control tool for a 2.53 + project.</para> 2.54 + 2.55 + <itemizedlist> 2.56 + <listitem><para>It will track the history and evolution of 2.57 + your project, so you don't have to. For every change, 2.58 + you'll have a log of <emphasis>who</emphasis> made it; 2.59 + <emphasis>why</emphasis> they made it; 2.60 + <emphasis>when</emphasis> they made it; and 2.61 + <emphasis>what</emphasis> the change 2.62 + was.</para></listitem> 2.63 + <listitem><para>When you're working with other people, 2.64 + revision control software makes it easier for you to 2.65 + collaborate. For example, when people more or less 2.66 + simultaneously make potentially incompatible changes, the 2.67 + software will help you to identify and resolve those 2.68 + conflicts.</para></listitem> 2.69 + <listitem><para>It can help you to recover from mistakes. If 2.70 + you make a change that later turns out to be in error, you 2.71 + can revert to an earlier version of one or more files. In 2.72 + fact, a <emphasis>really</emphasis> good revision control 2.73 + tool will even help you to efficiently figure out exactly 2.74 + when a problem was introduced (see section <xref 2.75 + linkend="sec:undo:bisect"/> for details).</para></listitem> 2.76 + <listitem><para>It will help you to work simultaneously on, 2.77 + and manage the drift between, multiple versions of your 2.78 + project.</para></listitem> 2.79 + </itemizedlist> 2.80 + 2.81 + <para>Most of these reasons are equally valid---at least in 2.82 + theory---whether you're working on a project by yourself, or 2.83 + with a hundred other people.</para> 2.84 + 2.85 + <para>A key question about the practicality of revision control 2.86 + at these two different scales (<quote>lone hacker</quote> and 2.87 + <quote>huge team</quote>) is how its 2.88 + <emphasis>benefits</emphasis> compare to its 2.89 + <emphasis>costs</emphasis>. A revision control tool that's 2.90 + difficult to understand or use is going to impose a high 2.91 + cost.</para> 2.92 + 2.93 + <para>A five-hundred-person project is likely to collapse under 2.94 + its own weight almost immediately without a revision control 2.95 + tool and process. In this case, the cost of using revision 2.96 + control might hardly seem worth considering, since 2.97 + <emphasis>without</emphasis> it, failure is almost 2.98 + guaranteed.</para> 2.99 + 2.100 + <para>On the other hand, a one-person <quote>quick hack</quote> 2.101 + might seem like a poor place to use a revision control tool, 2.102 + because surely the cost of using one must be close to the 2.103 + overall cost of the project. Right?</para> 2.104 + 2.105 + <para>Mercurial uniquely supports <emphasis>both</emphasis> of 2.106 + these scales of development. You can learn the basics in just 2.107 + a few minutes, and due to its low overhead, you can apply 2.108 + revision control to the smallest of projects with ease. Its 2.109 + simplicity means you won't have a lot of abstruse concepts or 2.110 + command sequences competing for mental space with whatever 2.111 + you're <emphasis>really</emphasis> trying to do. At the same 2.112 + time, Mercurial's high performance and peer-to-peer nature let 2.113 + you scale painlessly to handle large projects.</para> 2.114 + 2.115 + <para>No revision control tool can rescue a poorly run project, 2.116 + but a good choice of tools can make a huge difference to the 2.117 + fluidity with which you can work on a project.</para> 2.118 + 2.119 + </sect2> 2.120 + 2.121 + <sect2> 2.122 + <title>The many names of revision control</title> 2.123 + 2.124 + <para>Revision control is a diverse field, so much so that it is 2.125 + referred to by many names and acronyms. Here are a few of the 2.126 + more common variations you'll encounter:</para> 2.127 + <itemizedlist> 2.128 + <listitem><para>Revision control (RCS)</para></listitem> 2.129 + <listitem><para>Software configuration management (SCM), or 2.130 + configuration management</para></listitem> 2.131 + <listitem><para>Source code management</para></listitem> 2.132 + <listitem><para>Source code control, or source 2.133 + control</para></listitem> 2.134 + <listitem><para>Version control 2.135 + (VCS)</para></listitem></itemizedlist> 2.136 + <para>Some people claim that these terms actually have different 2.137 + meanings, but in practice they overlap so much that there's no 2.138 + agreed or even useful way to tease them apart.</para> 2.139 + 2.140 + </sect2> 2.141 + </sect1> 2.142 2.143 <sect1> 2.144 <title>This book is a work in progress</title> 2.145 2.146 <para>I am releasing this book while I am still writing it, in the 2.147 - hope that it will prove useful to others. I also hope that 2.148 - readers will contribute as they see fit.</para> 2.149 + hope that it will prove useful to others. I am writing under an 2.150 + open license in the hope that you, my readers, will contribute 2.151 + feedback and perhaps content of your own.</para> 2.152 2.153 </sect1> 2.154 <sect1> 2.155 @@ -59,8 +175,567 @@ 2.156 seeing is consistent and reproducible.</para> 2.157 2.158 </sect1> 2.159 - <sect1> 2.160 - <title>Colophon---this book is Free</title> 2.161 + 2.162 + <sect1> 2.163 + <title>Trends in the field</title> 2.164 + 2.165 + <para>There has been an unmistakable trend in the development and 2.166 + use of revision control tools over the past four decades, as 2.167 + people have become familiar with the capabilities of their tools 2.168 + and constrained by their limitations.</para> 2.169 + 2.170 + <para>The first generation began by managing single files on 2.171 + individual computers. Although these tools represented a huge 2.172 + advance over ad-hoc manual revision control, their locking model 2.173 + and reliance on a single computer limited them to small, 2.174 + tightly-knit teams.</para> 2.175 + 2.176 + <para>The second generation loosened these constraints by moving 2.177 + to network-centered architectures, and managing entire projects 2.178 + at a time. As projects grew larger, they ran into new problems. 2.179 + With clients needing to talk to servers very frequently, server 2.180 + scaling became an issue for large projects. An unreliable 2.181 + network connection could prevent remote users from being able to 2.182 + talk to the server at all. As open source projects started 2.183 + making read-only access available anonymously to anyone, people 2.184 + without commit privileges found that they could not use the 2.185 + tools to interact with a project in a natural way, as they could 2.186 + not record their changes.</para> 2.187 + 2.188 + <para>The current generation of revision control tools is 2.189 + peer-to-peer in nature. All of these systems have dropped the 2.190 + dependency on a single central server, and allow people to 2.191 + distribute their revision control data to where it's actually 2.192 + needed. Collaboration over the Internet has moved from 2.193 + constrained by technology to a matter of choice and consensus. 2.194 + Modern tools can operate offline indefinitely and autonomously, 2.195 + with a network connection only needed when syncing changes with 2.196 + another repository.</para> 2.197 + 2.198 + </sect1> 2.199 + <sect1> 2.200 + <title>A few of the advantages of distributed revision 2.201 + control</title> 2.202 + 2.203 + <para>Even though distributed revision control tools have for 2.204 + several years been as robust and usable as their 2.205 + previous-generation counterparts, people using older tools have 2.206 + not yet necessarily woken up to their advantages. There are a 2.207 + number of ways in which distributed tools shine relative to 2.208 + centralised ones.</para> 2.209 + 2.210 + <para>For an individual developer, distributed tools are almost 2.211 + always much faster than centralised tools. This is for a simple 2.212 + reason: a centralised tool needs to talk over the network for 2.213 + many common operations, because most metadata is stored in a 2.214 + single copy on the central server. A distributed tool stores 2.215 + all of its metadata locally. All else being equal, talking over 2.216 + the network adds overhead to a centralised tool. Don't 2.217 + underestimate the value of a snappy, responsive tool: you're 2.218 + going to spend a lot of time interacting with your revision 2.219 + control software.</para> 2.220 + 2.221 + <para>Distributed tools are indifferent to the vagaries of your 2.222 + server infrastructure, again because they replicate metadata to 2.223 + so many locations. If you use a centralised system and your 2.224 + server catches fire, you'd better hope that your backup media 2.225 + are reliable, and that your last backup was recent and actually 2.226 + worked. With a distributed tool, you have many backups 2.227 + available on every contributor's computer.</para> 2.228 + 2.229 + <para>The reliability of your network will affect distributed 2.230 + tools far less than it will centralised tools. You can't even 2.231 + use a centralised tool without a network connection, except for 2.232 + a few highly constrained commands. With a distributed tool, if 2.233 + your network connection goes down while you're working, you may 2.234 + not even notice. The only thing you won't be able to do is talk 2.235 + to repositories on other computers, something that is relatively 2.236 + rare compared with local operations. If you have a far-flung 2.237 + team of collaborators, this may be significant.</para> 2.238 + 2.239 + <sect2> 2.240 + <title>Advantages for open source projects</title> 2.241 + 2.242 + <para>If you take a shine to an open source project and decide 2.243 + that you would like to start hacking on it, and that project 2.244 + uses a distributed revision control tool, you are at once a 2.245 + peer with the people who consider themselves the 2.246 + <quote>core</quote> of that project. If they publish their 2.247 + repositories, you can immediately copy their project history, 2.248 + start making changes, and record your work, using the same 2.249 + tools in the same ways as insiders. By contrast, with a 2.250 + centralised tool, you must use the software in a <quote>read 2.251 + only</quote> mode unless someone grants you permission to 2.252 + commit changes to their central server. Until then, you won't 2.253 + be able to record changes, and your local modifications will 2.254 + be at risk of corruption any time you try to update your 2.255 + client's view of the repository.</para> 2.256 + 2.257 + <sect3> 2.258 + <title>The forking non-problem</title> 2.259 + 2.260 + <para>It has been suggested that distributed revision control 2.261 + tools pose some sort of risk to open source projects because 2.262 + they make it easy to <quote>fork</quote> the development of 2.263 + a project. A fork happens when there are differences in 2.264 + opinion or attitude between groups of developers that cause 2.265 + them to decide that they can't work together any longer. 2.266 + Each side takes a more or less complete copy of the 2.267 + project's source code, and goes off in its own 2.268 + direction.</para> 2.269 + 2.270 + <para>Sometimes the camps in a fork decide to reconcile their 2.271 + differences. With a centralised revision control system, the 2.272 + <emphasis>technical</emphasis> process of reconciliation is 2.273 + painful, and has to be performed largely by hand. You have 2.274 + to decide whose revision history is going to 2.275 + <quote>win</quote>, and graft the other team's changes into 2.276 + the tree somehow. This usually loses some or all of one 2.277 + side's revision history.</para> 2.278 + 2.279 + <para>What distributed tools do with respect to forking is 2.280 + they make forking the <emphasis>only</emphasis> way to 2.281 + develop a project. Every single change that you make is 2.282 + potentially a fork point. The great strength of this 2.283 + approach is that a distributed revision control tool has to 2.284 + be really good at <emphasis>merging</emphasis> forks, 2.285 + because forks are absolutely fundamental: they happen all 2.286 + the time.</para> 2.287 + 2.288 + <para>If every piece of work that everybody does, all the 2.289 + time, is framed in terms of forking and merging, then what 2.290 + the open source world refers to as a <quote>fork</quote> 2.291 + becomes <emphasis>purely</emphasis> a social issue. If 2.292 + anything, distributed tools <emphasis>lower</emphasis> the 2.293 + likelihood of a fork:</para> 2.294 + <itemizedlist> 2.295 + <listitem><para>They eliminate the social distinction that 2.296 + centralised tools impose: that between insiders (people 2.297 + with commit access) and outsiders (people 2.298 + without).</para></listitem> 2.299 + <listitem><para>They make it easier to reconcile after a 2.300 + social fork, because all that's involved from the 2.301 + perspective of the revision control software is just 2.302 + another merge.</para></listitem></itemizedlist> 2.303 + 2.304 + <para>Some people resist distributed tools because they want 2.305 + to retain tight control over their projects, and they 2.306 + believe that centralised tools give them this control. 2.307 + However, if you're of this belief, and you publish your CVS 2.308 + or Subversion repositories publicly, there are plenty of 2.309 + tools available that can pull out your entire project's 2.310 + history (albeit slowly) and recreate it somewhere that you 2.311 + don't control. So while your control in this case is 2.312 + illusory, you are forgoing the ability to fluidly 2.313 + collaborate with whatever people feel compelled to mirror 2.314 + and fork your history.</para> 2.315 + 2.316 + </sect3> 2.317 + </sect2> 2.318 + <sect2> 2.319 + <title>Advantages for commercial projects</title> 2.320 + 2.321 + <para>Many commercial projects are undertaken by teams that are 2.322 + scattered across the globe. Contributors who are far from a 2.323 + central server will see slower command execution and perhaps 2.324 + less reliability. Commercial revision control systems attempt 2.325 + to ameliorate these problems with remote-site replication 2.326 + add-ons that are typically expensive to buy and cantankerous 2.327 + to administer. A distributed system doesn't suffer from these 2.328 + problems in the first place. Better yet, you can easily set 2.329 + up multiple authoritative servers, say one per site, so that 2.330 + there's no redundant communication between repositories over 2.331 + expensive long-haul network links.</para> 2.332 + 2.333 + <para>Centralised revision control systems tend to have 2.334 + relatively low scalability. It's not unusual for an expensive 2.335 + centralised system to fall over under the combined load of 2.336 + just a few dozen concurrent users. Once again, the typical 2.337 + response tends to be an expensive and clunky replication 2.338 + facility. Since the load on a central server---if you have 2.339 + one at all---is many times lower with a distributed tool 2.340 + (because all of the data is replicated everywhere), a single 2.341 + cheap server can handle the needs of a much larger team, and 2.342 + replication to balance load becomes a simple matter of 2.343 + scripting.</para> 2.344 + 2.345 + <para>If you have an employee in the field, troubleshooting a 2.346 + problem at a customer's site, they'll benefit from distributed 2.347 + revision control. The tool will let them generate custom 2.348 + builds, try different fixes in isolation from each other, and 2.349 + search efficiently through history for the sources of bugs and 2.350 + regressions in the customer's environment, all without needing 2.351 + to connect to your company's network.</para> 2.352 + 2.353 + </sect2> 2.354 + </sect1> 2.355 + <sect1> 2.356 + <title>Why choose Mercurial?</title> 2.357 + 2.358 + <para>Mercurial has a unique set of properties that make it a 2.359 + particularly good choice as a revision control system.</para> 2.360 + <itemizedlist> 2.361 + <listitem><para>It is easy to learn and use.</para></listitem> 2.362 + <listitem><para>It is lightweight.</para></listitem> 2.363 + <listitem><para>It scales excellently.</para></listitem> 2.364 + <listitem><para>It is easy to 2.365 + customise.</para></listitem></itemizedlist> 2.366 + 2.367 + <para>If you are at all familiar with revision control systems, 2.368 + you should be able to get up and running with Mercurial in less 2.369 + than five minutes. Even if not, it will take no more than a few 2.370 + minutes longer. Mercurial's command and feature sets are 2.371 + generally uniform and consistent, so you can keep track of a few 2.372 + general rules instead of a host of exceptions.</para> 2.373 + 2.374 + <para>On a small project, you can start working with Mercurial in 2.375 + moments. Creating new changes and branches; transferring changes 2.376 + around (whether locally or over a network); and history and 2.377 + status operations are all fast. Mercurial attempts to stay 2.378 + nimble and largely out of your way by combining low cognitive 2.379 + overhead with blazingly fast operations.</para> 2.380 + 2.381 + <para>The usefulness of Mercurial is not limited to small 2.382 + projects: it is used by projects with hundreds to thousands of 2.383 + contributors, each containing tens of thousands of files and 2.384 + hundreds of megabytes of source code.</para> 2.385 + 2.386 + <para>If the core functionality of Mercurial is not enough for 2.387 + you, it's easy to build on. Mercurial is well suited to 2.388 + scripting tasks, and its clean internals and implementation in 2.389 + Python make it easy to add features in the form of extensions. 2.390 + There are a number of popular and useful extensions already 2.391 + available, ranging from helping to identify bugs to improving 2.392 + performance.</para> 2.393 + 2.394 + </sect1> 2.395 + <sect1> 2.396 + <title>Mercurial compared with other tools</title> 2.397 + 2.398 + <para>Before you read on, please understand that this section 2.399 + necessarily reflects my own experiences, interests, and (dare I 2.400 + say it) biases. I have used every one of the revision control 2.401 + tools listed below, in most cases for several years at a 2.402 + time.</para> 2.403 + 2.404 + 2.405 + <sect2> 2.406 + <title>Subversion</title> 2.407 + 2.408 + <para>Subversion is a popular revision control tool, developed 2.409 + to replace CVS. It has a centralised client/server 2.410 + architecture.</para> 2.411 + 2.412 + <para>Subversion and Mercurial have similarly named commands for 2.413 + performing the same operations, so if you're familiar with 2.414 + one, it is easy to learn to use the other. Both tools are 2.415 + portable to all popular operating systems.</para> 2.416 + 2.417 + <para>Prior to version 1.5, Subversion had no useful support for 2.418 + merges. At the time of writing, its merge tracking capability 2.419 + is new, and known to be <ulink 2.420 + url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 2.421 + and buggy</ulink>.</para> 2.422 + 2.423 + <para>Mercurial has a substantial performance advantage over 2.424 + Subversion on every revision control operation I have 2.425 + benchmarked. I have measured its advantage as ranging from a 2.426 + factor of two to a factor of six when compared with Subversion 2.427 + 1.4.3's <emphasis>ra_local</emphasis> file store, which is the 2.428 + fastest access method available. In more realistic 2.429 + deployments involving a network-based store, Subversion will 2.430 + be at a substantially larger disadvantage. Because many 2.431 + Subversion commands must talk to the server and Subversion 2.432 + does not have useful replication facilities, server capacity 2.433 + and network bandwidth become bottlenecks for modestly large 2.434 + projects.</para> 2.435 + 2.436 + <para>Additionally, Subversion incurs substantial storage 2.437 + overhead to avoid network transactions for a few common 2.438 + operations, such as finding modified files 2.439 + (<literal>status</literal>) and displaying modifications 2.440 + against the current revision (<literal>diff</literal>). As a 2.441 + result, a Subversion working copy is often the same size as, 2.442 + or larger than, a Mercurial repository and working directory, 2.443 + even though the Mercurial repository contains a complete 2.444 + history of the project.</para> 2.445 + 2.446 + <para>Subversion is widely supported by third party tools. 2.447 + Mercurial currently lags considerably in this area. This gap 2.448 + is closing, however, and indeed some of Mercurial's GUI tools 2.449 + now outshine their Subversion equivalents. Like Mercurial, 2.450 + Subversion has an excellent user manual.</para> 2.451 + 2.452 + <para>Because Subversion doesn't store revision history on the 2.453 + client, it is well suited to managing projects that deal with 2.454 + lots of large, opaque binary files. If you check in fifty 2.455 + revisions to an incompressible 10MB file, Subversion's 2.456 + client-side space usage stays constant The space used by any 2.457 + distributed SCM will grow rapidly in proportion to the number 2.458 + of revisions, because the differences between each revision 2.459 + are large.</para> 2.460 + 2.461 + <para>In addition, it's often difficult or, more usually, 2.462 + impossible to merge different versions of a binary file. 2.463 + Subversion's ability to let a user lock a file, so that they 2.464 + temporarily have the exclusive right to commit changes to it, 2.465 + can be a significant advantage to a project where binary files 2.466 + are widely used.</para> 2.467 + 2.468 + <para>Mercurial can import revision history from a Subversion 2.469 + repository. It can also export revision history to a 2.470 + Subversion repository. This makes it easy to <quote>test the 2.471 + waters</quote> and use Mercurial and Subversion in parallel 2.472 + before deciding to switch. History conversion is incremental, 2.473 + so you can perform an initial conversion, then small 2.474 + additional conversions afterwards to bring in new 2.475 + changes.</para> 2.476 + 2.477 + 2.478 + </sect2> 2.479 + <sect2> 2.480 + <title>Git</title> 2.481 + 2.482 + <para>Git is a distributed revision control tool that was 2.483 + developed for managing the Linux kernel source tree. Like 2.484 + Mercurial, its early design was somewhat influenced by 2.485 + Monotone.</para> 2.486 + 2.487 + <para>Git has a very large command set, with version 1.5.0 2.488 + providing 139 individual commands. It has something of a 2.489 + reputation for being difficult to learn. Compared to Git, 2.490 + Mercurial has a strong focus on simplicity.</para> 2.491 + 2.492 + <para>In terms of performance, Git is extremely fast. In 2.493 + several cases, it is faster than Mercurial, at least on Linux, 2.494 + while Mercurial performs better on other operations. However, 2.495 + on Windows, the performance and general level of support that 2.496 + Git provides is, at the time of writing, far behind that of 2.497 + Mercurial.</para> 2.498 + 2.499 + <para>While a Mercurial repository needs no maintenance, a Git 2.500 + repository requires frequent manual <quote>repacks</quote> of 2.501 + its metadata. Without these, performance degrades, while 2.502 + space usage grows rapidly. A server that contains many Git 2.503 + repositories that are not rigorously and frequently repacked 2.504 + will become heavily disk-bound during backups, and there have 2.505 + been instances of daily backups taking far longer than 24 2.506 + hours as a result. A freshly packed Git repository is 2.507 + slightly smaller than a Mercurial repository, but an unpacked 2.508 + repository is several orders of magnitude larger.</para> 2.509 + 2.510 + <para>The core of Git is written in C. Many Git commands are 2.511 + implemented as shell or Perl scripts, and the quality of these 2.512 + scripts varies widely. I have encountered several instances 2.513 + where scripts charged along blindly in the presence of errors 2.514 + that should have been fatal.</para> 2.515 + 2.516 + <para>Mercurial can import revision history from a Git 2.517 + repository.</para> 2.518 + 2.519 + 2.520 + </sect2> 2.521 + <sect2> 2.522 + <title>CVS</title> 2.523 + 2.524 + <para>CVS is probably the most widely used revision control tool 2.525 + in the world. Due to its age and internal untidiness, it has 2.526 + been only lightly maintained for many years.</para> 2.527 + 2.528 + <para>It has a centralised client/server architecture. It does 2.529 + not group related file changes into atomic commits, making it 2.530 + easy for people to <quote>break the build</quote>: one person 2.531 + can successfully commit part of a change and then be blocked 2.532 + by the need for a merge, causing other people to see only a 2.533 + portion of the work they intended to do. This also affects 2.534 + how you work with project history. If you want to see all of 2.535 + the modifications someone made as part of a task, you will 2.536 + need to manually inspect the descriptions and timestamps of 2.537 + the changes made to each file involved (if you even know what 2.538 + those files were).</para> 2.539 + 2.540 + <para>CVS has a muddled notion of tags and branches that I will 2.541 + not attempt to even describe. It does not support renaming of 2.542 + files or directories well, making it easy to corrupt a 2.543 + repository. It has almost no internal consistency checking 2.544 + capabilities, so it is usually not even possible to tell 2.545 + whether or how a repository is corrupt. I would not recommend 2.546 + CVS for any project, existing or new.</para> 2.547 + 2.548 + <para>Mercurial can import CVS revision history. However, there 2.549 + are a few caveats that apply; these are true of every other 2.550 + revision control tool's CVS importer, too. Due to CVS's lack 2.551 + of atomic changes and unversioned filesystem hierarchy, it is 2.552 + not possible to reconstruct CVS history completely accurately; 2.553 + some guesswork is involved, and renames will usually not show 2.554 + up. Because a lot of advanced CVS administration has to be 2.555 + done by hand and is hence error-prone, it's common for CVS 2.556 + importers to run into multiple problems with corrupted 2.557 + repositories (completely bogus revision timestamps and files 2.558 + that have remained locked for over a decade are just two of 2.559 + the less interesting problems I can recall from personal 2.560 + experience).</para> 2.561 + 2.562 + <para>Mercurial can import revision history from a CVS 2.563 + repository.</para> 2.564 + 2.565 + 2.566 + </sect2> 2.567 + <sect2> 2.568 + <title>Commercial tools</title> 2.569 + 2.570 + <para>Perforce has a centralised client/server architecture, 2.571 + with no client-side caching of any data. Unlike modern 2.572 + revision control tools, Perforce requires that a user run a 2.573 + command to inform the server about every file they intend to 2.574 + edit.</para> 2.575 + 2.576 + <para>The performance of Perforce is quite good for small teams, 2.577 + but it falls off rapidly as the number of users grows beyond a 2.578 + few dozen. Modestly large Perforce installations require the 2.579 + deployment of proxies to cope with the load their users 2.580 + generate.</para> 2.581 + 2.582 + 2.583 + </sect2> 2.584 + <sect2> 2.585 + <title>Choosing a revision control tool</title> 2.586 + 2.587 + <para>With the exception of CVS, all of the tools listed above 2.588 + have unique strengths that suit them to particular styles of 2.589 + work. There is no single revision control tool that is best 2.590 + in all situations.</para> 2.591 + 2.592 + <para>As an example, Subversion is a good choice for working 2.593 + with frequently edited binary files, due to its centralised 2.594 + nature and support for file locking.</para> 2.595 + 2.596 + <para>I personally find Mercurial's properties of simplicity, 2.597 + performance, and good merge support to be a compelling 2.598 + combination that has served me well for several years.</para> 2.599 + 2.600 + 2.601 + </sect2> 2.602 + </sect1> 2.603 + <sect1> 2.604 + <title>Switching from another tool to Mercurial</title> 2.605 + 2.606 + <para>Mercurial is bundled with an extension named <literal 2.607 + role="hg-ext">convert</literal>, which can incrementally 2.608 + import revision history from several other revision control 2.609 + tools. By <quote>incremental</quote>, I mean that you can 2.610 + convert all of a project's history to date in one go, then rerun 2.611 + the conversion later to obtain new changes that happened after 2.612 + the initial conversion.</para> 2.613 + 2.614 + <para>The revision control tools supported by <literal 2.615 + role="hg-ext">convert</literal> are as follows:</para> 2.616 + <itemizedlist> 2.617 + <listitem><para>Subversion</para></listitem> 2.618 + <listitem><para>CVS</para></listitem> 2.619 + <listitem><para>Git</para></listitem> 2.620 + <listitem><para>Darcs</para></listitem></itemizedlist> 2.621 + 2.622 + <para>In addition, <literal role="hg-ext">convert</literal> can 2.623 + export changes from Mercurial to Subversion. This makes it 2.624 + possible to try Subversion and Mercurial in parallel before 2.625 + committing to a switchover, without risking the loss of any 2.626 + work.</para> 2.627 + 2.628 + <para>The <command role="hg-ext-convert">convert</command> command 2.629 + is easy to use. Simply point it at the path or URL of the 2.630 + source repository, optionally give it the name of the 2.631 + destination repository, and it will start working. After the 2.632 + initial conversion, just run the same command again to import 2.633 + new changes.</para> 2.634 + </sect1> 2.635 + 2.636 + <sect1> 2.637 + <title>A short history of revision control</title> 2.638 + 2.639 + <para>The best known of the old-time revision control tools is 2.640 + SCCS (Source Code Control System), which Marc Rochkind wrote at 2.641 + Bell Labs, in the early 1970s. SCCS operated on individual 2.642 + files, and required every person working on a project to have 2.643 + access to a shared workspace on a single system. Only one 2.644 + person could modify a file at any time; arbitration for access 2.645 + to files was via locks. It was common for people to lock files, 2.646 + and later forget to unlock them, preventing anyone else from 2.647 + modifying those files without the help of an 2.648 + administrator.</para> 2.649 + 2.650 + <para>Walter Tichy developed a free alternative to SCCS in the 2.651 + early 1980s; he called his program RCS (Revision Control System). 2.652 + Like SCCS, RCS required developers to work in a single shared 2.653 + workspace, and to lock files to prevent multiple people from 2.654 + modifying them simultaneously.</para> 2.655 + 2.656 + <para>Later in the 1980s, Dick Grune used RCS as a building block 2.657 + for a set of shell scripts he initially called cmt, but then 2.658 + renamed to CVS (Concurrent Versions System). The big innovation 2.659 + of CVS was that it let developers work simultaneously and 2.660 + somewhat independently in their own personal workspaces. The 2.661 + personal workspaces prevented developers from stepping on each 2.662 + other's toes all the time, as was common with SCCS and RCS. Each 2.663 + developer had a copy of every project file, and could modify 2.664 + their copies independently. They had to merge their edits prior 2.665 + to committing changes to the central repository.</para> 2.666 + 2.667 + <para>Brian Berliner took Grune's original scripts and rewrote 2.668 + them in C, releasing in 1989 the code that has since developed 2.669 + into the modern version of CVS. CVS subsequently acquired the 2.670 + ability to operate over a network connection, giving it a 2.671 + client/server architecture. CVS's architecture is centralised; 2.672 + only the server has a copy of the history of the project. Client 2.673 + workspaces just contain copies of recent versions of the 2.674 + project's files, and a little metadata to tell them where the 2.675 + server is. CVS has been enormously successful; it is probably 2.676 + the world's most widely used revision control system.</para> 2.677 + 2.678 + <para>In the early 1990s, Sun Microsystems developed an early 2.679 + distributed revision control system, called TeamWare. A 2.680 + TeamWare workspace contains a complete copy of the project's 2.681 + history. TeamWare has no notion of a central repository. (CVS 2.682 + relied upon RCS for its history storage; TeamWare used 2.683 + SCCS.)</para> 2.684 + 2.685 + <para>As the 1990s progressed, awareness grew of a number of 2.686 + problems with CVS. It records simultaneous changes to multiple 2.687 + files individually, instead of grouping them together as a 2.688 + single logically atomic operation. It does not manage its file 2.689 + hierarchy well; it is easy to make a mess of a repository by 2.690 + renaming files and directories. Worse, its source code is 2.691 + difficult to read and maintain, which made the <quote>pain 2.692 + level</quote> of fixing these architectural problems 2.693 + prohibitive.</para> 2.694 + 2.695 + <para>In 2001, Jim Blandy and Karl Fogel, two developers who had 2.696 + worked on CVS, started a project to replace it with a tool that 2.697 + would have a better architecture and cleaner code. The result, 2.698 + Subversion, does not stray from CVS's centralised client/server 2.699 + model, but it adds multi-file atomic commits, better namespace 2.700 + management, and a number of other features that make it a 2.701 + generally better tool than CVS. Since its initial release, it 2.702 + has rapidly grown in popularity.</para> 2.703 + 2.704 + <para>More or less simultaneously, Graydon Hoare began working on 2.705 + an ambitious distributed revision control system that he named 2.706 + Monotone. While Monotone addresses many of CVS's design flaws 2.707 + and has a peer-to-peer architecture, it goes beyond earlier (and 2.708 + subsequent) revision control tools in a number of innovative 2.709 + ways. It uses cryptographic hashes as identifiers, and has an 2.710 + integral notion of <quote>trust</quote> for code from different 2.711 + sources.</para> 2.712 + 2.713 + <para>Mercurial began life in 2005. While a few aspects of its 2.714 + design are influenced by Monotone, Mercurial focuses on ease of 2.715 + use, high performance, and scalability to very large 2.716 + projects.</para> 2.717 + 2.718 + </sect1> 2.719 + 2.720 + <sect1> 2.721 + <title>Colophon&emdash;this book is Free</title> 2.722 2.723 <para>This book is licensed under the Open Publication License, 2.724 and is produced entirely using Free Software tools. It is
3.1 --- a/en/ch01-intro.xml Wed Mar 18 00:08:22 2009 -0700 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,680 +0,0 @@ 3.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 3.5 - 3.6 -<chapter id="chap:intro"> 3.7 - <?dbhtml filename="introduction.html"?> 3.8 - <title>Introduction</title> 3.9 - 3.10 - <sect1> 3.11 - <title>About revision control</title> 3.12 - 3.13 - <para>Revision control is the process of managing multiple 3.14 - versions of a piece of information. In its simplest form, this 3.15 - is something that many people do by hand: every time you modify 3.16 - a file, save it under a new name that contains a number, each 3.17 - one higher than the number of the preceding version.</para> 3.18 - 3.19 - <para>Manually managing multiple versions of even a single file is 3.20 - an error-prone task, though, so software tools to help automate 3.21 - this process have long been available. The earliest automated 3.22 - revision control tools were intended to help a single user to 3.23 - manage revisions of a single file. Over the past few decades, 3.24 - the scope of revision control tools has expanded greatly; they 3.25 - now manage multiple files, and help multiple people to work 3.26 - together. The best modern revision control tools have no 3.27 - problem coping with thousands of people working together on 3.28 - projects that consist of hundreds of thousands of files.</para> 3.29 - 3.30 - <sect2> 3.31 - <title>Why use revision control?</title> 3.32 - 3.33 - <para>There are a number of reasons why you or your team might 3.34 - want to use an automated revision control tool for a 3.35 - project.</para> 3.36 - <itemizedlist> 3.37 - <listitem><para>It will track the history and evolution of 3.38 - your project, so you don't have to. For every change, 3.39 - you'll have a log of <emphasis>who</emphasis> made it; 3.40 - <emphasis>why</emphasis> they made it; 3.41 - <emphasis>when</emphasis> they made it; and 3.42 - <emphasis>what</emphasis> the change 3.43 - was.</para></listitem> 3.44 - <listitem><para>When you're working with other people, 3.45 - revision control software makes it easier for you to 3.46 - collaborate. For example, when people more or less 3.47 - simultaneously make potentially incompatible changes, the 3.48 - software will help you to identify and resolve those 3.49 - conflicts.</para></listitem> 3.50 - <listitem><para>It can help you to recover from mistakes. If 3.51 - you make a change that later turns out to be in error, you 3.52 - can revert to an earlier version of one or more files. In 3.53 - fact, a <emphasis>really</emphasis> good revision control 3.54 - tool will even help you to efficiently figure out exactly 3.55 - when a problem was introduced (see section <xref 3.56 - linkend="sec:undo:bisect"/> for details).</para></listitem> 3.57 - <listitem><para>It will help you to work simultaneously on, 3.58 - and manage the drift between, multiple versions of your 3.59 - project.</para></listitem></itemizedlist> 3.60 - <para>Most of these reasons are equally valid---at least in 3.61 - theory---whether you're working on a project by yourself, or 3.62 - with a hundred other people.</para> 3.63 - 3.64 - <para>A key question about the practicality of revision control 3.65 - at these two different scales (<quote>lone hacker</quote> and 3.66 - <quote>huge team</quote>) is how its 3.67 - <emphasis>benefits</emphasis> compare to its 3.68 - <emphasis>costs</emphasis>. A revision control tool that's 3.69 - difficult to understand or use is going to impose a high 3.70 - cost.</para> 3.71 - 3.72 - <para>A five-hundred-person project is likely to collapse under 3.73 - its own weight almost immediately without a revision control 3.74 - tool and process. In this case, the cost of using revision 3.75 - control might hardly seem worth considering, since 3.76 - <emphasis>without</emphasis> it, failure is almost 3.77 - guaranteed.</para> 3.78 - 3.79 - <para>On the other hand, a one-person <quote>quick hack</quote> 3.80 - might seem like a poor place to use a revision control tool, 3.81 - because surely the cost of using one must be close to the 3.82 - overall cost of the project. Right?</para> 3.83 - 3.84 - <para>Mercurial uniquely supports <emphasis>both</emphasis> of 3.85 - these scales of development. You can learn the basics in just 3.86 - a few minutes, and due to its low overhead, you can apply 3.87 - revision control to the smallest of projects with ease. Its 3.88 - simplicity means you won't have a lot of abstruse concepts or 3.89 - command sequences competing for mental space with whatever 3.90 - you're <emphasis>really</emphasis> trying to do. At the same 3.91 - time, Mercurial's high performance and peer-to-peer nature let 3.92 - you scale painlessly to handle large projects.</para> 3.93 - 3.94 - <para>No revision control tool can rescue a poorly run project, 3.95 - but a good choice of tools can make a huge difference to the 3.96 - fluidity with which you can work on a project.</para> 3.97 - 3.98 - </sect2> 3.99 - <sect2> 3.100 - <title>The many names of revision control</title> 3.101 - 3.102 - <para>Revision control is a diverse field, so much so that it 3.103 - doesn't actually have a single name or acronym. Here are a 3.104 - few of the more common names and acronyms you'll 3.105 - encounter:</para> 3.106 - <itemizedlist> 3.107 - <listitem><para>Revision control (RCS)</para></listitem> 3.108 - <listitem><para>Software configuration management (SCM), or 3.109 - configuration management</para></listitem> 3.110 - <listitem><para>Source code management</para></listitem> 3.111 - <listitem><para>Source code control, or source 3.112 - control</para></listitem> 3.113 - <listitem><para>Version control 3.114 - (VCS)</para></listitem></itemizedlist> 3.115 - <para>Some people claim that these terms actually have different 3.116 - meanings, but in practice they overlap so much that there's no 3.117 - agreed or even useful way to tease them apart.</para> 3.118 - 3.119 - </sect2> 3.120 - </sect1> 3.121 - <sect1> 3.122 - <title>A short history of revision control</title> 3.123 - 3.124 - <para>The best known of the old-time revision control tools is 3.125 - SCCS (Source Code Control System), which Marc Rochkind wrote at 3.126 - Bell Labs, in the early 1970s. SCCS operated on individual 3.127 - files, and required every person working on a project to have 3.128 - access to a shared workspace on a single system. Only one 3.129 - person could modify a file at any time; arbitration for access 3.130 - to files was via locks. It was common for people to lock files, 3.131 - and later forget to unlock them, preventing anyone else from 3.132 - modifying those files without the help of an 3.133 - administrator.</para> 3.134 - 3.135 - <para>Walter Tichy developed a free alternative to SCCS in the 3.136 - early 1980s; he called his program RCS (Revision Control System). 3.137 - Like SCCS, RCS required developers to work in a single shared 3.138 - workspace, and to lock files to prevent multiple people from 3.139 - modifying them simultaneously.</para> 3.140 - 3.141 - <para>Later in the 1980s, Dick Grune used RCS as a building block 3.142 - for a set of shell scripts he initially called cmt, but then 3.143 - renamed to CVS (Concurrent Versions System). The big innovation 3.144 - of CVS was that it let developers work simultaneously and 3.145 - somewhat independently in their own personal workspaces. The 3.146 - personal workspaces prevented developers from stepping on each 3.147 - other's toes all the time, as was common with SCCS and RCS. Each 3.148 - developer had a copy of every project file, and could modify 3.149 - their copies independently. They had to merge their edits prior 3.150 - to committing changes to the central repository.</para> 3.151 - 3.152 - <para>Brian Berliner took Grune's original scripts and rewrote 3.153 - them in C, releasing in 1989 the code that has since developed 3.154 - into the modern version of CVS. CVS subsequently acquired the 3.155 - ability to operate over a network connection, giving it a 3.156 - client/server architecture. CVS's architecture is centralised; 3.157 - only the server has a copy of the history of the project. Client 3.158 - workspaces just contain copies of recent versions of the 3.159 - project's files, and a little metadata to tell them where the 3.160 - server is. CVS has been enormously successful; it is probably 3.161 - the world's most widely used revision control system.</para> 3.162 - 3.163 - <para>In the early 1990s, Sun Microsystems developed an early 3.164 - distributed revision control system, called TeamWare. A 3.165 - TeamWare workspace contains a complete copy of the project's 3.166 - history. TeamWare has no notion of a central repository. (CVS 3.167 - relied upon RCS for its history storage; TeamWare used 3.168 - SCCS.)</para> 3.169 - 3.170 - <para>As the 1990s progressed, awareness grew of a number of 3.171 - problems with CVS. It records simultaneous changes to multiple 3.172 - files individually, instead of grouping them together as a 3.173 - single logically atomic operation. It does not manage its file 3.174 - hierarchy well; it is easy to make a mess of a repository by 3.175 - renaming files and directories. Worse, its source code is 3.176 - difficult to read and maintain, which made the <quote>pain 3.177 - level</quote> of fixing these architectural problems 3.178 - prohibitive.</para> 3.179 - 3.180 - <para>In 2001, Jim Blandy and Karl Fogel, two developers who had 3.181 - worked on CVS, started a project to replace it with a tool that 3.182 - would have a better architecture and cleaner code. The result, 3.183 - Subversion, does not stray from CVS's centralised client/server 3.184 - model, but it adds multi-file atomic commits, better namespace 3.185 - management, and a number of other features that make it a 3.186 - generally better tool than CVS. Since its initial release, it 3.187 - has rapidly grown in popularity.</para> 3.188 - 3.189 - <para>More or less simultaneously, Graydon Hoare began working on 3.190 - an ambitious distributed revision control system that he named 3.191 - Monotone. While Monotone addresses many of CVS's design flaws 3.192 - and has a peer-to-peer architecture, it goes beyond earlier (and 3.193 - subsequent) revision control tools in a number of innovative 3.194 - ways. It uses cryptographic hashes as identifiers, and has an 3.195 - integral notion of <quote>trust</quote> for code from different 3.196 - sources.</para> 3.197 - 3.198 - <para>Mercurial began life in 2005. While a few aspects of its 3.199 - design are influenced by Monotone, Mercurial focuses on ease of 3.200 - use, high performance, and scalability to very large 3.201 - projects.</para> 3.202 - 3.203 - </sect1> 3.204 - <sect1> 3.205 - <title>Trends in revision control</title> 3.206 - 3.207 - <para>There has been an unmistakable trend in the development and 3.208 - use of revision control tools over the past four decades, as 3.209 - people have become familiar with the capabilities of their tools 3.210 - and constrained by their limitations.</para> 3.211 - 3.212 - <para>The first generation began by managing single files on 3.213 - individual computers. Although these tools represented a huge 3.214 - advance over ad-hoc manual revision control, their locking model 3.215 - and reliance on a single computer limited them to small, 3.216 - tightly-knit teams.</para> 3.217 - 3.218 - <para>The second generation loosened these constraints by moving 3.219 - to network-centered architectures, and managing entire projects 3.220 - at a time. As projects grew larger, they ran into new problems. 3.221 - With clients needing to talk to servers very frequently, server 3.222 - scaling became an issue for large projects. An unreliable 3.223 - network connection could prevent remote users from being able to 3.224 - talk to the server at all. As open source projects started 3.225 - making read-only access available anonymously to anyone, people 3.226 - without commit privileges found that they could not use the 3.227 - tools to interact with a project in a natural way, as they could 3.228 - not record their changes.</para> 3.229 - 3.230 - <para>The current generation of revision control tools is 3.231 - peer-to-peer in nature. All of these systems have dropped the 3.232 - dependency on a single central server, and allow people to 3.233 - distribute their revision control data to where it's actually 3.234 - needed. Collaboration over the Internet has moved from 3.235 - constrained by technology to a matter of choice and consensus. 3.236 - Modern tools can operate offline indefinitely and autonomously, 3.237 - with a network connection only needed when syncing changes with 3.238 - another repository.</para> 3.239 - 3.240 - </sect1> 3.241 - <sect1> 3.242 - <title>A few of the advantages of distributed revision 3.243 - control</title> 3.244 - 3.245 - <para>Even though distributed revision control tools have for 3.246 - several years been as robust and usable as their 3.247 - previous-generation counterparts, people using older tools have 3.248 - not yet necessarily woken up to their advantages. There are a 3.249 - number of ways in which distributed tools shine relative to 3.250 - centralised ones.</para> 3.251 - 3.252 - <para>For an individual developer, distributed tools are almost 3.253 - always much faster than centralised tools. This is for a simple 3.254 - reason: a centralised tool needs to talk over the network for 3.255 - many common operations, because most metadata is stored in a 3.256 - single copy on the central server. A distributed tool stores 3.257 - all of its metadata locally. All else being equal, talking over 3.258 - the network adds overhead to a centralised tool. Don't 3.259 - underestimate the value of a snappy, responsive tool: you're 3.260 - going to spend a lot of time interacting with your revision 3.261 - control software.</para> 3.262 - 3.263 - <para>Distributed tools are indifferent to the vagaries of your 3.264 - server infrastructure, again because they replicate metadata to 3.265 - so many locations. If you use a centralised system and your 3.266 - server catches fire, you'd better hope that your backup media 3.267 - are reliable, and that your last backup was recent and actually 3.268 - worked. With a distributed tool, you have many backups 3.269 - available on every contributor's computer.</para> 3.270 - 3.271 - <para>The reliability of your network will affect distributed 3.272 - tools far less than it will centralised tools. You can't even 3.273 - use a centralised tool without a network connection, except for 3.274 - a few highly constrained commands. With a distributed tool, if 3.275 - your network connection goes down while you're working, you may 3.276 - not even notice. The only thing you won't be able to do is talk 3.277 - to repositories on other computers, something that is relatively 3.278 - rare compared with local operations. If you have a far-flung 3.279 - team of collaborators, this may be significant.</para> 3.280 - 3.281 - <sect2> 3.282 - <title>Advantages for open source projects</title> 3.283 - 3.284 - <para>If you take a shine to an open source project and decide 3.285 - that you would like to start hacking on it, and that project 3.286 - uses a distributed revision control tool, you are at once a 3.287 - peer with the people who consider themselves the 3.288 - <quote>core</quote> of that project. If they publish their 3.289 - repositories, you can immediately copy their project history, 3.290 - start making changes, and record your work, using the same 3.291 - tools in the same ways as insiders. By contrast, with a 3.292 - centralised tool, you must use the software in a <quote>read 3.293 - only</quote> mode unless someone grants you permission to 3.294 - commit changes to their central server. Until then, you won't 3.295 - be able to record changes, and your local modifications will 3.296 - be at risk of corruption any time you try to update your 3.297 - client's view of the repository.</para> 3.298 - 3.299 - <sect3> 3.300 - <title>The forking non-problem</title> 3.301 - 3.302 - <para>It has been suggested that distributed revision control 3.303 - tools pose some sort of risk to open source projects because 3.304 - they make it easy to <quote>fork</quote> the development of 3.305 - a project. A fork happens when there are differences in 3.306 - opinion or attitude between groups of developers that cause 3.307 - them to decide that they can't work together any longer. 3.308 - Each side takes a more or less complete copy of the 3.309 - project's source code, and goes off in its own 3.310 - direction.</para> 3.311 - 3.312 - <para>Sometimes the camps in a fork decide to reconcile their 3.313 - differences. With a centralised revision control system, the 3.314 - <emphasis>technical</emphasis> process of reconciliation is 3.315 - painful, and has to be performed largely by hand. You have 3.316 - to decide whose revision history is going to 3.317 - <quote>win</quote>, and graft the other team's changes into 3.318 - the tree somehow. This usually loses some or all of one 3.319 - side's revision history.</para> 3.320 - 3.321 - <para>What distributed tools do with respect to forking is 3.322 - they make forking the <emphasis>only</emphasis> way to 3.323 - develop a project. Every single change that you make is 3.324 - potentially a fork point. The great strength of this 3.325 - approach is that a distributed revision control tool has to 3.326 - be really good at <emphasis>merging</emphasis> forks, 3.327 - because forks are absolutely fundamental: they happen all 3.328 - the time.</para> 3.329 - 3.330 - <para>If every piece of work that everybody does, all the 3.331 - time, is framed in terms of forking and merging, then what 3.332 - the open source world refers to as a <quote>fork</quote> 3.333 - becomes <emphasis>purely</emphasis> a social issue. If 3.334 - anything, distributed tools <emphasis>lower</emphasis> the 3.335 - likelihood of a fork:</para> 3.336 - <itemizedlist> 3.337 - <listitem><para>They eliminate the social distinction that 3.338 - centralised tools impose: that between insiders (people 3.339 - with commit access) and outsiders (people 3.340 - without).</para></listitem> 3.341 - <listitem><para>They make it easier to reconcile after a 3.342 - social fork, because all that's involved from the 3.343 - perspective of the revision control software is just 3.344 - another merge.</para></listitem></itemizedlist> 3.345 - 3.346 - <para>Some people resist distributed tools because they want 3.347 - to retain tight control over their projects, and they 3.348 - believe that centralised tools give them this control. 3.349 - However, if you're of this belief, and you publish your CVS 3.350 - or Subversion repositories publicly, there are plenty of 3.351 - tools available that can pull out your entire project's 3.352 - history (albeit slowly) and recreate it somewhere that you 3.353 - don't control. So while your control in this case is 3.354 - illusory, you are forgoing the ability to fluidly 3.355 - collaborate with whatever people feel compelled to mirror 3.356 - and fork your history.</para> 3.357 - 3.358 - </sect3> 3.359 - </sect2> 3.360 - <sect2> 3.361 - <title>Advantages for commercial projects</title> 3.362 - 3.363 - <para>Many commercial projects are undertaken by teams that are 3.364 - scattered across the globe. Contributors who are far from a 3.365 - central server will see slower command execution and perhaps 3.366 - less reliability. Commercial revision control systems attempt 3.367 - to ameliorate these problems with remote-site replication 3.368 - add-ons that are typically expensive to buy and cantankerous 3.369 - to administer. A distributed system doesn't suffer from these 3.370 - problems in the first place. Better yet, you can easily set 3.371 - up multiple authoritative servers, say one per site, so that 3.372 - there's no redundant communication between repositories over 3.373 - expensive long-haul network links.</para> 3.374 - 3.375 - <para>Centralised revision control systems tend to have 3.376 - relatively low scalability. It's not unusual for an expensive 3.377 - centralised system to fall over under the combined load of 3.378 - just a few dozen concurrent users. Once again, the typical 3.379 - response tends to be an expensive and clunky replication 3.380 - facility. Since the load on a central server---if you have 3.381 - one at all---is many times lower with a distributed tool 3.382 - (because all of the data is replicated everywhere), a single 3.383 - cheap server can handle the needs of a much larger team, and 3.384 - replication to balance load becomes a simple matter of 3.385 - scripting.</para> 3.386 - 3.387 - <para>If you have an employee in the field, troubleshooting a 3.388 - problem at a customer's site, they'll benefit from distributed 3.389 - revision control. The tool will let them generate custom 3.390 - builds, try different fixes in isolation from each other, and 3.391 - search efficiently through history for the sources of bugs and 3.392 - regressions in the customer's environment, all without needing 3.393 - to connect to your company's network.</para> 3.394 - 3.395 - </sect2> 3.396 - </sect1> 3.397 - <sect1> 3.398 - <title>Why choose Mercurial?</title> 3.399 - 3.400 - <para>Mercurial has a unique set of properties that make it a 3.401 - particularly good choice as a revision control system.</para> 3.402 - <itemizedlist> 3.403 - <listitem><para>It is easy to learn and use.</para></listitem> 3.404 - <listitem><para>It is lightweight.</para></listitem> 3.405 - <listitem><para>It scales excellently.</para></listitem> 3.406 - <listitem><para>It is easy to 3.407 - customise.</para></listitem></itemizedlist> 3.408 - 3.409 - <para>If you are at all familiar with revision control systems, 3.410 - you should be able to get up and running with Mercurial in less 3.411 - than five minutes. Even if not, it will take no more than a few 3.412 - minutes longer. Mercurial's command and feature sets are 3.413 - generally uniform and consistent, so you can keep track of a few 3.414 - general rules instead of a host of exceptions.</para> 3.415 - 3.416 - <para>On a small project, you can start working with Mercurial in 3.417 - moments. Creating new changes and branches; transferring changes 3.418 - around (whether locally or over a network); and history and 3.419 - status operations are all fast. Mercurial attempts to stay 3.420 - nimble and largely out of your way by combining low cognitive 3.421 - overhead with blazingly fast operations.</para> 3.422 - 3.423 - <para>The usefulness of Mercurial is not limited to small 3.424 - projects: it is used by projects with hundreds to thousands of 3.425 - contributors, each containing tens of thousands of files and 3.426 - hundreds of megabytes of source code.</para> 3.427 - 3.428 - <para>If the core functionality of Mercurial is not enough for 3.429 - you, it's easy to build on. Mercurial is well suited to 3.430 - scripting tasks, and its clean internals and implementation in 3.431 - Python make it easy to add features in the form of extensions. 3.432 - There are a number of popular and useful extensions already 3.433 - available, ranging from helping to identify bugs to improving 3.434 - performance.</para> 3.435 - 3.436 - </sect1> 3.437 - <sect1> 3.438 - <title>Mercurial compared with other tools</title> 3.439 - 3.440 - <para>Before you read on, please understand that this section 3.441 - necessarily reflects my own experiences, interests, and (dare I 3.442 - say it) biases. I have used every one of the revision control 3.443 - tools listed below, in most cases for several years at a 3.444 - time.</para> 3.445 - 3.446 - 3.447 - <sect2> 3.448 - <title>Subversion</title> 3.449 - 3.450 - <para>Subversion is a popular revision control tool, developed 3.451 - to replace CVS. It has a centralised client/server 3.452 - architecture.</para> 3.453 - 3.454 - <para>Subversion and Mercurial have similarly named commands for 3.455 - performing the same operations, so if you're familiar with 3.456 - one, it is easy to learn to use the other. Both tools are 3.457 - portable to all popular operating systems.</para> 3.458 - 3.459 - <para>Prior to version 1.5, Subversion had no useful support for 3.460 - merges. At the time of writing, its merge tracking capability 3.461 - is new, and known to be <ulink 3.462 - url="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html#svn.branchmerge.advanced.finalword">complicated 3.463 - and buggy</ulink>.</para> 3.464 - 3.465 - <para>Mercurial has a substantial performance advantage over 3.466 - Subversion on every revision control operation I have 3.467 - benchmarked. I have measured its advantage as ranging from a 3.468 - factor of two to a factor of six when compared with Subversion 3.469 - 1.4.3's <emphasis>ra_local</emphasis> file store, which is the 3.470 - fastest access method available. In more realistic 3.471 - deployments involving a network-based store, Subversion will 3.472 - be at a substantially larger disadvantage. Because many 3.473 - Subversion commands must talk to the server and Subversion 3.474 - does not have useful replication facilities, server capacity 3.475 - and network bandwidth become bottlenecks for modestly large 3.476 - projects.</para> 3.477 - 3.478 - <para>Additionally, Subversion incurs substantial storage 3.479 - overhead to avoid network transactions for a few common 3.480 - operations, such as finding modified files 3.481 - (<literal>status</literal>) and displaying modifications 3.482 - against the current revision (<literal>diff</literal>). As a 3.483 - result, a Subversion working copy is often the same size as, 3.484 - or larger than, a Mercurial repository and working directory, 3.485 - even though the Mercurial repository contains a complete 3.486 - history of the project.</para> 3.487 - 3.488 - <para>Subversion is widely supported by third party tools. 3.489 - Mercurial currently lags considerably in this area. This gap 3.490 - is closing, however, and indeed some of Mercurial's GUI tools 3.491 - now outshine their Subversion equivalents. Like Mercurial, 3.492 - Subversion has an excellent user manual.</para> 3.493 - 3.494 - <para>Because Subversion doesn't store revision history on the 3.495 - client, it is well suited to managing projects that deal with 3.496 - lots of large, opaque binary files. If you check in fifty 3.497 - revisions to an incompressible 10MB file, Subversion's 3.498 - client-side space usage stays constant The space used by any 3.499 - distributed SCM will grow rapidly in proportion to the number 3.500 - of revisions, because the differences between each revision 3.501 - are large.</para> 3.502 - 3.503 - <para>In addition, it's often difficult or, more usually, 3.504 - impossible to merge different versions of a binary file. 3.505 - Subversion's ability to let a user lock a file, so that they 3.506 - temporarily have the exclusive right to commit changes to it, 3.507 - can be a significant advantage to a project where binary files 3.508 - are widely used.</para> 3.509 - 3.510 - <para>Mercurial can import revision history from a Subversion 3.511 - repository. It can also export revision history to a 3.512 - Subversion repository. This makes it easy to <quote>test the 3.513 - waters</quote> and use Mercurial and Subversion in parallel 3.514 - before deciding to switch. History conversion is incremental, 3.515 - so you can perform an initial conversion, then small 3.516 - additional conversions afterwards to bring in new 3.517 - changes.</para> 3.518 - 3.519 - 3.520 - </sect2> 3.521 - <sect2> 3.522 - <title>Git</title> 3.523 - 3.524 - <para>Git is a distributed revision control tool that was 3.525 - developed for managing the Linux kernel source tree. Like 3.526 - Mercurial, its early design was somewhat influenced by 3.527 - Monotone.</para> 3.528 - 3.529 - <para>Git has a very large command set, with version 1.5.0 3.530 - providing 139 individual commands. It has something of a 3.531 - reputation for being difficult to learn. Compared to Git, 3.532 - Mercurial has a strong focus on simplicity.</para> 3.533 - 3.534 - <para>In terms of performance, Git is extremely fast. In 3.535 - several cases, it is faster than Mercurial, at least on Linux, 3.536 - while Mercurial performs better on other operations. However, 3.537 - on Windows, the performance and general level of support that 3.538 - Git provides is, at the time of writing, far behind that of 3.539 - Mercurial.</para> 3.540 - 3.541 - <para>While a Mercurial repository needs no maintenance, a Git 3.542 - repository requires frequent manual <quote>repacks</quote> of 3.543 - its metadata. Without these, performance degrades, while 3.544 - space usage grows rapidly. A server that contains many Git 3.545 - repositories that are not rigorously and frequently repacked 3.546 - will become heavily disk-bound during backups, and there have 3.547 - been instances of daily backups taking far longer than 24 3.548 - hours as a result. A freshly packed Git repository is 3.549 - slightly smaller than a Mercurial repository, but an unpacked 3.550 - repository is several orders of magnitude larger.</para> 3.551 - 3.552 - <para>The core of Git is written in C. Many Git commands are 3.553 - implemented as shell or Perl scripts, and the quality of these 3.554 - scripts varies widely. I have encountered several instances 3.555 - where scripts charged along blindly in the presence of errors 3.556 - that should have been fatal.</para> 3.557 - 3.558 - <para>Mercurial can import revision history from a Git 3.559 - repository.</para> 3.560 - 3.561 - 3.562 - </sect2> 3.563 - <sect2> 3.564 - <title>CVS</title> 3.565 - 3.566 - <para>CVS is probably the most widely used revision control tool 3.567 - in the world. Due to its age and internal untidiness, it has 3.568 - been only lightly maintained for many years.</para> 3.569 - 3.570 - <para>It has a centralised client/server architecture. It does 3.571 - not group related file changes into atomic commits, making it 3.572 - easy for people to <quote>break the build</quote>: one person 3.573 - can successfully commit part of a change and then be blocked 3.574 - by the need for a merge, causing other people to see only a 3.575 - portion of the work they intended to do. This also affects 3.576 - how you work with project history. If you want to see all of 3.577 - the modifications someone made as part of a task, you will 3.578 - need to manually inspect the descriptions and timestamps of 3.579 - the changes made to each file involved (if you even know what 3.580 - those files were).</para> 3.581 - 3.582 - <para>CVS has a muddled notion of tags and branches that I will 3.583 - not attempt to even describe. It does not support renaming of 3.584 - files or directories well, making it easy to corrupt a 3.585 - repository. It has almost no internal consistency checking 3.586 - capabilities, so it is usually not even possible to tell 3.587 - whether or how a repository is corrupt. I would not recommend 3.588 - CVS for any project, existing or new.</para> 3.589 - 3.590 - <para>Mercurial can import CVS revision history. However, there 3.591 - are a few caveats that apply; these are true of every other 3.592 - revision control tool's CVS importer, too. Due to CVS's lack 3.593 - of atomic changes and unversioned filesystem hierarchy, it is 3.594 - not possible to reconstruct CVS history completely accurately; 3.595 - some guesswork is involved, and renames will usually not show 3.596 - up. Because a lot of advanced CVS administration has to be 3.597 - done by hand and is hence error-prone, it's common for CVS 3.598 - importers to run into multiple problems with corrupted 3.599 - repositories (completely bogus revision timestamps and files 3.600 - that have remained locked for over a decade are just two of 3.601 - the less interesting problems I can recall from personal 3.602 - experience).</para> 3.603 - 3.604 - <para>Mercurial can import revision history from a CVS 3.605 - repository.</para> 3.606 - 3.607 - 3.608 - </sect2> 3.609 - <sect2> 3.610 - <title>Commercial tools</title> 3.611 - 3.612 - <para>Perforce has a centralised client/server architecture, 3.613 - with no client-side caching of any data. Unlike modern 3.614 - revision control tools, Perforce requires that a user run a 3.615 - command to inform the server about every file they intend to 3.616 - edit.</para> 3.617 - 3.618 - <para>The performance of Perforce is quite good for small teams, 3.619 - but it falls off rapidly as the number of users grows beyond a 3.620 - few dozen. Modestly large Perforce installations require the 3.621 - deployment of proxies to cope with the load their users 3.622 - generate.</para> 3.623 - 3.624 - 3.625 - </sect2> 3.626 - <sect2> 3.627 - <title>Choosing a revision control tool</title> 3.628 - 3.629 - <para>With the exception of CVS, all of the tools listed above 3.630 - have unique strengths that suit them to particular styles of 3.631 - work. There is no single revision control tool that is best 3.632 - in all situations.</para> 3.633 - 3.634 - <para>As an example, Subversion is a good choice for working 3.635 - with frequently edited binary files, due to its centralised 3.636 - nature and support for file locking.</para> 3.637 - 3.638 - <para>I personally find Mercurial's properties of simplicity, 3.639 - performance, and good merge support to be a compelling 3.640 - combination that has served me well for several years.</para> 3.641 - 3.642 - 3.643 - </sect2> 3.644 - </sect1> 3.645 - <sect1> 3.646 - <title>Switching from another tool to Mercurial</title> 3.647 - 3.648 - <para>Mercurial is bundled with an extension named <literal 3.649 - role="hg-ext">convert</literal>, which can incrementally 3.650 - import revision history from several other revision control 3.651 - tools. By <quote>incremental</quote>, I mean that you can 3.652 - convert all of a project's history to date in one go, then rerun 3.653 - the conversion later to obtain new changes that happened after 3.654 - the initial conversion.</para> 3.655 - 3.656 - <para>The revision control tools supported by <literal 3.657 - role="hg-ext">convert</literal> are as follows:</para> 3.658 - <itemizedlist> 3.659 - <listitem><para>Subversion</para></listitem> 3.660 - <listitem><para>CVS</para></listitem> 3.661 - <listitem><para>Git</para></listitem> 3.662 - <listitem><para>Darcs</para></listitem></itemizedlist> 3.663 - 3.664 - <para>In addition, <literal role="hg-ext">convert</literal> can 3.665 - export changes from Mercurial to Subversion. This makes it 3.666 - possible to try Subversion and Mercurial in parallel before 3.667 - committing to a switchover, without risking the loss of any 3.668 - work.</para> 3.669 - 3.670 - <para>The <command role="hg-ext-conver">convert</command> command 3.671 - is easy to use. Simply point it at the path or URL of the 3.672 - source repository, optionally give it the name of the 3.673 - destination repository, and it will start working. After the 3.674 - initial conversion, just run the same command again to import 3.675 - new changes.</para> 3.676 - </sect1> 3.677 -</chapter> 3.678 - 3.679 -<!-- 3.680 -local variables: 3.681 -sgml-parent-document: ("00book.xml" "book" "chapter") 3.682 -end: 3.683 --->
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/en/ch01-tour-basic.xml Thu Mar 19 20:54:12 2009 -0700 4.3 @@ -0,0 +1,860 @@ 4.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 4.5 + 4.6 +<chapter id="chap:tour-basic"> 4.7 + <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?> 4.8 + <title>A tour of Mercurial: the basics</title> 4.9 + 4.10 + <sect1 id="sec:tour:install"> 4.11 + <title>Installing Mercurial on your system</title> 4.12 + 4.13 + <para>Prebuilt binary packages of Mercurial are available for 4.14 + every popular operating system. These make it easy to start 4.15 + using Mercurial on your computer immediately.</para> 4.16 + 4.17 + <sect2> 4.18 + <title>Linux</title> 4.19 + 4.20 + <para>Because each Linux distribution has its own packaging 4.21 + tools, policies, and rate of development, it's difficult to 4.22 + give a comprehensive set of instructions on how to install 4.23 + Mercurial binaries. The version of Mercurial that you will 4.24 + end up with can vary depending on how active the person is who 4.25 + maintains the package for your distribution.</para> 4.26 + 4.27 + <para>To keep things simple, I will focus on installing 4.28 + Mercurial from the command line under the most popular Linux 4.29 + distributions. Most of these distributions provide graphical 4.30 + package managers that will let you install Mercurial with a 4.31 + single click; the package name to look for is 4.32 + <literal>mercurial</literal>.</para> 4.33 + 4.34 + <itemizedlist> 4.35 + <listitem><para>Debian:</para> 4.36 + <programlisting>apt-get install mercurial</programlisting></listitem> 4.37 + <listitem><para>Fedora Core:</para> 4.38 + <programlisting>yum install mercurial</programlisting></listitem> 4.39 + <listitem><para>Gentoo:</para> 4.40 + <programlisting>emerge mercurial</programlisting></listitem> 4.41 + <listitem><para>OpenSUSE:</para> 4.42 + <programlisting>yum install mercurial</programlisting></listitem> 4.43 + <listitem><para>Ubuntu: Ubuntu's Mercurial package is based on 4.44 + Debian's. To install it, run the following 4.45 + command.</para> 4.46 + <programlisting>apt-get install mercurial</programlisting></listitem> 4.47 + </itemizedlist> 4.48 + 4.49 + </sect2> 4.50 + <sect2> 4.51 + <title>Solaris</title> 4.52 + 4.53 + <para>SunFreeWare, at <ulink 4.54 + url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 4.55 + is a good source for a large number of pre-built Solaris 4.56 + packages for 32 and 64 bit Intel and Sparc architectures, 4.57 + including current versions of Mercurial.</para> 4.58 + 4.59 + </sect2> 4.60 + <sect2> 4.61 + <title>Mac OS X</title> 4.62 + 4.63 + <para>Lee Cantey publishes an installer of Mercurial for Mac OS 4.64 + X at <ulink 4.65 + url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 4.66 + This package works on both Intel- and Power-based Macs. Before 4.67 + you can use it, you must install a compatible version of 4.68 + Universal MacPython <citation>web:macpython</citation>. This 4.69 + is easy to do; simply follow the instructions on Lee's 4.70 + site.</para> 4.71 + 4.72 + <para>It's also possible to install Mercurial using Fink or 4.73 + MacPorts, two popular free package managers for Mac OS X. If 4.74 + you have Fink, use <command>sudo apt-get install 4.75 + mercurial-py25</command>. If MacPorts, <command>sudo port 4.76 + install mercurial</command>.</para> 4.77 + 4.78 + </sect2> 4.79 + <sect2> 4.80 + <title>Windows</title> 4.81 + 4.82 + <para>Lee Cantey publishes an installer of Mercurial for Windows 4.83 + at <ulink 4.84 + url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 4.85 + This package has no external dependencies; it <quote>just 4.86 + works</quote>.</para> 4.87 + 4.88 + <note> 4.89 + <para> The Windows version of Mercurial does not 4.90 + automatically convert line endings between Windows and Unix 4.91 + styles. If you want to share work with Unix users, you must 4.92 + do a little additional configuration work. XXX Flesh this 4.93 + out.</para> 4.94 + </note> 4.95 + 4.96 + </sect2> 4.97 + </sect1> 4.98 + <sect1> 4.99 + <title>Getting started</title> 4.100 + 4.101 + <para>To begin, we'll use the <command role="hg-cmd">hg 4.102 + version</command> command to find out whether Mercurial is 4.103 + actually installed properly. The actual version information 4.104 + that it prints isn't so important; it's whether it prints 4.105 + anything at all that we care about.</para> 4.106 + 4.107 + &interaction.tour.version; 4.108 + 4.109 + <sect2> 4.110 + <title>Built-in help</title> 4.111 + 4.112 + <para>Mercurial provides a built-in help system. This is 4.113 + invaluable for those times when you find yourself stuck 4.114 + trying to remember how to run a command. If you are 4.115 + completely stuck, simply run <command role="hg-cmd">hg 4.116 + help</command>; it will print a brief list of commands, 4.117 + along with a description of what each does. If you ask for 4.118 + help on a specific command (as below), it prints more 4.119 + detailed information.</para> 4.120 + 4.121 + &interaction.tour.help; 4.122 + 4.123 + <para>For a more impressive level of detail (which you won't 4.124 + usually need) run <command role="hg-cmd">hg help <option 4.125 + role="hg-opt-global">-v</option></command>. The <option 4.126 + role="hg-opt-global">-v</option> option is short for 4.127 + <option role="hg-opt-global">--verbose</option>, and tells 4.128 + Mercurial to print more information than it usually 4.129 + would.</para> 4.130 + 4.131 + </sect2> 4.132 + </sect1> 4.133 + <sect1> 4.134 + <title>Working with a repository</title> 4.135 + 4.136 + <para>In Mercurial, everything happens inside a 4.137 + <emphasis>repository</emphasis>. The repository for a project 4.138 + contains all of the files that <quote>belong to</quote> that 4.139 + project, along with a historical record of the project's 4.140 + files.</para> 4.141 + 4.142 + <para>There's nothing particularly magical about a repository; it 4.143 + is simply a directory tree in your filesystem that Mercurial 4.144 + treats as special. You can rename or delete a repository any 4.145 + time you like, using either the command line or your file 4.146 + browser.</para> 4.147 + 4.148 + <sect2> 4.149 + <title>Making a local copy of a repository</title> 4.150 + 4.151 + <para><emphasis>Copying</emphasis> a repository is just a little 4.152 + bit special. While you could use a normal file copying 4.153 + command to make a copy of a repository, it's best to use a 4.154 + built-in command that Mercurial provides. This command is 4.155 + called <command role="hg-cmd">hg clone</command>, because it 4.156 + creates an identical copy of an existing repository.</para> 4.157 + 4.158 + &interaction.tour.clone; 4.159 + 4.160 + <para>If our clone succeeded, we should now have a local 4.161 + directory called <filename class="directory">hello</filename>. 4.162 + This directory will contain some files.</para> 4.163 + 4.164 + &interaction.tour.ls; 4.165 + 4.166 + <para>These files have the same contents and history in our 4.167 + repository as they do in the repository we cloned.</para> 4.168 + 4.169 + <para>Every Mercurial repository is complete, self-contained, 4.170 + and independent. It contains its own private copy of a 4.171 + project's files and history. A cloned repository remembers 4.172 + the location of the repository it was cloned from, but it does 4.173 + not communicate with that repository, or any other, unless you 4.174 + tell it to.</para> 4.175 + 4.176 + <para>What this means for now is that we're free to experiment 4.177 + with our repository, safe in the knowledge that it's a private 4.178 + <quote>sandbox</quote> that won't affect anyone else.</para> 4.179 + 4.180 + </sect2> 4.181 + <sect2> 4.182 + <title>What's in a repository?</title> 4.183 + 4.184 + <para>When we take a more detailed look inside a repository, we 4.185 + can see that it contains a directory named <filename 4.186 + class="directory">.hg</filename>. This is where Mercurial 4.187 + keeps all of its metadata for the repository.</para> 4.188 + 4.189 + &interaction.tour.ls-a; 4.190 + 4.191 + <para>The contents of the <filename 4.192 + class="directory">.hg</filename> directory and its 4.193 + subdirectories are private to Mercurial. Every other file and 4.194 + directory in the repository is yours to do with as you 4.195 + please.</para> 4.196 + 4.197 + <para>To introduce a little terminology, the <filename 4.198 + class="directory">.hg</filename> directory is the 4.199 + <quote>real</quote> repository, and all of the files and 4.200 + directories that coexist with it are said to live in the 4.201 + <emphasis>working directory</emphasis>. An easy way to 4.202 + remember the distinction is that the 4.203 + <emphasis>repository</emphasis> contains the 4.204 + <emphasis>history</emphasis> of your project, while the 4.205 + <emphasis>working directory</emphasis> contains a 4.206 + <emphasis>snapshot</emphasis> of your project at a particular 4.207 + point in history.</para> 4.208 + 4.209 + </sect2> 4.210 + </sect1> 4.211 + <sect1> 4.212 + <title>A tour through history</title> 4.213 + 4.214 + <para>One of the first things we might want to do with a new, 4.215 + unfamiliar repository is understand its history. The <command 4.216 + role="hg-cmd">hg log</command> command gives us a view of 4.217 + history.</para> 4.218 + 4.219 + &interaction.tour.log; 4.220 + 4.221 + <para>By default, this command prints a brief paragraph of output 4.222 + for each change to the project that was recorded. In Mercurial 4.223 + terminology, we call each of these recorded events a 4.224 + <emphasis>changeset</emphasis>, because it can contain a record 4.225 + of changes to several files.</para> 4.226 + 4.227 + <para>The fields in a record of output from <command 4.228 + role="hg-cmd">hg log</command> are as follows.</para> 4.229 + <itemizedlist> 4.230 + <listitem><para><literal>changeset</literal>: This field has the 4.231 + format of a number, followed by a colon, followed by a 4.232 + hexadecimal string. These are 4.233 + <emphasis>identifiers</emphasis> for the changeset. There 4.234 + are two identifiers because the number is shorter and easier 4.235 + to type than the hex string.</para></listitem> 4.236 + <listitem><para><literal>user</literal>: The identity of the 4.237 + person who created the changeset. This is a free-form 4.238 + field, but it most often contains a person's name and email 4.239 + address.</para></listitem> 4.240 + <listitem><para><literal>date</literal>: The date and time on 4.241 + which the changeset was created, and the timezone in which 4.242 + it was created. (The date and time are local to that 4.243 + timezone; they display what time and date it was for the 4.244 + person who created the changeset.)</para></listitem> 4.245 + <listitem><para><literal>summary</literal>: The first line of 4.246 + the text message that the creator of the changeset entered 4.247 + to describe the changeset.</para></listitem></itemizedlist> 4.248 + <para>The default output printed by <command role="hg-cmd">hg 4.249 + log</command> is purely a summary; it is missing a lot of 4.250 + detail.</para> 4.251 + 4.252 + <para>Figure <xref linkend="fig:tour-basic:history"/> provides a 4.253 + graphical representation of the history of the <filename 4.254 + class="directory">hello</filename> repository, to make it a 4.255 + little easier to see which direction history is 4.256 + <quote>flowing</quote> in. We'll be returning to this figure 4.257 + several times in this chapter and the chapter that 4.258 + follows.</para> 4.259 + 4.260 + <informalfigure id="fig:tour-basic:history"> 4.261 + <mediaobject> 4.262 + <imageobject><imagedata fileref="tour-history"/></imageobject> 4.263 + <textobject><phrase>XXX add text</phrase></textobject> 4.264 + <caption><para>Graphical history of the <filename 4.265 + class="directory">hello</filename> 4.266 + repository</para></caption> 4.267 + </mediaobject> 4.268 + </informalfigure> 4.269 + 4.270 + <sect2> 4.271 + <title>Changesets, revisions, and talking to other 4.272 + people</title> 4.273 + 4.274 + <para>As English is a notoriously sloppy language, and computer 4.275 + science has a hallowed history of terminological confusion 4.276 + (why use one term when four will do?), revision control has a 4.277 + variety of words and phrases that mean the same thing. If you 4.278 + are talking about Mercurial history with other people, you 4.279 + will find that the word <quote>changeset</quote> is often 4.280 + compressed to <quote>change</quote> or (when written) 4.281 + <quote>cset</quote>, and sometimes a changeset is referred to 4.282 + as a <quote>revision</quote> or a <quote>rev</quote>.</para> 4.283 + 4.284 + <para>While it doesn't matter what <emphasis>word</emphasis> you 4.285 + use to refer to the concept of <quote>a changeset</quote>, the 4.286 + <emphasis>identifier</emphasis> that you use to refer to 4.287 + <quote>a <emphasis>specific</emphasis> changeset</quote> is of 4.288 + great importance. Recall that the <literal>changeset</literal> 4.289 + field in the output from <command role="hg-cmd">hg 4.290 + log</command> identifies a changeset using both a number and 4.291 + a hexadecimal string.</para> 4.292 + <itemizedlist> 4.293 + <listitem><para>The revision number is <emphasis>only valid in 4.294 + that repository</emphasis>,</para></listitem> 4.295 + <listitem><para>while the hex string is the 4.296 + <emphasis>permanent, unchanging identifier</emphasis> that 4.297 + will always identify that exact changeset in 4.298 + <emphasis>every</emphasis> copy of the 4.299 + repository.</para></listitem></itemizedlist> 4.300 + <para>This distinction is important. If you send someone an 4.301 + email talking about <quote>revision 33</quote>, there's a high 4.302 + likelihood that their revision 33 will <emphasis>not be the 4.303 + same</emphasis> as yours. The reason for this is that a 4.304 + revision number depends on the order in which changes arrived 4.305 + in a repository, and there is no guarantee that the same 4.306 + changes will happen in the same order in different 4.307 + repositories. Three changes $a,b,c$ can easily appear in one 4.308 + repository as $0,1,2$, while in another as $1,0,2$.</para> 4.309 + 4.310 + <para>Mercurial uses revision numbers purely as a convenient 4.311 + shorthand. If you need to discuss a changeset with someone, 4.312 + or make a record of a changeset for some other reason (for 4.313 + example, in a bug report), use the hexadecimal 4.314 + identifier.</para> 4.315 + 4.316 + </sect2> 4.317 + <sect2> 4.318 + <title>Viewing specific revisions</title> 4.319 + 4.320 + <para>To narrow the output of <command role="hg-cmd">hg 4.321 + log</command> down to a single revision, use the <option 4.322 + role="hg-opt-log">-r</option> (or <option 4.323 + role="hg-opt-log">--rev</option>) option. You can use 4.324 + either a revision number or a long-form changeset identifier, 4.325 + and you can provide as many revisions as you want.</para> 4.326 + 4.327 + &interaction.tour.log-r; 4.328 + 4.329 + <para>If you want to see the history of several revisions 4.330 + without having to list each one, you can use <emphasis>range 4.331 + notation</emphasis>; this lets you express the idea <quote>I 4.332 + want all revisions between <literal>abc</literal> and 4.333 + <literal>def</literal>, inclusive</quote>.</para> 4.334 + 4.335 + &interaction.tour.log.range; 4.336 + 4.337 + <para>Mercurial also honours the order in which you specify 4.338 + revisions, so <command role="hg-cmd">hg log -r 2:4</command> 4.339 + prints 2, 3, and 4. while <command role="hg-cmd">hg log -r 4.340 + 4:2</command> prints 4, 3, and 2.</para> 4.341 + 4.342 + </sect2> 4.343 + <sect2> 4.344 + <title>More detailed information</title> 4.345 + 4.346 + <para>While the summary information printed by <command 4.347 + role="hg-cmd">hg log</command> is useful if you already know 4.348 + what you're looking for, you may need to see a complete 4.349 + description of the change, or a list of the files changed, if 4.350 + you're trying to decide whether a changeset is the one you're 4.351 + looking for. The <command role="hg-cmd">hg log</command> 4.352 + command's <option role="hg-opt-global">-v</option> (or <option 4.353 + role="hg-opt-global">--verbose</option>) option gives you 4.354 + this extra detail.</para> 4.355 + 4.356 + &interaction.tour.log-v; 4.357 + 4.358 + <para>If you want to see both the description and content of a 4.359 + change, add the <option role="hg-opt-log">-p</option> (or 4.360 + <option role="hg-opt-log">--patch</option>) option. This 4.361 + displays the content of a change as a <emphasis>unified 4.362 + diff</emphasis> (if you've never seen a unified diff before, 4.363 + see section <xref linkend="sec:mq:patch"/> for an 4.364 + overview).</para> 4.365 + 4.366 + &interaction.tour.log-vp; 4.367 + 4.368 + </sect2> 4.369 + </sect1> 4.370 + <sect1> 4.371 + <title>All about command options</title> 4.372 + 4.373 + <para>Let's take a brief break from exploring Mercurial commands 4.374 + to discuss a pattern in the way that they work; you may find 4.375 + this useful to keep in mind as we continue our tour.</para> 4.376 + 4.377 + <para>Mercurial has a consistent and straightforward approach to 4.378 + dealing with the options that you can pass to commands. It 4.379 + follows the conventions for options that are common to modern 4.380 + Linux and Unix systems.</para> 4.381 + <itemizedlist> 4.382 + <listitem><para>Every option has a long name. For example, as 4.383 + we've already seen, the <command role="hg-cmd">hg 4.384 + log</command> command accepts a <option 4.385 + role="hg-opt-log">--rev</option> option.</para></listitem> 4.386 + <listitem><para>Most options have short names, too. Instead of 4.387 + <option role="hg-opt-log">--rev</option>, we can use <option 4.388 + role="hg-opt-log">-r</option>. (The reason that some 4.389 + options don't have short names is that the options in 4.390 + question are rarely used.)</para></listitem> 4.391 + <listitem><para>Long options start with two dashes (e.g. <option 4.392 + role="hg-opt-log">--rev</option>), while short options 4.393 + start with one (e.g. <option 4.394 + role="hg-opt-log">-r</option>).</para></listitem> 4.395 + <listitem><para>Option naming and usage is consistent across 4.396 + commands. For example, every command that lets you specify 4.397 + a changeset ID or revision number accepts both <option 4.398 + role="hg-opt-log">-r</option> and <option 4.399 + role="hg-opt-log">--rev</option> 4.400 + arguments.</para></listitem></itemizedlist> 4.401 + <para>In the examples throughout this book, I use short options 4.402 + instead of long. This just reflects my own preference, so don't 4.403 + read anything significant into it.</para> 4.404 + 4.405 + <para>Most commands that print output of some kind will print more 4.406 + output when passed a <option role="hg-opt-global">-v</option> 4.407 + (or <option role="hg-opt-global">--verbose</option>) option, and 4.408 + less when passed <option role="hg-opt-global">-q</option> (or 4.409 + <option role="hg-opt-global">--quiet</option>).</para> 4.410 + 4.411 + </sect1> 4.412 + <sect1> 4.413 + <title>Making and reviewing changes</title> 4.414 + 4.415 + <para>Now that we have a grasp of viewing history in Mercurial, 4.416 + let's take a look at making some changes and examining 4.417 + them.</para> 4.418 + 4.419 + <para>The first thing we'll do is isolate our experiment in a 4.420 + repository of its own. We use the <command role="hg-cmd">hg 4.421 + clone</command> command, but we don't need to clone a copy of 4.422 + the remote repository. Since we already have a copy of it 4.423 + locally, we can just clone that instead. This is much faster 4.424 + than cloning over the network, and cloning a local repository 4.425 + uses less disk space in most cases, too.</para> 4.426 + 4.427 + &interaction.tour.reclone; 4.428 + 4.429 + <para>As an aside, it's often good practice to keep a 4.430 + <quote>pristine</quote> copy of a remote repository around, 4.431 + which you can then make temporary clones of to create sandboxes 4.432 + for each task you want to work on. This lets you work on 4.433 + multiple tasks in parallel, each isolated from the others until 4.434 + it's complete and you're ready to integrate it back. Because 4.435 + local clones are so cheap, there's almost no overhead to cloning 4.436 + and destroying repositories whenever you want.</para> 4.437 + 4.438 + <para>In our <filename class="directory">my-hello</filename> 4.439 + repository, we have a file <filename>hello.c</filename> that 4.440 + contains the classic <quote>hello, world</quote> program. Let's 4.441 + use the ancient and venerable <command>sed</command> command to 4.442 + edit this file so that it prints a second line of output. (I'm 4.443 + only using <command>sed</command> to do this because it's easy 4.444 + to write a scripted example this way. Since you're not under 4.445 + the same constraint, you probably won't want to use 4.446 + <command>sed</command>; simply use your preferred text editor to 4.447 + do the same thing.)</para> 4.448 + 4.449 + &interaction.tour.sed; 4.450 + 4.451 + <para>Mercurial's <command role="hg-cmd">hg status</command> 4.452 + command will tell us what Mercurial knows about the files in the 4.453 + repository.</para> 4.454 + 4.455 + &interaction.tour.status; 4.456 + 4.457 + <para>The <command role="hg-cmd">hg status</command> command 4.458 + prints no output for some files, but a line starting with 4.459 + <quote><literal>M</literal></quote> for 4.460 + <filename>hello.c</filename>. Unless you tell it to, <command 4.461 + role="hg-cmd">hg status</command> will not print any output 4.462 + for files that have not been modified.</para> 4.463 + 4.464 + <para>The <quote><literal>M</literal></quote> indicates that 4.465 + Mercurial has noticed that we modified 4.466 + <filename>hello.c</filename>. We didn't need to 4.467 + <emphasis>inform</emphasis> Mercurial that we were going to 4.468 + modify the file before we started, or that we had modified the 4.469 + file after we were done; it was able to figure this out 4.470 + itself.</para> 4.471 + 4.472 + <para>It's a little bit helpful to know that we've modified 4.473 + <filename>hello.c</filename>, but we might prefer to know 4.474 + exactly <emphasis>what</emphasis> changes we've made to it. To 4.475 + do this, we use the <command role="hg-cmd">hg diff</command> 4.476 + command.</para> 4.477 + 4.478 + &interaction.tour.diff; 4.479 + 4.480 + </sect1> 4.481 + <sect1> 4.482 + <title>Recording changes in a new changeset</title> 4.483 + 4.484 + <para>We can modify files, build and test our changes, and use 4.485 + <command role="hg-cmd">hg status</command> and <command 4.486 + role="hg-cmd">hg diff</command> to review our changes, until 4.487 + we're satisfied with what we've done and arrive at a natural 4.488 + stopping point where we want to record our work in a new 4.489 + changeset.</para> 4.490 + 4.491 + <para>The <command role="hg-cmd">hg commit</command> command lets 4.492 + us create a new changeset; we'll usually refer to this as 4.493 + <quote>making a commit</quote> or 4.494 + <quote>committing</quote>.</para> 4.495 + 4.496 + <sect2> 4.497 + <title>Setting up a username</title> 4.498 + 4.499 + <para>When you try to run <command role="hg-cmd">hg 4.500 + commit</command> for the first time, it is not guaranteed to 4.501 + succeed. Mercurial records your name and address with each 4.502 + change that you commit, so that you and others will later be 4.503 + able to tell who made each change. Mercurial tries to 4.504 + automatically figure out a sensible username to commit the 4.505 + change with. It will attempt each of the following methods, 4.506 + in order:</para> 4.507 + <orderedlist> 4.508 + <listitem><para>If you specify a <option 4.509 + role="hg-opt-commit">-u</option> option to the <command 4.510 + role="hg-cmd">hg commit</command> command on the command 4.511 + line, followed by a username, this is always given the 4.512 + highest precedence.</para></listitem> 4.513 + <listitem><para>If you have set the <envar>HGUSER</envar> 4.514 + environment variable, this is checked 4.515 + next.</para></listitem> 4.516 + <listitem><para>If you create a file in your home directory 4.517 + called <filename role="special">.hgrc</filename>, with a 4.518 + <envar role="rc-item-ui">username</envar> entry, that will 4.519 + be used next. To see what the contents of this file 4.520 + should look like, refer to section <xref 4.521 + linkend="sec:tour-basic:username"/> 4.522 + below.</para></listitem> 4.523 + <listitem><para>If you have set the <envar>EMAIL</envar> 4.524 + environment variable, this will be used 4.525 + next.</para></listitem> 4.526 + <listitem><para>Mercurial will query your system to find out 4.527 + your local user name and host name, and construct a 4.528 + username from these components. Since this often results 4.529 + in a username that is not very useful, it will print a 4.530 + warning if it has to do 4.531 + this.</para></listitem> 4.532 + </orderedlist> 4.533 + <para>If all of these mechanisms fail, Mercurial will 4.534 + fail, printing an error message. In this case, it will not 4.535 + let you commit until you set up a 4.536 + username.</para> 4.537 + <para>You should think of the <envar>HGUSER</envar> environment 4.538 + variable and the <option role="hg-opt-commit">-u</option> 4.539 + option to the <command role="hg-cmd">hg commit</command> 4.540 + command as ways to <emphasis>override</emphasis> Mercurial's 4.541 + default selection of username. For normal use, the simplest 4.542 + and most robust way to set a username for yourself is by 4.543 + creating a <filename role="special">.hgrc</filename> file; see 4.544 + below for details.</para> 4.545 + <sect3 id="sec:tour-basic:username"> 4.546 + <title>Creating a Mercurial configuration file</title> 4.547 + 4.548 + <para>To set a user name, use your favourite editor 4.549 + to create a file called <filename 4.550 + role="special">.hgrc</filename> in your home directory. 4.551 + Mercurial will use this file to look up your personalised 4.552 + configuration settings. The initial contents of your 4.553 + <filename role="special">.hgrc</filename> should look like 4.554 + this.</para> 4.555 + <programlisting># This is a Mercurial configuration file. 4.556 +[ui] 4.557 +username = Firstname Lastname 4.558 +<email.address@domain.net></programlisting> 4.559 + 4.560 + <para>The <quote><literal>[ui]</literal></quote> line begins a 4.561 + <emphasis>section</emphasis> of the config file, so you can 4.562 + read the <quote><literal>username = ...</literal></quote> 4.563 + line as meaning <quote>set the value of the 4.564 + <literal>username</literal> item in the 4.565 + <literal>ui</literal> section</quote>. A section continues 4.566 + until a new section begins, or the end of the file. 4.567 + Mercurial ignores empty lines and treats any text from 4.568 + <quote><literal>#</literal></quote> to the end of a line as 4.569 + a comment.</para> 4.570 + </sect3> 4.571 + 4.572 + <sect3> 4.573 + <title>Choosing a user name</title> 4.574 + 4.575 + <para>You can use any text you like as the value of 4.576 + the <literal>username</literal> config item, since this 4.577 + information is for reading by other people, but for 4.578 + interpreting by Mercurial. The convention that most 4.579 + people follow is to use their name and email address, as 4.580 + in the example above.</para> 4.581 + <note> 4.582 + <para>Mercurial's built-in web server obfuscates 4.583 + email addresses, to make it more difficult for the email 4.584 + harvesting tools that spammers use. This reduces the 4.585 + likelihood that you'll start receiving more junk email 4.586 + if you publish a Mercurial repository on the 4.587 + web.</para></note> 4.588 + 4.589 + </sect3> 4.590 + </sect2> 4.591 + <sect2> 4.592 + <title>Writing a commit message</title> 4.593 + 4.594 + <para>When we commit a change, Mercurial drops us into 4.595 + a text editor, to enter a message that will describe the 4.596 + modifications we've made in this changeset. This is called 4.597 + the <emphasis>commit message</emphasis>. It will be a 4.598 + record for readers of what we did and why, and it will be 4.599 + printed by <command role="hg-cmd">hg log</command> after 4.600 + we've finished committing.</para> 4.601 + 4.602 + &interaction.tour.commit; 4.603 + 4.604 + <para>The editor that the <command role="hg-cmd">hg 4.605 + commit</command> command drops us into will contain an 4.606 + empty line, followed by a number of lines starting with 4.607 + <quote><literal>HG:</literal></quote>.</para> 4.608 + 4.609 + <programlisting>XXX fix this XXX</programlisting> 4.610 + 4.611 + <para>Mercurial ignores the lines that start with 4.612 + <quote><literal>HG:</literal></quote>; it uses them only to 4.613 + tell us which files it's recording changes to. Modifying or 4.614 + deleting these lines has no effect.</para> 4.615 + </sect2> 4.616 + <sect2> 4.617 + <title>Writing a good commit message</title> 4.618 + 4.619 + <para>Since <command role="hg-cmd">hg log</command> 4.620 + only prints the first line of a commit message by default, 4.621 + it's best to write a commit message whose first line stands 4.622 + alone. Here's a real example of a commit message that 4.623 + <emphasis>doesn't</emphasis> follow this guideline, and 4.624 + hence has a summary that is not 4.625 + readable.</para> 4.626 + 4.627 + <programlisting> 4.628 +changeset: 73:584af0e231be 4.629 +user: Censored Person <censored.person@example.org> 4.630 +date: Tue Sep 26 21:37:07 2006 -0700 4.631 +summary: include buildmeister/commondefs. Add exports.</programlisting> 4.632 + 4.633 + <para>As far as the remainder of the contents of the 4.634 + commit message are concerned, there are no hard-and-fast 4.635 + rules. Mercurial itself doesn't interpret or care about the 4.636 + contents of the commit message, though your project may have 4.637 + policies that dictate a certain kind of 4.638 + formatting.</para> 4.639 + <para>My personal preference is for short, but 4.640 + informative, commit messages that tell me something that I 4.641 + can't figure out with a quick glance at the output of 4.642 + <command role="hg-cmd">hg log 4.643 + --patch</command>.</para> 4.644 + </sect2> 4.645 + <sect2> 4.646 + <title>Aborting a commit</title> 4.647 + 4.648 + <para>If you decide that you don't want to commit 4.649 + while in the middle of editing a commit message, simply exit 4.650 + from your editor without saving the file that it's editing. 4.651 + This will cause nothing to happen to either the repository 4.652 + or the working directory.</para> 4.653 + <para>If we run the <command role="hg-cmd">hg 4.654 + commit</command> command without any arguments, it records 4.655 + all of the changes we've made, as reported by <command 4.656 + role="hg-cmd">hg status</command> and <command 4.657 + role="hg-cmd">hg diff</command>.</para> 4.658 + </sect2> 4.659 + <sect2> 4.660 + <title>Admiring our new handiwork</title> 4.661 + 4.662 + <para>Once we've finished the commit, we can use the 4.663 + <command role="hg-cmd">hg tip</command> command to display 4.664 + the changeset we just created. This command produces output 4.665 + that is identical to <command role="hg-cmd">hg 4.666 + log</command>, but it only displays the newest revision in 4.667 + the repository.</para> 4.668 + 4.669 + &interaction.tour.tip; 4.670 + 4.671 + <para>We refer to 4.672 + the newest revision in the repository as the tip revision, 4.673 + or simply the tip.</para> 4.674 + </sect2> 4.675 + </sect1> 4.676 + 4.677 + <sect1> 4.678 + <title>Sharing changes</title> 4.679 + 4.680 + <para>We mentioned earlier that repositories in 4.681 + Mercurial are self-contained. This means that the changeset 4.682 + we just created exists only in our <filename 4.683 + class="directory">my-hello</filename> repository. Let's 4.684 + look at a few ways that we can propagate this change into 4.685 + other repositories.</para> 4.686 + 4.687 + <sect2 id="sec:tour:pull"> 4.688 + <title>Pulling changes from another repository</title> 4.689 + <para>To get started, let's clone our original 4.690 + <filename class="directory">hello</filename> repository, 4.691 + which does not contain the change we just committed. We'll 4.692 + call our temporary repository <filename 4.693 + class="directory">hello-pull</filename>.</para> 4.694 + 4.695 + &interaction.tour.clone-pull; 4.696 + 4.697 + <para>We'll use the <command role="hg-cmd">hg 4.698 + pull</command> command to bring changes from <filename 4.699 + class="directory">my-hello</filename> into <filename 4.700 + class="directory">hello-pull</filename>. However, blindly 4.701 + pulling unknown changes into a repository is a somewhat 4.702 + scary prospect. Mercurial provides the <command 4.703 + role="hg-cmd">hg incoming</command> command to tell us 4.704 + what changes the <command role="hg-cmd">hg pull</command> 4.705 + command <emphasis>would</emphasis> pull into the repository, 4.706 + without actually pulling the changes in.</para> 4.707 + 4.708 + &interaction.tour.incoming; 4.709 + 4.710 + <para>(Of course, someone could 4.711 + cause more changesets to appear in the repository that we 4.712 + ran <command role="hg-cmd">hg incoming</command> in, before 4.713 + we get a chance to <command role="hg-cmd">hg pull</command> 4.714 + the changes, so that we could end up pulling changes that we 4.715 + didn't expect.)</para> 4.716 + 4.717 + <para>Bringing changes into a repository is a simple 4.718 + matter of running the <command role="hg-cmd">hg 4.719 + pull</command> command, and telling it which repository to 4.720 + pull from.</para> 4.721 + 4.722 + &interaction.tour.pull; 4.723 + 4.724 + <para>As you can see 4.725 + from the before-and-after output of <command 4.726 + role="hg-cmd">hg tip</command>, we have successfully 4.727 + pulled changes into our repository. There remains one step 4.728 + before we can see these changes in the working 4.729 + directory.</para> 4.730 + </sect2> 4.731 + <sect2> 4.732 + <title>Updating the working directory</title> 4.733 + 4.734 + <para>We have so far glossed over the relationship between a 4.735 + repository and its working directory. The <command 4.736 + role="hg-cmd">hg pull</command> command that we ran in 4.737 + section <xref linkend="sec:tour:pull"/> brought changes 4.738 + into the repository, but if we check, there's no sign of those 4.739 + changes in the working directory. This is because <command 4.740 + role="hg-cmd">hg pull</command> does not (by default) touch 4.741 + the working directory. Instead, we use the <command 4.742 + role="hg-cmd">hg update</command> command to do this.</para> 4.743 + 4.744 + &interaction.tour.update; 4.745 + 4.746 + <para>It might seem a bit strange that <command role="hg-cmd">hg 4.747 + pull</command> doesn't update the working directory 4.748 + automatically. There's actually a good reason for this: you 4.749 + can use <command role="hg-cmd">hg update</command> to update 4.750 + the working directory to the state it was in at <emphasis>any 4.751 + revision</emphasis> in the history of the repository. If 4.752 + you had the working directory updated to an old revision---to 4.753 + hunt down the origin of a bug, say---and ran a <command 4.754 + role="hg-cmd">hg pull</command> which automatically updated 4.755 + the working directory to a new revision, you might not be 4.756 + terribly happy.</para> 4.757 + <para>However, since pull-then-update is such a common thing to 4.758 + do, Mercurial lets you combine the two by passing the <option 4.759 + role="hg-opt-pull">-u</option> option to <command 4.760 + role="hg-cmd">hg pull</command>.</para> 4.761 + 4.762 + <para>If you look back at the output of <command 4.763 + role="hg-cmd">hg pull</command> in section <xref 4.764 + linkend="sec:tour:pull"/> when we ran it without <option 4.765 + role="hg-opt-pull">-u</option>, you can see that it printed 4.766 + a helpful reminder that we'd have to take an explicit step to 4.767 + update the working directory:</para> 4.768 + 4.769 + <!-- &interaction.xxx.fixme; --> 4.770 + 4.771 + <para>To find out what revision the working directory is at, use 4.772 + the <command role="hg-cmd">hg parents</command> 4.773 + command.</para> 4.774 + 4.775 + &interaction.tour.parents; 4.776 + 4.777 + <para>If you look back at figure <xref 4.778 + linkend="fig:tour-basic:history"/>, 4.779 + you'll see arrows connecting each changeset. The node that 4.780 + the arrow leads <emphasis>from</emphasis> in each case is a 4.781 + parent, and the node that the arrow leads 4.782 + <emphasis>to</emphasis> is its child. The working directory 4.783 + has a parent in just the same way; this is the changeset that 4.784 + the working directory currently contains.</para> 4.785 + 4.786 + <para>To update the working directory to a particular revision, 4.787 + 4.788 + give a revision number or changeset ID to the <command 4.789 + role="hg-cmd">hg update</command> command.</para> 4.790 + 4.791 + &interaction.tour.older; 4.792 + 4.793 + <para>If you omit an explicit revision, <command 4.794 + role="hg-cmd">hg update</command> will update to the tip 4.795 + revision, as shown by the second call to <command 4.796 + role="hg-cmd">hg update</command> in the example 4.797 + above.</para> 4.798 + </sect2> 4.799 + 4.800 + <sect2> 4.801 + <title>Pushing changes to another repository</title> 4.802 + 4.803 + <para>Mercurial lets us push changes to another 4.804 + repository, from the repository we're currently visiting. 4.805 + As with the example of <command role="hg-cmd">hg 4.806 + pull</command> above, we'll create a temporary repository 4.807 + to push our changes into.</para> 4.808 + 4.809 + &interaction.tour.clone-push; 4.810 + 4.811 + <para>The <command role="hg-cmd">hg outgoing</command> command 4.812 + tells us what changes would be pushed into another 4.813 + repository.</para> 4.814 + 4.815 + &interaction.tour.outgoing; 4.816 + 4.817 + <para>And the 4.818 + <command role="hg-cmd">hg push</command> command does the 4.819 + actual push.</para> 4.820 + 4.821 + &interaction.tour.push; 4.822 + 4.823 + <para>As with 4.824 + <command role="hg-cmd">hg pull</command>, the <command 4.825 + role="hg-cmd">hg push</command> command does not update 4.826 + the working directory in the repository that it's pushing 4.827 + changes into. (Unlike <command role="hg-cmd">hg 4.828 + pull</command>, <command role="hg-cmd">hg push</command> 4.829 + does not provide a <literal>-u</literal> option that updates 4.830 + the other repository's working directory.)</para> 4.831 + 4.832 + <para>What happens if we try to pull or push changes 4.833 + and the receiving repository already has those changes? 4.834 + Nothing too exciting.</para> 4.835 + 4.836 + &interaction.tour.push.nothing; 4.837 + </sect2> 4.838 + <sect2> 4.839 + <title>Sharing changes over a network</title> 4.840 + 4.841 + <para>The commands we have covered in the previous few 4.842 + sections are not limited to working with local repositories. 4.843 + Each works in exactly the same fashion over a network 4.844 + connection; simply pass in a URL instead of a local 4.845 + path.</para> 4.846 + 4.847 + &interaction.tour.outgoing.net; 4.848 + 4.849 + <para>In this example, we 4.850 + can see what changes we could push to the remote repository, 4.851 + but the repository is understandably not set up to let 4.852 + anonymous users push to it.</para> 4.853 + 4.854 + &interaction.tour.push.net; 4.855 + </sect2> 4.856 + </sect1> 4.857 +</chapter> 4.858 + 4.859 +<!-- 4.860 +local variables: 4.861 +sgml-parent-document: ("00book.xml" "book" "chapter") 4.862 +end: 4.863 +-->
5.1 --- a/en/ch02-tour-basic.xml Wed Mar 18 00:08:22 2009 -0700 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,860 +0,0 @@ 5.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 5.5 - 5.6 -<chapter id="chap:tour-basic"> 5.7 - <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?> 5.8 - <title>A tour of Mercurial: the basics</title> 5.9 - 5.10 - <sect1 id="sec:tour:install"> 5.11 - <title>Installing Mercurial on your system</title> 5.12 - 5.13 - <para>Prebuilt binary packages of Mercurial are available for 5.14 - every popular operating system. These make it easy to start 5.15 - using Mercurial on your computer immediately.</para> 5.16 - 5.17 - <sect2> 5.18 - <title>Linux</title> 5.19 - 5.20 - <para>Because each Linux distribution has its own packaging 5.21 - tools, policies, and rate of development, it's difficult to 5.22 - give a comprehensive set of instructions on how to install 5.23 - Mercurial binaries. The version of Mercurial that you will 5.24 - end up with can vary depending on how active the person is who 5.25 - maintains the package for your distribution.</para> 5.26 - 5.27 - <para>To keep things simple, I will focus on installing 5.28 - Mercurial from the command line under the most popular Linux 5.29 - distributions. Most of these distributions provide graphical 5.30 - package managers that will let you install Mercurial with a 5.31 - single click; the package name to look for is 5.32 - <literal>mercurial</literal>.</para> 5.33 - 5.34 - <itemizedlist> 5.35 - <listitem><para>Debian:</para> 5.36 - <programlisting>apt-get install mercurial</programlisting></listitem> 5.37 - <listitem><para>Fedora Core:</para> 5.38 - <programlisting>yum install mercurial</programlisting></listitem> 5.39 - <listitem><para>Gentoo:</para> 5.40 - <programlisting>emerge mercurial</programlisting></listitem> 5.41 - <listitem><para>OpenSUSE:</para> 5.42 - <programlisting>yum install mercurial</programlisting></listitem> 5.43 - <listitem><para>Ubuntu: Ubuntu's Mercurial package is based on 5.44 - Debian's. To install it, run the following 5.45 - command.</para> 5.46 - <programlisting>apt-get install mercurial</programlisting></listitem> 5.47 - </itemizedlist> 5.48 - 5.49 - </sect2> 5.50 - <sect2> 5.51 - <title>Solaris</title> 5.52 - 5.53 - <para>SunFreeWare, at <ulink 5.54 - url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink>, 5.55 - is a good source for a large number of pre-built Solaris 5.56 - packages for 32 and 64 bit Intel and Sparc architectures, 5.57 - including current versions of Mercurial.</para> 5.58 - 5.59 - </sect2> 5.60 - <sect2> 5.61 - <title>Mac OS X</title> 5.62 - 5.63 - <para>Lee Cantey publishes an installer of Mercurial for Mac OS 5.64 - X at <ulink 5.65 - url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 5.66 - This package works on both Intel- and Power-based Macs. Before 5.67 - you can use it, you must install a compatible version of 5.68 - Universal MacPython <citation>web:macpython</citation>. This 5.69 - is easy to do; simply follow the instructions on Lee's 5.70 - site.</para> 5.71 - 5.72 - <para>It's also possible to install Mercurial using Fink or 5.73 - MacPorts, two popular free package managers for Mac OS X. If 5.74 - you have Fink, use <command>sudo apt-get install 5.75 - mercurial-py25</command>. If MacPorts, <command>sudo port 5.76 - install mercurial</command>.</para> 5.77 - 5.78 - </sect2> 5.79 - <sect2> 5.80 - <title>Windows</title> 5.81 - 5.82 - <para>Lee Cantey publishes an installer of Mercurial for Windows 5.83 - at <ulink 5.84 - url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>. 5.85 - This package has no external dependencies; it <quote>just 5.86 - works</quote>.</para> 5.87 - 5.88 - <note> 5.89 - <para> The Windows version of Mercurial does not 5.90 - automatically convert line endings between Windows and Unix 5.91 - styles. If you want to share work with Unix users, you must 5.92 - do a little additional configuration work. XXX Flesh this 5.93 - out.</para> 5.94 - </note> 5.95 - 5.96 - </sect2> 5.97 - </sect1> 5.98 - <sect1> 5.99 - <title>Getting started</title> 5.100 - 5.101 - <para>To begin, we'll use the <command role="hg-cmd">hg 5.102 - version</command> command to find out whether Mercurial is 5.103 - actually installed properly. The actual version information 5.104 - that it prints isn't so important; it's whether it prints 5.105 - anything at all that we care about.</para> 5.106 - 5.107 - &interaction.tour.version; 5.108 - 5.109 - <sect2> 5.110 - <title>Built-in help</title> 5.111 - 5.112 - <para>Mercurial provides a built-in help system. This is 5.113 - invaluable for those times when you find yourself stuck 5.114 - trying to remember how to run a command. If you are 5.115 - completely stuck, simply run <command role="hg-cmd">hg 5.116 - help</command>; it will print a brief list of commands, 5.117 - along with a description of what each does. If you ask for 5.118 - help on a specific command (as below), it prints more 5.119 - detailed information.</para> 5.120 - 5.121 - &interaction.tour.help; 5.122 - 5.123 - <para>For a more impressive level of detail (which you won't 5.124 - usually need) run <command role="hg-cmd">hg help <option 5.125 - role="hg-opt-global">-v</option></command>. The <option 5.126 - role="hg-opt-global">-v</option> option is short for 5.127 - <option role="hg-opt-global">--verbose</option>, and tells 5.128 - Mercurial to print more information than it usually 5.129 - would.</para> 5.130 - 5.131 - </sect2> 5.132 - </sect1> 5.133 - <sect1> 5.134 - <title>Working with a repository</title> 5.135 - 5.136 - <para>In Mercurial, everything happens inside a 5.137 - <emphasis>repository</emphasis>. The repository for a project 5.138 - contains all of the files that <quote>belong to</quote> that 5.139 - project, along with a historical record of the project's 5.140 - files.</para> 5.141 - 5.142 - <para>There's nothing particularly magical about a repository; it 5.143 - is simply a directory tree in your filesystem that Mercurial 5.144 - treats as special. You can rename or delete a repository any 5.145 - time you like, using either the command line or your file 5.146 - browser.</para> 5.147 - 5.148 - <sect2> 5.149 - <title>Making a local copy of a repository</title> 5.150 - 5.151 - <para><emphasis>Copying</emphasis> a repository is just a little 5.152 - bit special. While you could use a normal file copying 5.153 - command to make a copy of a repository, it's best to use a 5.154 - built-in command that Mercurial provides. This command is 5.155 - called <command role="hg-cmd">hg clone</command>, because it 5.156 - creates an identical copy of an existing repository.</para> 5.157 - 5.158 - &interaction.tour.clone; 5.159 - 5.160 - <para>If our clone succeeded, we should now have a local 5.161 - directory called <filename class="directory">hello</filename>. 5.162 - This directory will contain some files.</para> 5.163 - 5.164 - &interaction.tour.ls; 5.165 - 5.166 - <para>These files have the same contents and history in our 5.167 - repository as they do in the repository we cloned.</para> 5.168 - 5.169 - <para>Every Mercurial repository is complete, self-contained, 5.170 - and independent. It contains its own private copy of a 5.171 - project's files and history. A cloned repository remembers 5.172 - the location of the repository it was cloned from, but it does 5.173 - not communicate with that repository, or any other, unless you 5.174 - tell it to.</para> 5.175 - 5.176 - <para>What this means for now is that we're free to experiment 5.177 - with our repository, safe in the knowledge that it's a private 5.178 - <quote>sandbox</quote> that won't affect anyone else.</para> 5.179 - 5.180 - </sect2> 5.181 - <sect2> 5.182 - <title>What's in a repository?</title> 5.183 - 5.184 - <para>When we take a more detailed look inside a repository, we 5.185 - can see that it contains a directory named <filename 5.186 - class="directory">.hg</filename>. This is where Mercurial 5.187 - keeps all of its metadata for the repository.</para> 5.188 - 5.189 - &interaction.tour.ls-a; 5.190 - 5.191 - <para>The contents of the <filename 5.192 - class="directory">.hg</filename> directory and its 5.193 - subdirectories are private to Mercurial. Every other file and 5.194 - directory in the repository is yours to do with as you 5.195 - please.</para> 5.196 - 5.197 - <para>To introduce a little terminology, the <filename 5.198 - class="directory">.hg</filename> directory is the 5.199 - <quote>real</quote> repository, and all of the files and 5.200 - directories that coexist with it are said to live in the 5.201 - <emphasis>working directory</emphasis>. An easy way to 5.202 - remember the distinction is that the 5.203 - <emphasis>repository</emphasis> contains the 5.204 - <emphasis>history</emphasis> of your project, while the 5.205 - <emphasis>working directory</emphasis> contains a 5.206 - <emphasis>snapshot</emphasis> of your project at a particular 5.207 - point in history.</para> 5.208 - 5.209 - </sect2> 5.210 - </sect1> 5.211 - <sect1> 5.212 - <title>A tour through history</title> 5.213 - 5.214 - <para>One of the first things we might want to do with a new, 5.215 - unfamiliar repository is understand its history. The <command 5.216 - role="hg-cmd">hg log</command> command gives us a view of 5.217 - history.</para> 5.218 - 5.219 - &interaction.tour.log; 5.220 - 5.221 - <para>By default, this command prints a brief paragraph of output 5.222 - for each change to the project that was recorded. In Mercurial 5.223 - terminology, we call each of these recorded events a 5.224 - <emphasis>changeset</emphasis>, because it can contain a record 5.225 - of changes to several files.</para> 5.226 - 5.227 - <para>The fields in a record of output from <command 5.228 - role="hg-cmd">hg log</command> are as follows.</para> 5.229 - <itemizedlist> 5.230 - <listitem><para><literal>changeset</literal>: This field has the 5.231 - format of a number, followed by a colon, followed by a 5.232 - hexadecimal string. These are 5.233 - <emphasis>identifiers</emphasis> for the changeset. There 5.234 - are two identifiers because the number is shorter and easier 5.235 - to type than the hex string.</para></listitem> 5.236 - <listitem><para><literal>user</literal>: The identity of the 5.237 - person who created the changeset. This is a free-form 5.238 - field, but it most often contains a person's name and email 5.239 - address.</para></listitem> 5.240 - <listitem><para><literal>date</literal>: The date and time on 5.241 - which the changeset was created, and the timezone in which 5.242 - it was created. (The date and time are local to that 5.243 - timezone; they display what time and date it was for the 5.244 - person who created the changeset.)</para></listitem> 5.245 - <listitem><para><literal>summary</literal>: The first line of 5.246 - the text message that the creator of the changeset entered 5.247 - to describe the changeset.</para></listitem></itemizedlist> 5.248 - <para>The default output printed by <command role="hg-cmd">hg 5.249 - log</command> is purely a summary; it is missing a lot of 5.250 - detail.</para> 5.251 - 5.252 - <para>Figure <xref linkend="fig:tour-basic:history"/> provides a 5.253 - graphical representation of the history of the <filename 5.254 - class="directory">hello</filename> repository, to make it a 5.255 - little easier to see which direction history is 5.256 - <quote>flowing</quote> in. We'll be returning to this figure 5.257 - several times in this chapter and the chapter that 5.258 - follows.</para> 5.259 - 5.260 - <informalfigure id="fig:tour-basic:history"> 5.261 - <mediaobject> 5.262 - <imageobject><imagedata fileref="tour-history"/></imageobject> 5.263 - <textobject><phrase>XXX add text</phrase></textobject> 5.264 - <caption><para>Graphical history of the <filename 5.265 - class="directory">hello</filename> 5.266 - repository</para></caption> 5.267 - </mediaobject> 5.268 - </informalfigure> 5.269 - 5.270 - <sect2> 5.271 - <title>Changesets, revisions, and talking to other 5.272 - people</title> 5.273 - 5.274 - <para>As English is a notoriously sloppy language, and computer 5.275 - science has a hallowed history of terminological confusion 5.276 - (why use one term when four will do?), revision control has a 5.277 - variety of words and phrases that mean the same thing. If you 5.278 - are talking about Mercurial history with other people, you 5.279 - will find that the word <quote>changeset</quote> is often 5.280 - compressed to <quote>change</quote> or (when written) 5.281 - <quote>cset</quote>, and sometimes a changeset is referred to 5.282 - as a <quote>revision</quote> or a <quote>rev</quote>.</para> 5.283 - 5.284 - <para>While it doesn't matter what <emphasis>word</emphasis> you 5.285 - use to refer to the concept of <quote>a changeset</quote>, the 5.286 - <emphasis>identifier</emphasis> that you use to refer to 5.287 - <quote>a <emphasis>specific</emphasis> changeset</quote> is of 5.288 - great importance. Recall that the <literal>changeset</literal> 5.289 - field in the output from <command role="hg-cmd">hg 5.290 - log</command> identifies a changeset using both a number and 5.291 - a hexadecimal string.</para> 5.292 - <itemizedlist> 5.293 - <listitem><para>The revision number is <emphasis>only valid in 5.294 - that repository</emphasis>,</para></listitem> 5.295 - <listitem><para>while the hex string is the 5.296 - <emphasis>permanent, unchanging identifier</emphasis> that 5.297 - will always identify that exact changeset in 5.298 - <emphasis>every</emphasis> copy of the 5.299 - repository.</para></listitem></itemizedlist> 5.300 - <para>This distinction is important. If you send someone an 5.301 - email talking about <quote>revision 33</quote>, there's a high 5.302 - likelihood that their revision 33 will <emphasis>not be the 5.303 - same</emphasis> as yours. The reason for this is that a 5.304 - revision number depends on the order in which changes arrived 5.305 - in a repository, and there is no guarantee that the same 5.306 - changes will happen in the same order in different 5.307 - repositories. Three changes $a,b,c$ can easily appear in one 5.308 - repository as $0,1,2$, while in another as $1,0,2$.</para> 5.309 - 5.310 - <para>Mercurial uses revision numbers purely as a convenient 5.311 - shorthand. If you need to discuss a changeset with someone, 5.312 - or make a record of a changeset for some other reason (for 5.313 - example, in a bug report), use the hexadecimal 5.314 - identifier.</para> 5.315 - 5.316 - </sect2> 5.317 - <sect2> 5.318 - <title>Viewing specific revisions</title> 5.319 - 5.320 - <para>To narrow the output of <command role="hg-cmd">hg 5.321 - log</command> down to a single revision, use the <option 5.322 - role="hg-opt-log">-r</option> (or <option 5.323 - role="hg-opt-log">--rev</option>) option. You can use 5.324 - either a revision number or a long-form changeset identifier, 5.325 - and you can provide as many revisions as you want.</para> 5.326 - 5.327 - &interaction.tour.log-r; 5.328 - 5.329 - <para>If you want to see the history of several revisions 5.330 - without having to list each one, you can use <emphasis>range 5.331 - notation</emphasis>; this lets you express the idea <quote>I 5.332 - want all revisions between <literal>abc</literal> and 5.333 - <literal>def</literal>, inclusive</quote>.</para> 5.334 - 5.335 - &interaction.tour.log.range; 5.336 - 5.337 - <para>Mercurial also honours the order in which you specify 5.338 - revisions, so <command role="hg-cmd">hg log -r 2:4</command> 5.339 - prints 2, 3, and 4. while <command role="hg-cmd">hg log -r 5.340 - 4:2</command> prints 4, 3, and 2.</para> 5.341 - 5.342 - </sect2> 5.343 - <sect2> 5.344 - <title>More detailed information</title> 5.345 - 5.346 - <para>While the summary information printed by <command 5.347 - role="hg-cmd">hg log</command> is useful if you already know 5.348 - what you're looking for, you may need to see a complete 5.349 - description of the change, or a list of the files changed, if 5.350 - you're trying to decide whether a changeset is the one you're 5.351 - looking for. The <command role="hg-cmd">hg log</command> 5.352 - command's <option role="hg-opt-global">-v</option> (or <option 5.353 - role="hg-opt-global">--verbose</option>) option gives you 5.354 - this extra detail.</para> 5.355 - 5.356 - &interaction.tour.log-v; 5.357 - 5.358 - <para>If you want to see both the description and content of a 5.359 - change, add the <option role="hg-opt-log">-p</option> (or 5.360 - <option role="hg-opt-log">--patch</option>) option. This 5.361 - displays the content of a change as a <emphasis>unified 5.362 - diff</emphasis> (if you've never seen a unified diff before, 5.363 - see section <xref linkend="sec:mq:patch"/> for an 5.364 - overview).</para> 5.365 - 5.366 - &interaction.tour.log-vp; 5.367 - 5.368 - </sect2> 5.369 - </sect1> 5.370 - <sect1> 5.371 - <title>All about command options</title> 5.372 - 5.373 - <para>Let's take a brief break from exploring Mercurial commands 5.374 - to discuss a pattern in the way that they work; you may find 5.375 - this useful to keep in mind as we continue our tour.</para> 5.376 - 5.377 - <para>Mercurial has a consistent and straightforward approach to 5.378 - dealing with the options that you can pass to commands. It 5.379 - follows the conventions for options that are common to modern 5.380 - Linux and Unix systems.</para> 5.381 - <itemizedlist> 5.382 - <listitem><para>Every option has a long name. For example, as 5.383 - we've already seen, the <command role="hg-cmd">hg 5.384 - log</command> command accepts a <option 5.385 - role="hg-opt-log">--rev</option> option.</para></listitem> 5.386 - <listitem><para>Most options have short names, too. Instead of 5.387 - <option role="hg-opt-log">--rev</option>, we can use <option 5.388 - role="hg-opt-log">-r</option>. (The reason that some 5.389 - options don't have short names is that the options in 5.390 - question are rarely used.)</para></listitem> 5.391 - <listitem><para>Long options start with two dashes (e.g. <option 5.392 - role="hg-opt-log">--rev</option>), while short options 5.393 - start with one (e.g. <option 5.394 - role="hg-opt-log">-r</option>).</para></listitem> 5.395 - <listitem><para>Option naming and usage is consistent across 5.396 - commands. For example, every command that lets you specify 5.397 - a changeset ID or revision number accepts both <option 5.398 - role="hg-opt-log">-r</option> and <option 5.399 - role="hg-opt-log">--rev</option> 5.400 - arguments.</para></listitem></itemizedlist> 5.401 - <para>In the examples throughout this book, I use short options 5.402 - instead of long. This just reflects my own preference, so don't 5.403 - read anything significant into it.</para> 5.404 - 5.405 - <para>Most commands that print output of some kind will print more 5.406 - output when passed a <option role="hg-opt-global">-v</option> 5.407 - (or <option role="hg-opt-global">--verbose</option>) option, and 5.408 - less when passed <option role="hg-opt-global">-q</option> (or 5.409 - <option role="hg-opt-global">--quiet</option>).</para> 5.410 - 5.411 - </sect1> 5.412 - <sect1> 5.413 - <title>Making and reviewing changes</title> 5.414 - 5.415 - <para>Now that we have a grasp of viewing history in Mercurial, 5.416 - let's take a look at making some changes and examining 5.417 - them.</para> 5.418 - 5.419 - <para>The first thing we'll do is isolate our experiment in a 5.420 - repository of its own. We use the <command role="hg-cmd">hg 5.421 - clone</command> command, but we don't need to clone a copy of 5.422 - the remote repository. Since we already have a copy of it 5.423 - locally, we can just clone that instead. This is much faster 5.424 - than cloning over the network, and cloning a local repository 5.425 - uses less disk space in most cases, too.</para> 5.426 - 5.427 - &interaction.tour.reclone; 5.428 - 5.429 - <para>As an aside, it's often good practice to keep a 5.430 - <quote>pristine</quote> copy of a remote repository around, 5.431 - which you can then make temporary clones of to create sandboxes 5.432 - for each task you want to work on. This lets you work on 5.433 - multiple tasks in parallel, each isolated from the others until 5.434 - it's complete and you're ready to integrate it back. Because 5.435 - local clones are so cheap, there's almost no overhead to cloning 5.436 - and destroying repositories whenever you want.</para> 5.437 - 5.438 - <para>In our <filename class="directory">my-hello</filename> 5.439 - repository, we have a file <filename>hello.c</filename> that 5.440 - contains the classic <quote>hello, world</quote> program. Let's 5.441 - use the ancient and venerable <command>sed</command> command to 5.442 - edit this file so that it prints a second line of output. (I'm 5.443 - only using <command>sed</command> to do this because it's easy 5.444 - to write a scripted example this way. Since you're not under 5.445 - the same constraint, you probably won't want to use 5.446 - <command>sed</command>; simply use your preferred text editor to 5.447 - do the same thing.)</para> 5.448 - 5.449 - &interaction.tour.sed; 5.450 - 5.451 - <para>Mercurial's <command role="hg-cmd">hg status</command> 5.452 - command will tell us what Mercurial knows about the files in the 5.453 - repository.</para> 5.454 - 5.455 - &interaction.tour.status; 5.456 - 5.457 - <para>The <command role="hg-cmd">hg status</command> command 5.458 - prints no output for some files, but a line starting with 5.459 - <quote><literal>M</literal></quote> for 5.460 - <filename>hello.c</filename>. Unless you tell it to, <command 5.461 - role="hg-cmd">hg status</command> will not print any output 5.462 - for files that have not been modified.</para> 5.463 - 5.464 - <para>The <quote><literal>M</literal></quote> indicates that 5.465 - Mercurial has noticed that we modified 5.466 - <filename>hello.c</filename>. We didn't need to 5.467 - <emphasis>inform</emphasis> Mercurial that we were going to 5.468 - modify the file before we started, or that we had modified the 5.469 - file after we were done; it was able to figure this out 5.470 - itself.</para> 5.471 - 5.472 - <para>It's a little bit helpful to know that we've modified 5.473 - <filename>hello.c</filename>, but we might prefer to know 5.474 - exactly <emphasis>what</emphasis> changes we've made to it. To 5.475 - do this, we use the <command role="hg-cmd">hg diff</command> 5.476 - command.</para> 5.477 - 5.478 - &interaction.tour.diff; 5.479 - 5.480 - </sect1> 5.481 - <sect1> 5.482 - <title>Recording changes in a new changeset</title> 5.483 - 5.484 - <para>We can modify files, build and test our changes, and use 5.485 - <command role="hg-cmd">hg status</command> and <command 5.486 - role="hg-cmd">hg diff</command> to review our changes, until 5.487 - we're satisfied with what we've done and arrive at a natural 5.488 - stopping point where we want to record our work in a new 5.489 - changeset.</para> 5.490 - 5.491 - <para>The <command role="hg-cmd">hg commit</command> command lets 5.492 - us create a new changeset; we'll usually refer to this as 5.493 - <quote>making a commit</quote> or 5.494 - <quote>committing</quote>.</para> 5.495 - 5.496 - <sect2> 5.497 - <title>Setting up a username</title> 5.498 - 5.499 - <para>When you try to run <command role="hg-cmd">hg 5.500 - commit</command> for the first time, it is not guaranteed to 5.501 - succeed. Mercurial records your name and address with each 5.502 - change that you commit, so that you and others will later be 5.503 - able to tell who made each change. Mercurial tries to 5.504 - automatically figure out a sensible username to commit the 5.505 - change with. It will attempt each of the following methods, 5.506 - in order:</para> 5.507 - <orderedlist> 5.508 - <listitem><para>If you specify a <option 5.509 - role="hg-opt-commit">-u</option> option to the <command 5.510 - role="hg-cmd">hg commit</command> command on the command 5.511 - line, followed by a username, this is always given the 5.512 - highest precedence.</para></listitem> 5.513 - <listitem><para>If you have set the <envar>HGUSER</envar> 5.514 - environment variable, this is checked 5.515 - next.</para></listitem> 5.516 - <listitem><para>If you create a file in your home directory 5.517 - called <filename role="special">.hgrc</filename>, with a 5.518 - <envar role="rc-item-ui">username</envar> entry, that will 5.519 - be used next. To see what the contents of this file 5.520 - should look like, refer to section <xref 5.521 - linkend="sec:tour-basic:username"/> 5.522 - below.</para></listitem> 5.523 - <listitem><para>If you have set the <envar>EMAIL</envar> 5.524 - environment variable, this will be used 5.525 - next.</para></listitem> 5.526 - <listitem><para>Mercurial will query your system to find out 5.527 - your local user name and host name, and construct a 5.528 - username from these components. Since this often results 5.529 - in a username that is not very useful, it will print a 5.530 - warning if it has to do 5.531 - this.</para></listitem> 5.532 - </orderedlist> 5.533 - <para>If all of these mechanisms fail, Mercurial will 5.534 - fail, printing an error message. In this case, it will not 5.535 - let you commit until you set up a 5.536 - username.</para> 5.537 - <para>You should think of the <envar>HGUSER</envar> environment 5.538 - variable and the <option role="hg-opt-commit">-u</option> 5.539 - option to the <command role="hg-cmd">hg commit</command> 5.540 - command as ways to <emphasis>override</emphasis> Mercurial's 5.541 - default selection of username. For normal use, the simplest 5.542 - and most robust way to set a username for yourself is by 5.543 - creating a <filename role="special">.hgrc</filename> file; see 5.544 - below for details.</para> 5.545 - <sect3 id="sec:tour-basic:username"> 5.546 - <title>Creating a Mercurial configuration file</title> 5.547 - 5.548 - <para>To set a user name, use your favourite editor 5.549 - to create a file called <filename 5.550 - role="special">.hgrc</filename> in your home directory. 5.551 - Mercurial will use this file to look up your personalised 5.552 - configuration settings. The initial contents of your 5.553 - <filename role="special">.hgrc</filename> should look like 5.554 - this.</para> 5.555 - <programlisting># This is a Mercurial configuration file. 5.556 -[ui] 5.557 -username = Firstname Lastname 5.558 -<email.address@domain.net></programlisting> 5.559 - 5.560 - <para>The <quote><literal>[ui]</literal></quote> line begins a 5.561 - <emphasis>section</emphasis> of the config file, so you can 5.562 - read the <quote><literal>username = ...</literal></quote> 5.563 - line as meaning <quote>set the value of the 5.564 - <literal>username</literal> item in the 5.565 - <literal>ui</literal> section</quote>. A section continues 5.566 - until a new section begins, or the end of the file. 5.567 - Mercurial ignores empty lines and treats any text from 5.568 - <quote><literal>#</literal></quote> to the end of a line as 5.569 - a comment.</para> 5.570 - </sect3> 5.571 - 5.572 - <sect3> 5.573 - <title>Choosing a user name</title> 5.574 - 5.575 - <para>You can use any text you like as the value of 5.576 - the <literal>username</literal> config item, since this 5.577 - information is for reading by other people, but for 5.578 - interpreting by Mercurial. The convention that most 5.579 - people follow is to use their name and email address, as 5.580 - in the example above.</para> 5.581 - <note> 5.582 - <para>Mercurial's built-in web server obfuscates 5.583 - email addresses, to make it more difficult for the email 5.584 - harvesting tools that spammers use. This reduces the 5.585 - likelihood that you'll start receiving more junk email 5.586 - if you publish a Mercurial repository on the 5.587 - web.</para></note> 5.588 - 5.589 - </sect3> 5.590 - </sect2> 5.591 - <sect2> 5.592 - <title>Writing a commit message</title> 5.593 - 5.594 - <para>When we commit a change, Mercurial drops us into 5.595 - a text editor, to enter a message that will describe the 5.596 - modifications we've made in this changeset. This is called 5.597 - the <emphasis>commit message</emphasis>. It will be a 5.598 - record for readers of what we did and why, and it will be 5.599 - printed by <command role="hg-cmd">hg log</command> after 5.600 - we've finished committing.</para> 5.601 - 5.602 - &interaction.tour.commit; 5.603 - 5.604 - <para>The editor that the <command role="hg-cmd">hg 5.605 - commit</command> command drops us into will contain an 5.606 - empty line, followed by a number of lines starting with 5.607 - <quote><literal>HG:</literal></quote>.</para> 5.608 - 5.609 - <programlisting>XXX fix this XXX</programlisting> 5.610 - 5.611 - <para>Mercurial ignores the lines that start with 5.612 - <quote><literal>HG:</literal></quote>; it uses them only to 5.613 - tell us which files it's recording changes to. Modifying or 5.614 - deleting these lines has no effect.</para> 5.615 - </sect2> 5.616 - <sect2> 5.617 - <title>Writing a good commit message</title> 5.618 - 5.619 - <para>Since <command role="hg-cmd">hg log</command> 5.620 - only prints the first line of a commit message by default, 5.621 - it's best to write a commit message whose first line stands 5.622 - alone. Here's a real example of a commit message that 5.623 - <emphasis>doesn't</emphasis> follow this guideline, and 5.624 - hence has a summary that is not 5.625 - readable.</para> 5.626 - 5.627 - <programlisting> 5.628 -changeset: 73:584af0e231be 5.629 -user: Censored Person <censored.person@example.org> 5.630 -date: Tue Sep 26 21:37:07 2006 -0700 5.631 -summary: include buildmeister/commondefs. Add exports.</programlisting> 5.632 - 5.633 - <para>As far as the remainder of the contents of the 5.634 - commit message are concerned, there are no hard-and-fast 5.635 - rules. Mercurial itself doesn't interpret or care about the 5.636 - contents of the commit message, though your project may have 5.637 - policies that dictate a certain kind of 5.638 - formatting.</para> 5.639 - <para>My personal preference is for short, but 5.640 - informative, commit messages that tell me something that I 5.641 - can't figure out with a quick glance at the output of 5.642 - <command role="hg-cmd">hg log 5.643 - --patch</command>.</para> 5.644 - </sect2> 5.645 - <sect2> 5.646 - <title>Aborting a commit</title> 5.647 - 5.648 - <para>If you decide that you don't want to commit 5.649 - while in the middle of editing a commit message, simply exit 5.650 - from your editor without saving the file that it's editing. 5.651 - This will cause nothing to happen to either the repository 5.652 - or the working directory.</para> 5.653 - <para>If we run the <command role="hg-cmd">hg 5.654 - commit</command> command without any arguments, it records 5.655 - all of the changes we've made, as reported by <command 5.656 - role="hg-cmd">hg status</command> and <command 5.657 - role="hg-cmd">hg diff</command>.</para> 5.658 - </sect2> 5.659 - <sect2> 5.660 - <title>Admiring our new handiwork</title> 5.661 - 5.662 - <para>Once we've finished the commit, we can use the 5.663 - <command role="hg-cmd">hg tip</command> command to display 5.664 - the changeset we just created. This command produces output 5.665 - that is identical to <command role="hg-cmd">hg 5.666 - log</command>, but it only displays the newest revision in 5.667 - the repository.</para> 5.668 - 5.669 - &interaction.tour.tip; 5.670 - 5.671 - <para>We refer to 5.672 - the newest revision in the repository as the tip revision, 5.673 - or simply the tip.</para> 5.674 - </sect2> 5.675 - </sect1> 5.676 - 5.677 - <sect1> 5.678 - <title>Sharing changes</title> 5.679 - 5.680 - <para>We mentioned earlier that repositories in 5.681 - Mercurial are self-contained. This means that the changeset 5.682 - we just created exists only in our <filename 5.683 - class="directory">my-hello</filename> repository. Let's 5.684 - look at a few ways that we can propagate this change into 5.685 - other repositories.</para> 5.686 - 5.687 - <sect2 id="sec:tour:pull"> 5.688 - <title>Pulling changes from another repository</title> 5.689 - <para>To get started, let's clone our original 5.690 - <filename class="directory">hello</filename> repository, 5.691 - which does not contain the change we just committed. We'll 5.692 - call our temporary repository <filename 5.693 - class="directory">hello-pull</filename>.</para> 5.694 - 5.695 - &interaction.tour.clone-pull; 5.696 - 5.697 - <para>We'll use the <command role="hg-cmd">hg 5.698 - pull</command> command to bring changes from <filename 5.699 - class="directory">my-hello</filename> into <filename 5.700 - class="directory">hello-pull</filename>. However, blindly 5.701 - pulling unknown changes into a repository is a somewhat 5.702 - scary prospect. Mercurial provides the <command 5.703 - role="hg-cmd">hg incoming</command> command to tell us 5.704 - what changes the <command role="hg-cmd">hg pull</command> 5.705 - command <emphasis>would</emphasis> pull into the repository, 5.706 - without actually pulling the changes in.</para> 5.707 - 5.708 - &interaction.tour.incoming; 5.709 - 5.710 - <para>(Of course, someone could 5.711 - cause more changesets to appear in the repository that we 5.712 - ran <command role="hg-cmd">hg incoming</command> in, before 5.713 - we get a chance to <command role="hg-cmd">hg pull</command> 5.714 - the changes, so that we could end up pulling changes that we 5.715 - didn't expect.)</para> 5.716 - 5.717 - <para>Bringing changes into a repository is a simple 5.718 - matter of running the <command role="hg-cmd">hg 5.719 - pull</command> command, and telling it which repository to 5.720 - pull from.</para> 5.721 - 5.722 - &interaction.tour.pull; 5.723 - 5.724 - <para>As you can see 5.725 - from the before-and-after output of <command 5.726 - role="hg-cmd">hg tip</command>, we have successfully 5.727 - pulled changes into our repository. There remains one step 5.728 - before we can see these changes in the working 5.729 - directory.</para> 5.730 - </sect2> 5.731 - <sect2> 5.732 - <title>Updating the working directory</title> 5.733 - 5.734 - <para>We have so far glossed over the relationship between a 5.735 - repository and its working directory. The <command 5.736 - role="hg-cmd">hg pull</command> command that we ran in 5.737 - section <xref linkend="sec:tour:pull"/> brought changes 5.738 - into the repository, but if we check, there's no sign of those 5.739 - changes in the working directory. This is because <command 5.740 - role="hg-cmd">hg pull</command> does not (by default) touch 5.741 - the working directory. Instead, we use the <command 5.742 - role="hg-cmd">hg update</command> command to do this.</para> 5.743 - 5.744 - &interaction.tour.update; 5.745 - 5.746 - <para>It might seem a bit strange that <command role="hg-cmd">hg 5.747 - pull</command> doesn't update the working directory 5.748 - automatically. There's actually a good reason for this: you 5.749 - can use <command role="hg-cmd">hg update</command> to update 5.750 - the working directory to the state it was in at <emphasis>any 5.751 - revision</emphasis> in the history of the repository. If 5.752 - you had the working directory updated to an old revision---to 5.753 - hunt down the origin of a bug, say---and ran a <command 5.754 - role="hg-cmd">hg pull</command> which automatically updated 5.755 - the working directory to a new revision, you might not be 5.756 - terribly happy.</para> 5.757 - <para>However, since pull-then-update is such a common thing to 5.758 - do, Mercurial lets you combine the two by passing the <option 5.759 - role="hg-opt-pull">-u</option> option to <command 5.760 - role="hg-cmd">hg pull</command>.</para> 5.761 - 5.762 - <para>If you look back at the output of <command 5.763 - role="hg-cmd">hg pull</command> in section <xref 5.764 - linkend="sec:tour:pull"/> when we ran it without <option 5.765 - role="hg-opt-pull">-u</option>, you can see that it printed 5.766 - a helpful reminder that we'd have to take an explicit step to 5.767 - update the working directory:</para> 5.768 - 5.769 - <!-- &interaction.xxx.fixme; --> 5.770 - 5.771 - <para>To find out what revision the working directory is at, use 5.772 - the <command role="hg-cmd">hg parents</command> 5.773 - command.</para> 5.774 - 5.775 - &interaction.tour.parents; 5.776 - 5.777 - <para>If you look back at figure <xref 5.778 - linkend="fig:tour-basic:history"/>, 5.779 - you'll see arrows connecting each changeset. The node that 5.780 - the arrow leads <emphasis>from</emphasis> in each case is a 5.781 - parent, and the node that the arrow leads 5.782 - <emphasis>to</emphasis> is its child. The working directory 5.783 - has a parent in just the same way; this is the changeset that 5.784 - the working directory currently contains.</para> 5.785 - 5.786 - <para>To update the working directory to a particular revision, 5.787 - 5.788 - give a revision number or changeset ID to the <command 5.789 - role="hg-cmd">hg update</command> command.</para> 5.790 - 5.791 - &interaction.tour.older; 5.792 - 5.793 - <para>If you omit an explicit revision, <command 5.794 - role="hg-cmd">hg update</command> will update to the tip 5.795 - revision, as shown by the second call to <command 5.796 - role="hg-cmd">hg update</command> in the example 5.797 - above.</para> 5.798 - </sect2> 5.799 - 5.800 - <sect2> 5.801 - <title>Pushing changes to another repository</title> 5.802 - 5.803 - <para>Mercurial lets us push changes to another 5.804 - repository, from the repository we're currently visiting. 5.805 - As with the example of <command role="hg-cmd">hg 5.806 - pull</command> above, we'll create a temporary repository 5.807 - to push our changes into.</para> 5.808 - 5.809 - &interaction.tour.clone-push; 5.810 - 5.811 - <para>The <command role="hg-cmd">hg outgoing</command> command 5.812 - tells us what changes would be pushed into another 5.813 - repository.</para> 5.814 - 5.815 - &interaction.tour.outgoing; 5.816 - 5.817 - <para>And the 5.818 - <command role="hg-cmd">hg push</command> command does the 5.819 - actual push.</para> 5.820 - 5.821 - &interaction.tour.push; 5.822 - 5.823 - <para>As with 5.824 - <command role="hg-cmd">hg pull</command>, the <command 5.825 - role="hg-cmd">hg push</command> command does not update 5.826 - the working directory in the repository that it's pushing 5.827 - changes into. (Unlike <command role="hg-cmd">hg 5.828 - pull</command>, <command role="hg-cmd">hg push</command> 5.829 - does not provide a <literal>-u</literal> option that updates 5.830 - the other repository's working directory.)</para> 5.831 - 5.832 - <para>What happens if we try to pull or push changes 5.833 - and the receiving repository already has those changes? 5.834 - Nothing too exciting.</para> 5.835 - 5.836 - &interaction.tour.push.nothing; 5.837 - </sect2> 5.838 - <sect2> 5.839 - <title>Sharing changes over a network</title> 5.840 - 5.841 - <para>The commands we have covered in the previous few 5.842 - sections are not limited to working with local repositories. 5.843 - Each works in exactly the same fashion over a network 5.844 - connection; simply pass in a URL instead of a local 5.845 - path.</para> 5.846 - 5.847 - &interaction.tour.outgoing.net; 5.848 - 5.849 - <para>In this example, we 5.850 - can see what changes we could push to the remote repository, 5.851 - but the repository is understandably not set up to let 5.852 - anonymous users push to it.</para> 5.853 - 5.854 - &interaction.tour.push.net; 5.855 - </sect2> 5.856 - </sect1> 5.857 -</chapter> 5.858 - 5.859 -<!-- 5.860 -local variables: 5.861 -sgml-parent-document: ("00book.xml" "book" "chapter") 5.862 -end: 5.863 --->
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/en/ch02-tour-merge.xml Thu Mar 19 20:54:12 2009 -0700 6.3 @@ -0,0 +1,394 @@ 6.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 6.5 + 6.6 +<chapter id="chap:tour-merge"> 6.7 + <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?> 6.8 + <title>A tour of Mercurial: merging work</title> 6.9 + 6.10 + <para>We've now covered cloning a repository, making changes in a 6.11 + repository, and pulling or pushing changes from one repository 6.12 + into another. Our next step is <emphasis>merging</emphasis> 6.13 + changes from separate repositories.</para> 6.14 + 6.15 + <sect1> 6.16 + <title>Merging streams of work</title> 6.17 + 6.18 + <para>Merging is a fundamental part of working with a distributed 6.19 + revision control tool.</para> 6.20 + <itemizedlist> 6.21 + <listitem><para>Alice and Bob each have a personal copy of a 6.22 + repository for a project they're collaborating on. Alice 6.23 + fixes a bug in her repository; Bob adds a new feature in 6.24 + his. They want the shared repository to contain both the 6.25 + bug fix and the new feature.</para> 6.26 + </listitem> 6.27 + <listitem><para>I frequently work on several different tasks for 6.28 + a single project at once, each safely isolated in its own 6.29 + repository. Working this way means that I often need to 6.30 + merge one piece of my own work with another.</para> 6.31 + </listitem></itemizedlist> 6.32 + 6.33 + <para>Because merging is such a common thing to need to do, 6.34 + Mercurial makes it easy. Let's walk through the process. We'll 6.35 + begin by cloning yet another repository (see how often they 6.36 + spring up?) and making a change in it.</para> 6.37 + 6.38 + &interaction.tour.merge.clone; 6.39 + 6.40 + <para>We should now have two copies of 6.41 + <filename>hello.c</filename> with different contents. The 6.42 + histories of the two repositories have also diverged, as 6.43 + illustrated in figure <xref 6.44 + linkend="fig:tour-merge:sep-repos"/>.</para> 6.45 + 6.46 + &interaction.tour.merge.cat; 6.47 + 6.48 + <informalfigure id="fig:tour-merge:sep-repos"> 6.49 + <mediaobject> 6.50 + <imageobject><imagedata fileref="tour-merge-sep-repos"/></imageobject> 6.51 + <textobject><phrase>XXX add text</phrase></textobject> 6.52 + <caption><para>Divergent recent histories of the <filename 6.53 + class="directory">my-hello</filename> and <filename 6.54 + class="directory">my-new-hello</filename> 6.55 + repositories</para></caption> 6.56 + </mediaobject> 6.57 + </informalfigure> 6.58 + 6.59 + <para>We already know that pulling changes from our <filename 6.60 + class="directory">my-hello</filename> repository will have no 6.61 + effect on the working directory.</para> 6.62 + 6.63 + &interaction.tour.merge.pull; 6.64 + 6.65 + <para>However, the <command role="hg-cmd">hg pull</command> 6.66 + command says something about <quote>heads</quote>.</para> 6.67 + 6.68 + <sect2> 6.69 + <title>Head changesets</title> 6.70 + 6.71 + <para>A head is a change that has no descendants, or children, 6.72 + as they're also known. The tip revision is thus a head, 6.73 + because the newest revision in a repository doesn't have any 6.74 + children, but a repository can contain more than one 6.75 + head.</para> 6.76 + 6.77 + <informalfigure id="fig:tour-merge:pull"> 6.78 + <mediaobject><imageobject><imagedata 6.79 + fileref="tour-merge-pull"/></imageobject><textobject><phrase>XXX 6.80 + add text</phrase></textobject> 6.81 + <caption><para>Repository contents after pulling from 6.82 + <filename class="directory">my-hello</filename> into 6.83 + <filename 6.84 + class="directory">my-new-hello</filename></para></caption> 6.85 + </mediaobject> 6.86 + </informalfigure> 6.87 + 6.88 + <para>In figure <xref linkend="fig:tour-merge:pull"/>, you can 6.89 + see the effect of the pull from <filename 6.90 + class="directory">my-hello</filename> into <filename 6.91 + class="directory">my-new-hello</filename>. The history that 6.92 + was already present in <filename 6.93 + class="directory">my-new-hello</filename> is untouched, but 6.94 + a new revision has been added. By referring to figure <xref 6.95 + linkend="fig:tour-merge:sep-repos"/>, we can see that the 6.96 + <emphasis>changeset ID</emphasis> remains the same in the new 6.97 + repository, but the <emphasis>revision number</emphasis> has 6.98 + changed. (This, incidentally, is a fine example of why it's 6.99 + not safe to use revision numbers when discussing changesets.) 6.100 + We can view the heads in a repository using the <command 6.101 + role="hg-cmd">hg heads</command> command.</para> 6.102 + 6.103 + &interaction.tour.merge.heads; 6.104 + 6.105 + </sect2> 6.106 + <sect2> 6.107 + <title>Performing the merge</title> 6.108 + 6.109 + <para>What happens if we try to use the normal <command 6.110 + role="hg-cmd">hg update</command> command to update to the 6.111 + new tip?</para> 6.112 + 6.113 + &interaction.tour.merge.update; 6.114 + 6.115 + <para>Mercurial is telling us that the <command role="hg-cmd">hg 6.116 + update</command> command won't do a merge; it won't update 6.117 + the working directory when it thinks we might be wanting to do 6.118 + a merge, unless we force it to do so. Instead, we use the 6.119 + <command role="hg-cmd">hg merge</command> command to merge the 6.120 + two heads.</para> 6.121 + 6.122 + &interaction.tour.merge.merge; 6.123 + 6.124 + <informalfigure id="fig:tour-merge:merge"> 6.125 + 6.126 + <mediaobject><imageobject><imagedata 6.127 + fileref="tour-merge-merge"/></imageobject><textobject><phrase>XXX 6.128 + add text</phrase></textobject> 6.129 + <caption><para>Working directory and repository during 6.130 + merge, and following commit</para></caption> 6.131 + </mediaobject> 6.132 + </informalfigure> 6.133 + 6.134 + <para>This updates the working directory so that it contains 6.135 + changes from <emphasis>both</emphasis> heads, which is 6.136 + reflected in both the output of <command role="hg-cmd">hg 6.137 + parents</command> and the contents of 6.138 + <filename>hello.c</filename>.</para> 6.139 + 6.140 + &interaction.tour.merge.parents; 6.141 + 6.142 + </sect2> 6.143 + <sect2> 6.144 + <title>Committing the results of the merge</title> 6.145 + 6.146 + <para>Whenever we've done a merge, <command role="hg-cmd">hg 6.147 + parents</command> will display two parents until we <command 6.148 + role="hg-cmd">hg commit</command> the results of the 6.149 + merge.</para> 6.150 + 6.151 + &interaction.tour.merge.commit; 6.152 + 6.153 + <para>We now have a new tip revision; notice that it has 6.154 + <emphasis>both</emphasis> of our former heads as its parents. 6.155 + These are the same revisions that were previously displayed by 6.156 + <command role="hg-cmd">hg parents</command>.</para> 6.157 + 6.158 + &interaction.tour.merge.tip; 6.159 + 6.160 + <para>In figure <xref 6.161 + linkend="fig:tour-merge:merge"/>, you can see a 6.162 + representation of what happens to the working directory during 6.163 + the merge, and how this affects the repository when the commit 6.164 + happens. During the merge, the working directory has two 6.165 + parent changesets, and these become the parents of the new 6.166 + changeset.</para> 6.167 + 6.168 + </sect2> 6.169 + </sect1> 6.170 + <sect1> 6.171 + <title>Merging conflicting changes</title> 6.172 + 6.173 + <para>Most merges are simple affairs, but sometimes you'll find 6.174 + yourself merging changes where each modifies the same portions 6.175 + of the same files. Unless both modifications are identical, 6.176 + this results in a <emphasis>conflict</emphasis>, where you have 6.177 + to decide how to reconcile the different changes into something 6.178 + coherent.</para> 6.179 + 6.180 + <informalfigure> 6.181 + 6.182 + <mediaobject id="fig:tour-merge:conflict"> 6.183 + <imageobject><imagedata fileref="tour-merge-conflict"/></imageobject> 6.184 + <textobject><phrase>XXX add text</phrase></textobject> 6.185 + <caption><para>Conflicting changes to a 6.186 + document</para></caption> </mediaobject> 6.187 + </informalfigure> 6.188 + 6.189 + <para>Figure <xref linkend="fig:tour-merge:conflict"/> illustrates 6.190 + an instance of two conflicting changes to a document. We 6.191 + started with a single version of the file; then we made some 6.192 + changes; while someone else made different changes to the same 6.193 + text. Our task in resolving the conflicting changes is to 6.194 + decide what the file should look like.</para> 6.195 + 6.196 + <para>Mercurial doesn't have a built-in facility for handling 6.197 + conflicts. Instead, it runs an external program called 6.198 + <command>hgmerge</command>. This is a shell script that is 6.199 + bundled with Mercurial; you can change it to behave however you 6.200 + please. What it does by default is try to find one of several 6.201 + different merging tools that are likely to be installed on your 6.202 + system. It first tries a few fully automatic merging tools; if 6.203 + these don't succeed (because the resolution process requires 6.204 + human guidance) or aren't present, the script tries a few 6.205 + different graphical merging tools.</para> 6.206 + 6.207 + <para>It's also possible to get Mercurial to run another program 6.208 + or script instead of <command>hgmerge</command>, by setting the 6.209 + <envar>HGMERGE</envar> environment variable to the name of your 6.210 + preferred program.</para> 6.211 + 6.212 + <sect2> 6.213 + <title>Using a graphical merge tool</title> 6.214 + 6.215 + <para>My preferred graphical merge tool is 6.216 + <command>kdiff3</command>, which I'll use to describe the 6.217 + features that are common to graphical file merging tools. You 6.218 + can see a screenshot of <command>kdiff3</command> in action in 6.219 + figure <xref linkend="fig:tour-merge:kdiff3"/>. The kind of 6.220 + merge it is performing is called a <emphasis>three-way 6.221 + merge</emphasis>, because there are three different versions 6.222 + of the file of interest to us. The tool thus splits the upper 6.223 + portion of the window into three panes:</para> 6.224 + <itemizedlist> 6.225 + <listitem><para>At the left is the <emphasis>base</emphasis> 6.226 + version of the file, i.e. the most recent version from 6.227 + which the two versions we're trying to merge are 6.228 + descended.</para> 6.229 + </listitem> 6.230 + <listitem><para>In the middle is <quote>our</quote> version of 6.231 + the file, with the contents that we modified.</para> 6.232 + </listitem> 6.233 + <listitem><para>On the right is <quote>their</quote> version 6.234 + of the file, the one that from the changeset that we're 6.235 + trying to merge with.</para> 6.236 + </listitem></itemizedlist> 6.237 + <para>In the pane below these is the current 6.238 + <emphasis>result</emphasis> of the merge. Our task is to 6.239 + replace all of the red text, which indicates unresolved 6.240 + conflicts, with some sensible merger of the 6.241 + <quote>ours</quote> and <quote>theirs</quote> versions of the 6.242 + file.</para> 6.243 + 6.244 + <para>All four of these panes are <emphasis>locked 6.245 + together</emphasis>; if we scroll vertically or horizontally 6.246 + in any of them, the others are updated to display the 6.247 + corresponding sections of their respective files.</para> 6.248 + 6.249 + <informalfigure id="fig:tour-merge:kdiff3"> 6.250 + <mediaobject><imageobject><imagedata 6.251 + fileref="kdiff3"/></imageobject><textobject><phrase>XXX 6.252 + add text</phrase></textobject> 6.253 + <caption><para>Using <command>kdiff3</command> to merge 6.254 + versions of a file</para></caption> 6.255 + </mediaobject> 6.256 + </informalfigure> 6.257 + 6.258 + <para>For each conflicting portion of the file, we can choose to 6.259 + resolve the conflict using some combination of text from the 6.260 + base version, ours, or theirs. We can also manually edit the 6.261 + merged file at any time, in case we need to make further 6.262 + modifications.</para> 6.263 + 6.264 + <para>There are <emphasis>many</emphasis> file merging tools 6.265 + available, too many to cover here. They vary in which 6.266 + platforms they are available for, and in their particular 6.267 + strengths and weaknesses. Most are tuned for merging files 6.268 + containing plain text, while a few are aimed at specialised 6.269 + file formats (generally XML).</para> 6.270 + 6.271 + </sect2> 6.272 + <sect2> 6.273 + <title>A worked example</title> 6.274 + 6.275 + <para>In this example, we will reproduce the file modification 6.276 + history of figure <xref linkend="fig:tour-merge:conflict"/> 6.277 + above. Let's begin by creating a repository with a base 6.278 + version of our document.</para> 6.279 + 6.280 + &interaction.tour-merge-conflict.wife; 6.281 + 6.282 + <para>We'll clone the repository and make a change to the 6.283 + file.</para> 6.284 + 6.285 + &interaction.tour-merge-conflict.cousin; 6.286 + 6.287 + <para>And another clone, to simulate someone else making a 6.288 + change to the file. (This hints at the idea that it's not all 6.289 + that unusual to merge with yourself when you isolate tasks in 6.290 + separate repositories, and indeed to find and resolve 6.291 + conflicts while doing so.)</para> 6.292 + 6.293 + &interaction.tour-merge-conflict.son; 6.294 + 6.295 + <para>Having created two 6.296 + different versions of the file, we'll set up an environment 6.297 + suitable for running our merge.</para> 6.298 + 6.299 + &interaction.tour-merge-conflict.pull; 6.300 + 6.301 + <para>In this example, I won't use Mercurial's normal 6.302 + <command>hgmerge</command> program to do the merge, because it 6.303 + would drop my nice automated example-running tool into a 6.304 + graphical user interface. Instead, I'll set 6.305 + <envar>HGMERGE</envar> to tell Mercurial to use the 6.306 + non-interactive <command>merge</command> command. This is 6.307 + bundled with many Unix-like systems. If you're following this 6.308 + example on your computer, don't bother setting 6.309 + <envar>HGMERGE</envar>.</para> 6.310 + 6.311 + <para><emphasis role="bold">XXX FIX THIS 6.312 + EXAMPLE.</emphasis></para> 6.313 + 6.314 + &interaction.tour-merge-conflict.merge; 6.315 + 6.316 + <para>Because <command>merge</command> can't resolve the 6.317 + conflicting changes, it leaves <emphasis>merge 6.318 + markers</emphasis> inside the file that has conflicts, 6.319 + indicating which lines have conflicts, and whether they came 6.320 + from our version of the file or theirs.</para> 6.321 + 6.322 + <para>Mercurial can tell from the way <command>merge</command> 6.323 + exits that it wasn't able to merge successfully, so it tells 6.324 + us what commands we'll need to run if we want to redo the 6.325 + merging operation. This could be useful if, for example, we 6.326 + were running a graphical merge tool and quit because we were 6.327 + confused or realised we had made a mistake.</para> 6.328 + 6.329 + <para>If automatic or manual merges fail, there's nothing to 6.330 + prevent us from <quote>fixing up</quote> the affected files 6.331 + ourselves, and committing the results of our merge:</para> 6.332 + 6.333 + &interaction.tour-merge-conflict.commit; 6.334 + 6.335 + </sect2> 6.336 + </sect1> 6.337 + <sect1 id="sec:tour-merge:fetch"> 6.338 + <title>Simplifying the pull-merge-commit sequence</title> 6.339 + 6.340 + <para>The process of merging changes as outlined above is 6.341 + straightforward, but requires running three commands in 6.342 + sequence.</para> 6.343 + <programlisting>hg pull 6.344 +hg merge 6.345 +hg commit -m 'Merged remote changes'</programlisting> 6.346 + <para>In the case of the final commit, you also need to enter a 6.347 + commit message, which is almost always going to be a piece of 6.348 + uninteresting <quote>boilerplate</quote> text.</para> 6.349 + 6.350 + <para>It would be nice to reduce the number of steps needed, if 6.351 + this were possible. Indeed, Mercurial is distributed with an 6.352 + extension called <literal role="hg-ext">fetch</literal> that 6.353 + does just this.</para> 6.354 + 6.355 + <para>Mercurial provides a flexible extension mechanism that lets 6.356 + people extend its functionality, while keeping the core of 6.357 + Mercurial small and easy to deal with. Some extensions add new 6.358 + commands that you can use from the command line, while others 6.359 + work <quote>behind the scenes,</quote> for example adding 6.360 + capabilities to the server.</para> 6.361 + 6.362 + <para>The <literal role="hg-ext">fetch</literal> extension adds a 6.363 + new command called, not surprisingly, <command role="hg-cmd">hg 6.364 + fetch</command>. This extension acts as a combination of 6.365 + <command role="hg-cmd">hg pull</command>, <command 6.366 + role="hg-cmd">hg update</command> and <command 6.367 + role="hg-cmd">hg merge</command>. It begins by pulling 6.368 + changes from another repository into the current repository. If 6.369 + it finds that the changes added a new head to the repository, it 6.370 + begins a merge, then commits the result of the merge with an 6.371 + automatically-generated commit message. If no new heads were 6.372 + added, it updates the working directory to the new tip 6.373 + changeset.</para> 6.374 + 6.375 + <para>Enabling the <literal role="hg-ext">fetch</literal> 6.376 + extension is easy. Edit your <filename 6.377 + role="special">.hgrc</filename>, and either go to the <literal 6.378 + role="rc-extensions">extensions</literal> section or create an 6.379 + <literal role="rc-extensions">extensions</literal> section. Then 6.380 + add a line that simply reads <quote><literal>fetch 6.381 + </literal></quote>.</para> 6.382 + <programlisting>[extensions] 6.383 +fetch =</programlisting> 6.384 + <para>(Normally, on the right-hand side of the 6.385 + <quote><literal>=</literal></quote> would appear the location of 6.386 + the extension, but since the <literal 6.387 + role="hg-ext">fetch</literal> extension is in the standard 6.388 + distribution, Mercurial knows where to search for it.)</para> 6.389 + 6.390 + </sect1> 6.391 +</chapter> 6.392 + 6.393 +<!-- 6.394 +local variables: 6.395 +sgml-parent-document: ("00book.xml" "book" "chapter") 6.396 +end: 6.397 +-->
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/en/ch03-concepts.xml Thu Mar 19 20:54:12 2009 -0700 7.3 @@ -0,0 +1,726 @@ 7.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 7.5 + 7.6 +<chapter id="chap:concepts"> 7.7 + <?dbhtml filename="behind-the-scenes.html"?> 7.8 + <title>Behind the scenes</title> 7.9 + 7.10 + <para>Unlike many revision control systems, the concepts upon which 7.11 + Mercurial is built are simple enough that it's easy to understand 7.12 + how the software really works. Knowing this certainly isn't 7.13 + necessary, but I find it useful to have a <quote>mental 7.14 + model</quote> of what's going on.</para> 7.15 + 7.16 + <para>This understanding gives me confidence that Mercurial has been 7.17 + carefully designed to be both <emphasis>safe</emphasis> and 7.18 + <emphasis>efficient</emphasis>. And just as importantly, if it's 7.19 + easy for me to retain a good idea of what the software is doing 7.20 + when I perform a revision control task, I'm less likely to be 7.21 + surprised by its behaviour.</para> 7.22 + 7.23 + <para>In this chapter, we'll initially cover the core concepts 7.24 + behind Mercurial's design, then continue to discuss some of the 7.25 + interesting details of its implementation.</para> 7.26 + 7.27 + <sect1> 7.28 + <title>Mercurial's historical record</title> 7.29 + 7.30 + <sect2> 7.31 + <title>Tracking the history of a single file</title> 7.32 + 7.33 + <para>When Mercurial tracks modifications to a file, it stores 7.34 + the history of that file in a metadata object called a 7.35 + <emphasis>filelog</emphasis>. Each entry in the filelog 7.36 + contains enough information to reconstruct one revision of the 7.37 + file that is being tracked. Filelogs are stored as files in 7.38 + the <filename role="special" 7.39 + class="directory">.hg/store/data</filename> directory. A 7.40 + filelog contains two kinds of information: revision data, and 7.41 + an index to help Mercurial to find a revision 7.42 + efficiently.</para> 7.43 + 7.44 + <para>A file that is large, or has a lot of history, has its 7.45 + filelog stored in separate data 7.46 + (<quote><literal>.d</literal></quote> suffix) and index 7.47 + (<quote><literal>.i</literal></quote> suffix) files. For 7.48 + small files without much history, the revision data and index 7.49 + are combined in a single <quote><literal>.i</literal></quote> 7.50 + file. The correspondence between a file in the working 7.51 + directory and the filelog that tracks its history in the 7.52 + repository is illustrated in figure <xref 7.53 + linkend="fig:concepts:filelog"/>.</para> 7.54 + 7.55 + <informalfigure id="fig:concepts:filelog"> 7.56 + <mediaobject><imageobject><imagedata 7.57 + fileref="filelog"/></imageobject><textobject><phrase>XXX 7.58 + add text</phrase></textobject> 7.59 + <caption><para>Relationships between files in working 7.60 + directory and filelogs in 7.61 + repository</para></caption></mediaobject> 7.62 + </informalfigure> 7.63 + 7.64 + </sect2> 7.65 + <sect2> 7.66 + <title>Managing tracked files</title> 7.67 + 7.68 + <para>Mercurial uses a structure called a 7.69 + <emphasis>manifest</emphasis> to collect together information 7.70 + about the files that it tracks. Each entry in the manifest 7.71 + contains information about the files present in a single 7.72 + changeset. An entry records which files are present in the 7.73 + changeset, the revision of each file, and a few other pieces 7.74 + of file metadata.</para> 7.75 + 7.76 + </sect2> 7.77 + <sect2> 7.78 + <title>Recording changeset information</title> 7.79 + 7.80 + <para>The <emphasis>changelog</emphasis> contains information 7.81 + about each changeset. Each revision records who committed a 7.82 + change, the changeset comment, other pieces of 7.83 + changeset-related information, and the revision of the 7.84 + manifest to use.</para> 7.85 + 7.86 + </sect2> 7.87 + <sect2> 7.88 + <title>Relationships between revisions</title> 7.89 + 7.90 + <para>Within a changelog, a manifest, or a filelog, each 7.91 + revision stores a pointer to its immediate parent (or to its 7.92 + two parents, if it's a merge revision). As I mentioned above, 7.93 + there are also relationships between revisions 7.94 + <emphasis>across</emphasis> these structures, and they are 7.95 + hierarchical in nature.</para> 7.96 + 7.97 + <para>For every changeset in a repository, there is exactly one 7.98 + revision stored in the changelog. Each revision of the 7.99 + changelog contains a pointer to a single revision of the 7.100 + manifest. A revision of the manifest stores a pointer to a 7.101 + single revision of each filelog tracked when that changeset 7.102 + was created. These relationships are illustrated in figure 7.103 + <xref linkend="fig:concepts:metadata"/>.</para> 7.104 + 7.105 + <informalfigure id="fig:concepts:metadata"> 7.106 + <mediaobject><imageobject><imagedata 7.107 + fileref="metadata"/></imageobject><textobject><phrase>XXX 7.108 + add text</phrase></textobject><caption><para>Metadata 7.109 + relationships</para></caption> 7.110 + </mediaobject> 7.111 + </informalfigure> 7.112 + 7.113 + <para>As the illustration shows, there is 7.114 + <emphasis>not</emphasis> a <quote>one to one</quote> 7.115 + relationship between revisions in the changelog, manifest, or 7.116 + filelog. If the manifest hasn't changed between two 7.117 + changesets, the changelog entries for those changesets will 7.118 + point to the same revision of the manifest. If a file that 7.119 + Mercurial tracks hasn't changed between two changesets, the 7.120 + entry for that file in the two revisions of the manifest will 7.121 + point to the same revision of its filelog.</para> 7.122 + 7.123 + </sect2> 7.124 + </sect1> 7.125 + <sect1> 7.126 + <title>Safe, efficient storage</title> 7.127 + 7.128 + <para>The underpinnings of changelogs, manifests, and filelogs are 7.129 + provided by a single structure called the 7.130 + <emphasis>revlog</emphasis>.</para> 7.131 + 7.132 + <sect2> 7.133 + <title>Efficient storage</title> 7.134 + 7.135 + <para>The revlog provides efficient storage of revisions using a 7.136 + <emphasis>delta</emphasis> mechanism. Instead of storing a 7.137 + complete copy of a file for each revision, it stores the 7.138 + changes needed to transform an older revision into the new 7.139 + revision. For many kinds of file data, these deltas are 7.140 + typically a fraction of a percent of the size of a full copy 7.141 + of a file.</para> 7.142 + 7.143 + <para>Some obsolete revision control systems can only work with 7.144 + deltas of text files. They must either store binary files as 7.145 + complete snapshots or encoded into a text representation, both 7.146 + of which are wasteful approaches. Mercurial can efficiently 7.147 + handle deltas of files with arbitrary binary contents; it 7.148 + doesn't need to treat text as special.</para> 7.149 + 7.150 + </sect2> 7.151 + <sect2 id="sec:concepts:txn"> 7.152 + <title>Safe operation</title> 7.153 + 7.154 + <para>Mercurial only ever <emphasis>appends</emphasis> data to 7.155 + the end of a revlog file. It never modifies a section of a 7.156 + file after it has written it. This is both more robust and 7.157 + efficient than schemes that need to modify or rewrite 7.158 + data.</para> 7.159 + 7.160 + <para>In addition, Mercurial treats every write as part of a 7.161 + <emphasis>transaction</emphasis> that can span a number of 7.162 + files. A transaction is <emphasis>atomic</emphasis>: either 7.163 + the entire transaction succeeds and its effects are all 7.164 + visible to readers in one go, or the whole thing is undone. 7.165 + This guarantee of atomicity means that if you're running two 7.166 + copies of Mercurial, where one is reading data and one is 7.167 + writing it, the reader will never see a partially written 7.168 + result that might confuse it.</para> 7.169 + 7.170 + <para>The fact that Mercurial only appends to files makes it 7.171 + easier to provide this transactional guarantee. The easier it 7.172 + is to do stuff like this, the more confident you should be 7.173 + that it's done correctly.</para> 7.174 + 7.175 + </sect2> 7.176 + <sect2> 7.177 + <title>Fast retrieval</title> 7.178 + 7.179 + <para>Mercurial cleverly avoids a pitfall common to all earlier 7.180 + revision control systems: the problem of <emphasis>inefficient 7.181 + retrieval</emphasis>. Most revision control systems store 7.182 + the contents of a revision as an incremental series of 7.183 + modifications against a <quote>snapshot</quote>. To 7.184 + reconstruct a specific revision, you must first read the 7.185 + snapshot, and then every one of the revisions between the 7.186 + snapshot and your target revision. The more history that a 7.187 + file accumulates, the more revisions you must read, hence the 7.188 + longer it takes to reconstruct a particular revision.</para> 7.189 + 7.190 + <informalfigure id="fig:concepts:snapshot"> 7.191 + <mediaobject><imageobject><imagedata 7.192 + fileref="snapshot"/></imageobject><textobject><phrase>XXX 7.193 + add text</phrase></textobject><caption><para>Snapshot of 7.194 + a revlog, with incremental 7.195 + deltas</para></caption></mediaobject> 7.196 + </informalfigure> 7.197 + 7.198 + <para>The innovation that Mercurial applies to this problem is 7.199 + simple but effective. Once the cumulative amount of delta 7.200 + information stored since the last snapshot exceeds a fixed 7.201 + threshold, it stores a new snapshot (compressed, of course), 7.202 + instead of another delta. This makes it possible to 7.203 + reconstruct <emphasis>any</emphasis> revision of a file 7.204 + quickly. This approach works so well that it has since been 7.205 + copied by several other revision control systems.</para> 7.206 + 7.207 + <para>Figure <xref linkend="fig:concepts:snapshot"/> illustrates 7.208 + the idea. In an entry in a revlog's index file, Mercurial 7.209 + stores the range of entries from the data file that it must 7.210 + read to reconstruct a particular revision.</para> 7.211 + 7.212 + <sect3> 7.213 + <title>Aside: the influence of video compression</title> 7.214 + 7.215 + <para>If you're familiar with video compression or have ever 7.216 + watched a TV feed through a digital cable or satellite 7.217 + service, you may know that most video compression schemes 7.218 + store each frame of video as a delta against its predecessor 7.219 + frame. In addition, these schemes use <quote>lossy</quote> 7.220 + compression techniques to increase the compression ratio, so 7.221 + visual errors accumulate over the course of a number of 7.222 + inter-frame deltas.</para> 7.223 + 7.224 + <para>Because it's possible for a video stream to <quote>drop 7.225 + out</quote> occasionally due to signal glitches, and to 7.226 + limit the accumulation of artefacts introduced by the lossy 7.227 + compression process, video encoders periodically insert a 7.228 + complete frame (called a <quote>key frame</quote>) into the 7.229 + video stream; the next delta is generated against that 7.230 + frame. This means that if the video signal gets 7.231 + interrupted, it will resume once the next key frame is 7.232 + received. Also, the accumulation of encoding errors 7.233 + restarts anew with each key frame.</para> 7.234 + 7.235 + </sect3> 7.236 + </sect2> 7.237 + <sect2> 7.238 + <title>Identification and strong integrity</title> 7.239 + 7.240 + <para>Along with delta or snapshot information, a revlog entry 7.241 + contains a cryptographic hash of the data that it represents. 7.242 + This makes it difficult to forge the contents of a revision, 7.243 + and easy to detect accidental corruption.</para> 7.244 + 7.245 + <para>Hashes provide more than a mere check against corruption; 7.246 + they are used as the identifiers for revisions. The changeset 7.247 + identification hashes that you see as an end user are from 7.248 + revisions of the changelog. Although filelogs and the 7.249 + manifest also use hashes, Mercurial only uses these behind the 7.250 + scenes.</para> 7.251 + 7.252 + <para>Mercurial verifies that hashes are correct when it 7.253 + retrieves file revisions and when it pulls changes from 7.254 + another repository. If it encounters an integrity problem, it 7.255 + will complain and stop whatever it's doing.</para> 7.256 + 7.257 + <para>In addition to the effect it has on retrieval efficiency, 7.258 + Mercurial's use of periodic snapshots makes it more robust 7.259 + against partial data corruption. If a revlog becomes partly 7.260 + corrupted due to a hardware error or system bug, it's often 7.261 + possible to reconstruct some or most revisions from the 7.262 + uncorrupted sections of the revlog, both before and after the 7.263 + corrupted section. This would not be possible with a 7.264 + delta-only storage model.</para> 7.265 + 7.266 + </sect2> 7.267 + </sect1> 7.268 + <sect1> 7.269 + <title>Revision history, branching, and merging</title> 7.270 + 7.271 + <para>Every entry in a Mercurial revlog knows the identity of its 7.272 + immediate ancestor revision, usually referred to as its 7.273 + <emphasis>parent</emphasis>. In fact, a revision contains room 7.274 + for not one parent, but two. Mercurial uses a special hash, 7.275 + called the <quote>null ID</quote>, to represent the idea 7.276 + <quote>there is no parent here</quote>. This hash is simply a 7.277 + string of zeroes.</para> 7.278 + 7.279 + <para>In figure <xref linkend="fig:concepts:revlog"/>, you can see 7.280 + an example of the conceptual structure of a revlog. Filelogs, 7.281 + manifests, and changelogs all have this same structure; they 7.282 + differ only in the kind of data stored in each delta or 7.283 + snapshot.</para> 7.284 + 7.285 + <para>The first revision in a revlog (at the bottom of the image) 7.286 + has the null ID in both of its parent slots. For a 7.287 + <quote>normal</quote> revision, its first parent slot contains 7.288 + the ID of its parent revision, and its second contains the null 7.289 + ID, indicating that the revision has only one real parent. Any 7.290 + two revisions that have the same parent ID are branches. A 7.291 + revision that represents a merge between branches has two normal 7.292 + revision IDs in its parent slots.</para> 7.293 + 7.294 + <informalfigure id="fig:concepts:revlog"> 7.295 + <mediaobject><imageobject><imagedata 7.296 + fileref="revlog"/></imageobject><textobject><phrase>XXX 7.297 + add text</phrase></textobject></mediaobject> 7.298 + </informalfigure> 7.299 + 7.300 + </sect1> 7.301 + <sect1> 7.302 + <title>The working directory</title> 7.303 + 7.304 + <para>In the working directory, Mercurial stores a snapshot of the 7.305 + files from the repository as of a particular changeset.</para> 7.306 + 7.307 + <para>The working directory <quote>knows</quote> which changeset 7.308 + it contains. When you update the working directory to contain a 7.309 + particular changeset, Mercurial looks up the appropriate 7.310 + revision of the manifest to find out which files it was tracking 7.311 + at the time that changeset was committed, and which revision of 7.312 + each file was then current. It then recreates a copy of each of 7.313 + those files, with the same contents it had when the changeset 7.314 + was committed.</para> 7.315 + 7.316 + <para>The <emphasis>dirstate</emphasis> contains Mercurial's 7.317 + knowledge of the working directory. This details which 7.318 + changeset the working directory is updated to, and all of the 7.319 + files that Mercurial is tracking in the working 7.320 + directory.</para> 7.321 + 7.322 + <para>Just as a revision of a revlog has room for two parents, so 7.323 + that it can represent either a normal revision (with one parent) 7.324 + or a merge of two earlier revisions, the dirstate has slots for 7.325 + two parents. When you use the <command role="hg-cmd">hg 7.326 + update</command> command, the changeset that you update to is 7.327 + stored in the <quote>first parent</quote> slot, and the null ID 7.328 + in the second. When you <command role="hg-cmd">hg 7.329 + merge</command> with another changeset, the first parent 7.330 + remains unchanged, and the second parent is filled in with the 7.331 + changeset you're merging with. The <command role="hg-cmd">hg 7.332 + parents</command> command tells you what the parents of the 7.333 + dirstate are.</para> 7.334 + 7.335 + <sect2> 7.336 + <title>What happens when you commit</title> 7.337 + 7.338 + <para>The dirstate stores parent information for more than just 7.339 + book-keeping purposes. Mercurial uses the parents of the 7.340 + dirstate as <emphasis>the parents of a new 7.341 + changeset</emphasis> when you perform a commit.</para> 7.342 + 7.343 + <informalfigure id="fig:concepts:wdir"> 7.344 + <mediaobject><imageobject><imagedata 7.345 + fileref="wdir"/></imageobject><textobject><phrase>XXX 7.346 + add text</phrase></textobject><caption><para>The working 7.347 + directory can have two 7.348 + parents</para></caption></mediaobject> 7.349 + </informalfigure> 7.350 + 7.351 + <para>Figure <xref linkend="fig:concepts:wdir"/> shows the 7.352 + normal state of the working directory, where it has a single 7.353 + changeset as parent. That changeset is the 7.354 + <emphasis>tip</emphasis>, the newest changeset in the 7.355 + repository that has no children.</para> 7.356 + 7.357 + <informalfigure id="fig:concepts:wdir-after-commit"> 7.358 + <mediaobject><imageobject><imagedata 7.359 + fileref="wdir-after-commit"/></imageobject><textobject><phrase>XXX 7.360 + add text</phrase></textobject><caption><para>The working 7.361 + directory gains new parents after a 7.362 + commit</para></caption></mediaobject> 7.363 + </informalfigure> 7.364 + 7.365 + <para>It's useful to think of the working directory as 7.366 + <quote>the changeset I'm about to commit</quote>. Any files 7.367 + that you tell Mercurial that you've added, removed, renamed, 7.368 + or copied will be reflected in that changeset, as will 7.369 + modifications to any files that Mercurial is already tracking; 7.370 + the new changeset will have the parents of the working 7.371 + directory as its parents.</para> 7.372 + 7.373 + <para>After a commit, Mercurial will update the parents of the 7.374 + working directory, so that the first parent is the ID of the 7.375 + new changeset, and the second is the null ID. This is shown 7.376 + in figure <xref linkend="fig:concepts:wdir-after-commit"/>. 7.377 + Mercurial 7.378 + doesn't touch any of the files in the working directory when 7.379 + you commit; it just modifies the dirstate to note its new 7.380 + parents.</para> 7.381 + 7.382 + </sect2> 7.383 + <sect2> 7.384 + <title>Creating a new head</title> 7.385 + 7.386 + <para>It's perfectly normal to update the working directory to a 7.387 + changeset other than the current tip. For example, you might 7.388 + want to know what your project looked like last Tuesday, or 7.389 + you could be looking through changesets to see which one 7.390 + introduced a bug. In cases like this, the natural thing to do 7.391 + is update the working directory to the changeset you're 7.392 + interested in, and then examine the files in the working 7.393 + directory directly to see their contents as they were when you 7.394 + committed that changeset. The effect of this is shown in 7.395 + figure <xref linkend="fig:concepts:wdir-pre-branch"/>.</para> 7.396 + 7.397 + <informalfigure id="fig:concepts:wdir-pre-branch"> 7.398 + <mediaobject><imageobject><imagedata 7.399 + fileref="wdir-pre-branch"/></imageobject><textobject><phrase>XXX 7.400 + add text</phrase></textobject><caption><para>The working 7.401 + directory, updated to an older 7.402 + changeset</para></caption></mediaobject> 7.403 + </informalfigure> 7.404 + 7.405 + <para>Having updated the working directory to an older 7.406 + changeset, what happens if you make some changes, and then 7.407 + commit? Mercurial behaves in the same way as I outlined 7.408 + above. The parents of the working directory become the 7.409 + parents of the new changeset. This new changeset has no 7.410 + children, so it becomes the new tip. And the repository now 7.411 + contains two changesets that have no children; we call these 7.412 + <emphasis>heads</emphasis>. You can see the structure that 7.413 + this creates in figure <xref 7.414 + linkend="fig:concepts:wdir-branch"/>.</para> 7.415 + 7.416 + <informalfigure id="fig:concepts:wdir-branch"> 7.417 + <mediaobject><imageobject><imagedata 7.418 + fileref="wdir-branch"/></imageobject><textobject><phrase>XXX 7.419 + add text</phrase></textobject><caption><para>After a 7.420 + commit made while synced to an older 7.421 + changeset</para></caption></mediaobject> 7.422 + </informalfigure> 7.423 + 7.424 + <note> 7.425 + <para> If you're new to Mercurial, you should keep in mind a 7.426 + common <quote>error</quote>, which is to use the <command 7.427 + role="hg-cmd">hg pull</command> command without any 7.428 + options. By default, the <command role="hg-cmd">hg 7.429 + pull</command> command <emphasis>does not</emphasis> 7.430 + update the working directory, so you'll bring new changesets 7.431 + into your repository, but the working directory will stay 7.432 + synced at the same changeset as before the pull. If you 7.433 + make some changes and commit afterwards, you'll thus create 7.434 + a new head, because your working directory isn't synced to 7.435 + whatever the current tip is.</para> 7.436 + 7.437 + <para> I put the word <quote>error</quote> in quotes because 7.438 + all that you need to do to rectify this situation is 7.439 + <command role="hg-cmd">hg merge</command>, then <command 7.440 + role="hg-cmd">hg commit</command>. In other words, this 7.441 + almost never has negative consequences; it just surprises 7.442 + people. I'll discuss other ways to avoid this behaviour, 7.443 + and why Mercurial behaves in this initially surprising way, 7.444 + later on.</para> 7.445 + </note> 7.446 + 7.447 + </sect2> 7.448 + <sect2> 7.449 + <title>Merging heads</title> 7.450 + 7.451 + <para>When you run the <command role="hg-cmd">hg merge</command> 7.452 + command, Mercurial leaves the first parent of the working 7.453 + directory unchanged, and sets the second parent to the 7.454 + changeset you're merging with, as shown in figure <xref 7.455 + linkend="fig:concepts:wdir-merge"/>.</para> 7.456 + 7.457 + <informalfigure id="fig:concepts:wdir-merge"> 7.458 + <mediaobject><imageobject><imagedata 7.459 + fileref="wdir-merge"/></imageobject><textobject><phrase>XXX 7.460 + add text</phrase></textobject><caption><para>Merging two 7.461 + heads</para></caption></mediaobject> 7.462 + </informalfigure> 7.463 + 7.464 + <para>Mercurial also has to modify the working directory, to 7.465 + merge the files managed in the two changesets. Simplified a 7.466 + little, the merging process goes like this, for every file in 7.467 + the manifests of both changesets.</para> 7.468 + <itemizedlist> 7.469 + <listitem><para>If neither changeset has modified a file, do 7.470 + nothing with that file.</para> 7.471 + </listitem> 7.472 + <listitem><para>If one changeset has modified a file, and the 7.473 + other hasn't, create the modified copy of the file in the 7.474 + working directory.</para> 7.475 + </listitem> 7.476 + <listitem><para>If one changeset has removed a file, and the 7.477 + other hasn't (or has also deleted it), delete the file 7.478 + from the working directory.</para> 7.479 + </listitem> 7.480 + <listitem><para>If one changeset has removed a file, but the 7.481 + other has modified the file, ask the user what to do: keep 7.482 + the modified file, or remove it?</para> 7.483 + </listitem> 7.484 + <listitem><para>If both changesets have modified a file, 7.485 + invoke an external merge program to choose the new 7.486 + contents for the merged file. This may require input from 7.487 + the user.</para> 7.488 + </listitem> 7.489 + <listitem><para>If one changeset has modified a file, and the 7.490 + other has renamed or copied the file, make sure that the 7.491 + changes follow the new name of the file.</para> 7.492 + </listitem></itemizedlist> 7.493 + <para>There are more details&emdash;merging has plenty of corner 7.494 + cases&emdash;but these are the most common choices that are 7.495 + involved in a merge. As you can see, most cases are 7.496 + completely automatic, and indeed most merges finish 7.497 + automatically, without requiring your input to resolve any 7.498 + conflicts.</para> 7.499 + 7.500 + <para>When you're thinking about what happens when you commit 7.501 + after a merge, once again the working directory is <quote>the 7.502 + changeset I'm about to commit</quote>. After the <command 7.503 + role="hg-cmd">hg merge</command> command completes, the 7.504 + working directory has two parents; these will become the 7.505 + parents of the new changeset.</para> 7.506 + 7.507 + <para>Mercurial lets you perform multiple merges, but you must 7.508 + commit the results of each individual merge as you go. This 7.509 + is necessary because Mercurial only tracks two parents for 7.510 + both revisions and the working directory. While it would be 7.511 + technically possible to merge multiple changesets at once, the 7.512 + prospect of user confusion and making a terrible mess of a 7.513 + merge immediately becomes overwhelming.</para> 7.514 + 7.515 + </sect2> 7.516 + </sect1> 7.517 + <sect1> 7.518 + <title>Other interesting design features</title> 7.519 + 7.520 + <para>In the sections above, I've tried to highlight some of the 7.521 + most important aspects of Mercurial's design, to illustrate that 7.522 + it pays careful attention to reliability and performance. 7.523 + However, the attention to detail doesn't stop there. There are 7.524 + a number of other aspects of Mercurial's construction that I 7.525 + personally find interesting. I'll detail a few of them here, 7.526 + separate from the <quote>big ticket</quote> items above, so that 7.527 + if you're interested, you can gain a better idea of the amount 7.528 + of thinking that goes into a well-designed system.</para> 7.529 + 7.530 + <sect2> 7.531 + <title>Clever compression</title> 7.532 + 7.533 + <para>When appropriate, Mercurial will store both snapshots and 7.534 + deltas in compressed form. It does this by always 7.535 + <emphasis>trying to</emphasis> compress a snapshot or delta, 7.536 + but only storing the compressed version if it's smaller than 7.537 + the uncompressed version.</para> 7.538 + 7.539 + <para>This means that Mercurial does <quote>the right 7.540 + thing</quote> when storing a file whose native form is 7.541 + compressed, such as a <literal>zip</literal> archive or a JPEG 7.542 + image. When these types of files are compressed a second 7.543 + time, the resulting file is usually bigger than the 7.544 + once-compressed form, and so Mercurial will store the plain 7.545 + <literal>zip</literal> or JPEG.</para> 7.546 + 7.547 + <para>Deltas between revisions of a compressed file are usually 7.548 + larger than snapshots of the file, and Mercurial again does 7.549 + <quote>the right thing</quote> in these cases. It finds that 7.550 + such a delta exceeds the threshold at which it should store a 7.551 + complete snapshot of the file, so it stores the snapshot, 7.552 + again saving space compared to a naive delta-only 7.553 + approach.</para> 7.554 + 7.555 + <sect3> 7.556 + <title>Network recompression</title> 7.557 + 7.558 + <para>When storing revisions on disk, Mercurial uses the 7.559 + <quote>deflate</quote> compression algorithm (the same one 7.560 + used by the popular <literal>zip</literal> archive format), 7.561 + which balances good speed with a respectable compression 7.562 + ratio. However, when transmitting revision data over a 7.563 + network connection, Mercurial uncompresses the compressed 7.564 + revision data.</para> 7.565 + 7.566 + <para>If the connection is over HTTP, Mercurial recompresses 7.567 + the entire stream of data using a compression algorithm that 7.568 + gives a better compression ratio (the Burrows-Wheeler 7.569 + algorithm from the widely used <literal>bzip2</literal> 7.570 + compression package). This combination of algorithm and 7.571 + compression of the entire stream (instead of a revision at a 7.572 + time) substantially reduces the number of bytes to be 7.573 + transferred, yielding better network performance over almost 7.574 + all kinds of network.</para> 7.575 + 7.576 + <para>(If the connection is over <command>ssh</command>, 7.577 + Mercurial <emphasis>doesn't</emphasis> recompress the 7.578 + stream, because <command>ssh</command> can already do this 7.579 + itself.)</para> 7.580 + 7.581 + </sect3> 7.582 + </sect2> 7.583 + <sect2> 7.584 + <title>Read/write ordering and atomicity</title> 7.585 + 7.586 + <para>Appending to files isn't the whole story when it comes to 7.587 + guaranteeing that a reader won't see a partial write. If you 7.588 + recall figure <xref linkend="fig:concepts:metadata"/>, 7.589 + revisions in the 7.590 + changelog point to revisions in the manifest, and revisions in 7.591 + the manifest point to revisions in filelogs. This hierarchy 7.592 + is deliberate.</para> 7.593 + 7.594 + <para>A writer starts a transaction by writing filelog and 7.595 + manifest data, and doesn't write any changelog data until 7.596 + those are finished. A reader starts by reading changelog 7.597 + data, then manifest data, followed by filelog data.</para> 7.598 + 7.599 + <para>Since the writer has always finished writing filelog and 7.600 + manifest data before it writes to the changelog, a reader will 7.601 + never read a pointer to a partially written manifest revision 7.602 + from the changelog, and it will never read a pointer to a 7.603 + partially written filelog revision from the manifest.</para> 7.604 + 7.605 + </sect2> 7.606 + <sect2> 7.607 + <title>Concurrent access</title> 7.608 + 7.609 + <para>The read/write ordering and atomicity guarantees mean that 7.610 + Mercurial never needs to <emphasis>lock</emphasis> a 7.611 + repository when it's reading data, even if the repository is 7.612 + being written to while the read is occurring. This has a big 7.613 + effect on scalability; you can have an arbitrary number of 7.614 + Mercurial processes safely reading data from a repository 7.615 + safely all at once, no matter whether it's being written to or 7.616 + not.</para> 7.617 + 7.618 + <para>The lockless nature of reading means that if you're 7.619 + sharing a repository on a multi-user system, you don't need to 7.620 + grant other local users permission to 7.621 + <emphasis>write</emphasis> to your repository in order for 7.622 + them to be able to clone it or pull changes from it; they only 7.623 + need <emphasis>read</emphasis> permission. (This is 7.624 + <emphasis>not</emphasis> a common feature among revision 7.625 + control systems, so don't take it for granted! Most require 7.626 + readers to be able to lock a repository to access it safely, 7.627 + and this requires write permission on at least one directory, 7.628 + which of course makes for all kinds of nasty and annoying 7.629 + security and administrative problems.)</para> 7.630 + 7.631 + <para>Mercurial uses locks to ensure that only one process can 7.632 + write to a repository at a time (the locking mechanism is safe 7.633 + even over filesystems that are notoriously hostile to locking, 7.634 + such as NFS). If a repository is locked, a writer will wait 7.635 + for a while to retry if the repository becomes unlocked, but 7.636 + if the repository remains locked for too long, the process 7.637 + attempting to write will time out after a while. This means 7.638 + that your daily automated scripts won't get stuck forever and 7.639 + pile up if a system crashes unnoticed, for example. (Yes, the 7.640 + timeout is configurable, from zero to infinity.)</para> 7.641 + 7.642 + <sect3> 7.643 + <title>Safe dirstate access</title> 7.644 + 7.645 + <para>As with revision data, Mercurial doesn't take a lock to 7.646 + read the dirstate file; it does acquire a lock to write it. 7.647 + To avoid the possibility of reading a partially written copy 7.648 + of the dirstate file, Mercurial writes to a file with a 7.649 + unique name in the same directory as the dirstate file, then 7.650 + renames the temporary file atomically to 7.651 + <filename>dirstate</filename>. The file named 7.652 + <filename>dirstate</filename> is thus guaranteed to be 7.653 + complete, not partially written.</para> 7.654 + 7.655 + </sect3> 7.656 + </sect2> 7.657 + <sect2> 7.658 + <title>Avoiding seeks</title> 7.659 + 7.660 + <para>Critical to Mercurial's performance is the avoidance of 7.661 + seeks of the disk head, since any seek is far more expensive 7.662 + than even a comparatively large read operation.</para> 7.663 + 7.664 + <para>This is why, for example, the dirstate is stored in a 7.665 + single file. If there were a dirstate file per directory that 7.666 + Mercurial tracked, the disk would seek once per directory. 7.667 + Instead, Mercurial reads the entire single dirstate file in 7.668 + one step.</para> 7.669 + 7.670 + <para>Mercurial also uses a <quote>copy on write</quote> scheme 7.671 + when cloning a repository on local storage. Instead of 7.672 + copying every revlog file from the old repository into the new 7.673 + repository, it makes a <quote>hard link</quote>, which is a 7.674 + shorthand way to say <quote>these two names point to the same 7.675 + file</quote>. When Mercurial is about to write to one of a 7.676 + revlog's files, it checks to see if the number of names 7.677 + pointing at the file is greater than one. If it is, more than 7.678 + one repository is using the file, so Mercurial makes a new 7.679 + copy of the file that is private to this repository.</para> 7.680 + 7.681 + <para>A few revision control developers have pointed out that 7.682 + this idea of making a complete private copy of a file is not 7.683 + very efficient in its use of storage. While this is true, 7.684 + storage is cheap, and this method gives the highest 7.685 + performance while deferring most book-keeping to the operating 7.686 + system. An alternative scheme would most likely reduce 7.687 + performance and increase the complexity of the software, each 7.688 + of which is much more important to the <quote>feel</quote> of 7.689 + day-to-day use.</para> 7.690 + 7.691 + </sect2> 7.692 + <sect2> 7.693 + <title>Other contents of the dirstate</title> 7.694 + 7.695 + <para>Because Mercurial doesn't force you to tell it when you're 7.696 + modifying a file, it uses the dirstate to store some extra 7.697 + information so it can determine efficiently whether you have 7.698 + modified a file. For each file in the working directory, it 7.699 + stores the time that it last modified the file itself, and the 7.700 + size of the file at that time.</para> 7.701 + 7.702 + <para>When you explicitly <command role="hg-cmd">hg 7.703 + add</command>, <command role="hg-cmd">hg remove</command>, 7.704 + <command role="hg-cmd">hg rename</command> or <command 7.705 + role="hg-cmd">hg copy</command> files, Mercurial updates the 7.706 + dirstate so that it knows what to do with those files when you 7.707 + commit.</para> 7.708 + 7.709 + <para>When Mercurial is checking the states of files in the 7.710 + working directory, it first checks a file's modification time. 7.711 + If that has not changed, the file must not have been modified. 7.712 + If the file's size has changed, the file must have been 7.713 + modified. If the modification time has changed, but the size 7.714 + has not, only then does Mercurial need to read the actual 7.715 + contents of the file to see if they've changed. Storing these 7.716 + few extra pieces of information dramatically reduces the 7.717 + amount of data that Mercurial needs to read, which yields 7.718 + large performance improvements compared to other revision 7.719 + control systems.</para> 7.720 + 7.721 + </sect2> 7.722 + </sect1> 7.723 +</chapter> 7.724 + 7.725 +<!-- 7.726 +local variables: 7.727 +sgml-parent-document: ("00book.xml" "book" "chapter") 7.728 +end: 7.729 +-->
8.1 --- a/en/ch03-tour-merge.xml Wed Mar 18 00:08:22 2009 -0700 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,394 +0,0 @@ 8.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 8.5 - 8.6 -<chapter id="chap:tour-merge"> 8.7 - <?dbhtml filename="a-tour-of-mercurial-merging-work.html"?> 8.8 - <title>A tour of Mercurial: merging work</title> 8.9 - 8.10 - <para>We've now covered cloning a repository, making changes in a 8.11 - repository, and pulling or pushing changes from one repository 8.12 - into another. Our next step is <emphasis>merging</emphasis> 8.13 - changes from separate repositories.</para> 8.14 - 8.15 - <sect1> 8.16 - <title>Merging streams of work</title> 8.17 - 8.18 - <para>Merging is a fundamental part of working with a distributed 8.19 - revision control tool.</para> 8.20 - <itemizedlist> 8.21 - <listitem><para>Alice and Bob each have a personal copy of a 8.22 - repository for a project they're collaborating on. Alice 8.23 - fixes a bug in her repository; Bob adds a new feature in 8.24 - his. They want the shared repository to contain both the 8.25 - bug fix and the new feature.</para> 8.26 - </listitem> 8.27 - <listitem><para>I frequently work on several different tasks for 8.28 - a single project at once, each safely isolated in its own 8.29 - repository. Working this way means that I often need to 8.30 - merge one piece of my own work with another.</para> 8.31 - </listitem></itemizedlist> 8.32 - 8.33 - <para>Because merging is such a common thing to need to do, 8.34 - Mercurial makes it easy. Let's walk through the process. We'll 8.35 - begin by cloning yet another repository (see how often they 8.36 - spring up?) and making a change in it.</para> 8.37 - 8.38 - &interaction.tour.merge.clone; 8.39 - 8.40 - <para>We should now have two copies of 8.41 - <filename>hello.c</filename> with different contents. The 8.42 - histories of the two repositories have also diverged, as 8.43 - illustrated in figure <xref 8.44 - linkend="fig:tour-merge:sep-repos"/>.</para> 8.45 - 8.46 - &interaction.tour.merge.cat; 8.47 - 8.48 - <informalfigure id="fig:tour-merge:sep-repos"> 8.49 - <mediaobject> 8.50 - <imageobject><imagedata fileref="tour-merge-sep-repos"/></imageobject> 8.51 - <textobject><phrase>XXX add text</phrase></textobject> 8.52 - <caption><para>Divergent recent histories of the <filename 8.53 - class="directory">my-hello</filename> and <filename 8.54 - class="directory">my-new-hello</filename> 8.55 - repositories</para></caption> 8.56 - </mediaobject> 8.57 - </informalfigure> 8.58 - 8.59 - <para>We already know that pulling changes from our <filename 8.60 - class="directory">my-hello</filename> repository will have no 8.61 - effect on the working directory.</para> 8.62 - 8.63 - &interaction.tour.merge.pull; 8.64 - 8.65 - <para>However, the <command role="hg-cmd">hg pull</command> 8.66 - command says something about <quote>heads</quote>.</para> 8.67 - 8.68 - <sect2> 8.69 - <title>Head changesets</title> 8.70 - 8.71 - <para>A head is a change that has no descendants, or children, 8.72 - as they're also known. The tip revision is thus a head, 8.73 - because the newest revision in a repository doesn't have any 8.74 - children, but a repository can contain more than one 8.75 - head.</para> 8.76 - 8.77 - <informalfigure id="fig:tour-merge:pull"> 8.78 - <mediaobject><imageobject><imagedata 8.79 - fileref="tour-merge-pull"/></imageobject><textobject><phrase>XXX 8.80 - add text</phrase></textobject> 8.81 - <caption><para>Repository contents after pulling from 8.82 - <filename class="directory">my-hello</filename> into 8.83 - <filename 8.84 - class="directory">my-new-hello</filename></para></caption> 8.85 - </mediaobject> 8.86 - </informalfigure> 8.87 - 8.88 - <para>In figure <xref linkend="fig:tour-merge:pull"/>, you can 8.89 - see the effect of the pull from <filename 8.90 - class="directory">my-hello</filename> into <filename 8.91 - class="directory">my-new-hello</filename>. The history that 8.92 - was already present in <filename 8.93 - class="directory">my-new-hello</filename> is untouched, but 8.94 - a new revision has been added. By referring to figure <xref 8.95 - linkend="fig:tour-merge:sep-repos"/>, we can see that the 8.96 - <emphasis>changeset ID</emphasis> remains the same in the new 8.97 - repository, but the <emphasis>revision number</emphasis> has 8.98 - changed. (This, incidentally, is a fine example of why it's 8.99 - not safe to use revision numbers when discussing changesets.) 8.100 - We can view the heads in a repository using the <command 8.101 - role="hg-cmd">hg heads</command> command.</para> 8.102 - 8.103 - &interaction.tour.merge.heads; 8.104 - 8.105 - </sect2> 8.106 - <sect2> 8.107 - <title>Performing the merge</title> 8.108 - 8.109 - <para>What happens if we try to use the normal <command 8.110 - role="hg-cmd">hg update</command> command to update to the 8.111 - new tip?</para> 8.112 - 8.113 - &interaction.tour.merge.update; 8.114 - 8.115 - <para>Mercurial is telling us that the <command role="hg-cmd">hg 8.116 - update</command> command won't do a merge; it won't update 8.117 - the working directory when it thinks we might be wanting to do 8.118 - a merge, unless we force it to do so. Instead, we use the 8.119 - <command role="hg-cmd">hg merge</command> command to merge the 8.120 - two heads.</para> 8.121 - 8.122 - &interaction.tour.merge.merge; 8.123 - 8.124 - <informalfigure id="fig:tour-merge:merge"> 8.125 - 8.126 - <mediaobject><imageobject><imagedata 8.127 - fileref="tour-merge-merge"/></imageobject><textobject><phrase>XXX 8.128 - add text</phrase></textobject> 8.129 - <caption><para>Working directory and repository during 8.130 - merge, and following commit</para></caption> 8.131 - </mediaobject> 8.132 - </informalfigure> 8.133 - 8.134 - <para>This updates the working directory so that it contains 8.135 - changes from <emphasis>both</emphasis> heads, which is 8.136 - reflected in both the output of <command role="hg-cmd">hg 8.137 - parents</command> and the contents of 8.138 - <filename>hello.c</filename>.</para> 8.139 - 8.140 - &interaction.tour.merge.parents; 8.141 - 8.142 - </sect2> 8.143 - <sect2> 8.144 - <title>Committing the results of the merge</title> 8.145 - 8.146 - <para>Whenever we've done a merge, <command role="hg-cmd">hg 8.147 - parents</command> will display two parents until we <command 8.148 - role="hg-cmd">hg commit</command> the results of the 8.149 - merge.</para> 8.150 - 8.151 - &interaction.tour.merge.commit; 8.152 - 8.153 - <para>We now have a new tip revision; notice that it has 8.154 - <emphasis>both</emphasis> of our former heads as its parents. 8.155 - These are the same revisions that were previously displayed by 8.156 - <command role="hg-cmd">hg parents</command>.</para> 8.157 - 8.158 - &interaction.tour.merge.tip; 8.159 - 8.160 - <para>In figure <xref 8.161 - linkend="fig:tour-merge:merge"/>, you can see a 8.162 - representation of what happens to the working directory during 8.163 - the merge, and how this affects the repository when the commit 8.164 - happens. During the merge, the working directory has two 8.165 - parent changesets, and these become the parents of the new 8.166 - changeset.</para> 8.167 - 8.168 - </sect2> 8.169 - </sect1> 8.170 - <sect1> 8.171 - <title>Merging conflicting changes</title> 8.172 - 8.173 - <para>Most merges are simple affairs, but sometimes you'll find 8.174 - yourself merging changes where each modifies the same portions 8.175 - of the same files. Unless both modifications are identical, 8.176 - this results in a <emphasis>conflict</emphasis>, where you have 8.177 - to decide how to reconcile the different changes into something 8.178 - coherent.</para> 8.179 - 8.180 - <informalfigure> 8.181 - 8.182 - <mediaobject id="fig:tour-merge:conflict"> 8.183 - <imageobject><imagedata fileref="tour-merge-conflict"/></imageobject> 8.184 - <textobject><phrase>XXX add text</phrase></textobject> 8.185 - <caption><para>Conflicting changes to a 8.186 - document</para></caption> </mediaobject> 8.187 - </informalfigure> 8.188 - 8.189 - <para>Figure <xref linkend="fig:tour-merge:conflict"/> illustrates 8.190 - an instance of two conflicting changes to a document. We 8.191 - started with a single version of the file; then we made some 8.192 - changes; while someone else made different changes to the same 8.193 - text. Our task in resolving the conflicting changes is to 8.194 - decide what the file should look like.</para> 8.195 - 8.196 - <para>Mercurial doesn't have a built-in facility for handling 8.197 - conflicts. Instead, it runs an external program called 8.198 - <command>hgmerge</command>. This is a shell script that is 8.199 - bundled with Mercurial; you can change it to behave however you 8.200 - please. What it does by default is try to find one of several 8.201 - different merging tools that are likely to be installed on your 8.202 - system. It first tries a few fully automatic merging tools; if 8.203 - these don't succeed (because the resolution process requires 8.204 - human guidance) or aren't present, the script tries a few 8.205 - different graphical merging tools.</para> 8.206 - 8.207 - <para>It's also possible to get Mercurial to run another program 8.208 - or script instead of <command>hgmerge</command>, by setting the 8.209 - <envar>HGMERGE</envar> environment variable to the name of your 8.210 - preferred program.</para> 8.211 - 8.212 - <sect2> 8.213 - <title>Using a graphical merge tool</title> 8.214 - 8.215 - <para>My preferred graphical merge tool is 8.216 - <command>kdiff3</command>, which I'll use to describe the 8.217 - features that are common to graphical file merging tools. You 8.218 - can see a screenshot of <command>kdiff3</command> in action in 8.219 - figure <xref linkend="fig:tour-merge:kdiff3"/>. The kind of 8.220 - merge it is performing is called a <emphasis>three-way 8.221 - merge</emphasis>, because there are three different versions 8.222 - of the file of interest to us. The tool thus splits the upper 8.223 - portion of the window into three panes:</para> 8.224 - <itemizedlist> 8.225 - <listitem><para>At the left is the <emphasis>base</emphasis> 8.226 - version of the file, i.e. the most recent version from 8.227 - which the two versions we're trying to merge are 8.228 - descended.</para> 8.229 - </listitem> 8.230 - <listitem><para>In the middle is <quote>our</quote> version of 8.231 - the file, with the contents that we modified.</para> 8.232 - </listitem> 8.233 - <listitem><para>On the right is <quote>their</quote> version 8.234 - of the file, the one that from the changeset that we're 8.235 - trying to merge with.</para> 8.236 - </listitem></itemizedlist> 8.237 - <para>In the pane below these is the current 8.238 - <emphasis>result</emphasis> of the merge. Our task is to 8.239 - replace all of the red text, which indicates unresolved 8.240 - conflicts, with some sensible merger of the 8.241 - <quote>ours</quote> and <quote>theirs</quote> versions of the 8.242 - file.</para> 8.243 - 8.244 - <para>All four of these panes are <emphasis>locked 8.245 - together</emphasis>; if we scroll vertically or horizontally 8.246 - in any of them, the others are updated to display the 8.247 - corresponding sections of their respective files.</para> 8.248 - 8.249 - <informalfigure id="fig:tour-merge:kdiff3"> 8.250 - <mediaobject><imageobject><imagedata 8.251 - fileref="kdiff3"/></imageobject><textobject><phrase>XXX 8.252 - add text</phrase></textobject> 8.253 - <caption><para>Using <command>kdiff3</command> to merge 8.254 - versions of a file</para></caption> 8.255 - </mediaobject> 8.256 - </informalfigure> 8.257 - 8.258 - <para>For each conflicting portion of the file, we can choose to 8.259 - resolve the conflict using some combination of text from the 8.260 - base version, ours, or theirs. We can also manually edit the 8.261 - merged file at any time, in case we need to make further 8.262 - modifications.</para> 8.263 - 8.264 - <para>There are <emphasis>many</emphasis> file merging tools 8.265 - available, too many to cover here. They vary in which 8.266 - platforms they are available for, and in their particular 8.267 - strengths and weaknesses. Most are tuned for merging files 8.268 - containing plain text, while a few are aimed at specialised 8.269 - file formats (generally XML).</para> 8.270 - 8.271 - </sect2> 8.272 - <sect2> 8.273 - <title>A worked example</title> 8.274 - 8.275 - <para>In this example, we will reproduce the file modification 8.276 - history of figure <xref linkend="fig:tour-merge:conflict"/> 8.277 - above. Let's begin by creating a repository with a base 8.278 - version of our document.</para> 8.279 - 8.280 - &interaction.tour-merge-conflict.wife; 8.281 - 8.282 - <para>We'll clone the repository and make a change to the 8.283 - file.</para> 8.284 - 8.285 - &interaction.tour-merge-conflict.cousin; 8.286 - 8.287 - <para>And another clone, to simulate someone else making a 8.288 - change to the file. (This hints at the idea that it's not all 8.289 - that unusual to merge with yourself when you isolate tasks in 8.290 - separate repositories, and indeed to find and resolve 8.291 - conflicts while doing so.)</para> 8.292 - 8.293 - &interaction.tour-merge-conflict.son; 8.294 - 8.295 - <para>Having created two 8.296 - different versions of the file, we'll set up an environment 8.297 - suitable for running our merge.</para> 8.298 - 8.299 - &interaction.tour-merge-conflict.pull; 8.300 - 8.301 - <para>In this example, I won't use Mercurial's normal 8.302 - <command>hgmerge</command> program to do the merge, because it 8.303 - would drop my nice automated example-running tool into a 8.304 - graphical user interface. Instead, I'll set 8.305 - <envar>HGMERGE</envar> to tell Mercurial to use the 8.306 - non-interactive <command>merge</command> command. This is 8.307 - bundled with many Unix-like systems. If you're following this 8.308 - example on your computer, don't bother setting 8.309 - <envar>HGMERGE</envar>.</para> 8.310 - 8.311 - <para><emphasis role="bold">XXX FIX THIS 8.312 - EXAMPLE.</emphasis></para> 8.313 - 8.314 - &interaction.tour-merge-conflict.merge; 8.315 - 8.316 - <para>Because <command>merge</command> can't resolve the 8.317 - conflicting changes, it leaves <emphasis>merge 8.318 - markers</emphasis> inside the file that has conflicts, 8.319 - indicating which lines have conflicts, and whether they came 8.320 - from our version of the file or theirs.</para> 8.321 - 8.322 - <para>Mercurial can tell from the way <command>merge</command> 8.323 - exits that it wasn't able to merge successfully, so it tells 8.324 - us what commands we'll need to run if we want to redo the 8.325 - merging operation. This could be useful if, for example, we 8.326 - were running a graphical merge tool and quit because we were 8.327 - confused or realised we had made a mistake.</para> 8.328 - 8.329 - <para>If automatic or manual merges fail, there's nothing to 8.330 - prevent us from <quote>fixing up</quote> the affected files 8.331 - ourselves, and committing the results of our merge:</para> 8.332 - 8.333 - &interaction.tour-merge-conflict.commit; 8.334 - 8.335 - </sect2> 8.336 - </sect1> 8.337 - <sect1 id="sec:tour-merge:fetch"> 8.338 - <title>Simplifying the pull-merge-commit sequence</title> 8.339 - 8.340 - <para>The process of merging changes as outlined above is 8.341 - straightforward, but requires running three commands in 8.342 - sequence.</para> 8.343 - <programlisting>hg pull 8.344 -hg merge 8.345 -hg commit -m 'Merged remote changes'</programlisting> 8.346 - <para>In the case of the final commit, you also need to enter a 8.347 - commit message, which is almost always going to be a piece of 8.348 - uninteresting <quote>boilerplate</quote> text.</para> 8.349 - 8.350 - <para>It would be nice to reduce the number of steps needed, if 8.351 - this were possible. Indeed, Mercurial is distributed with an 8.352 - extension called <literal role="hg-ext">fetch</literal> that 8.353 - does just this.</para> 8.354 - 8.355 - <para>Mercurial provides a flexible extension mechanism that lets 8.356 - people extend its functionality, while keeping the core of 8.357 - Mercurial small and easy to deal with. Some extensions add new 8.358 - commands that you can use from the command line, while others 8.359 - work <quote>behind the scenes,</quote> for example adding 8.360 - capabilities to the server.</para> 8.361 - 8.362 - <para>The <literal role="hg-ext">fetch</literal> extension adds a 8.363 - new command called, not surprisingly, <command role="hg-cmd">hg 8.364 - fetch</command>. This extension acts as a combination of 8.365 - <command role="hg-cmd">hg pull</command>, <command 8.366 - role="hg-cmd">hg update</command> and <command 8.367 - role="hg-cmd">hg merge</command>. It begins by pulling 8.368 - changes from another repository into the current repository. If 8.369 - it finds that the changes added a new head to the repository, it 8.370 - begins a merge, then commits the result of the merge with an 8.371 - automatically-generated commit message. If no new heads were 8.372 - added, it updates the working directory to the new tip 8.373 - changeset.</para> 8.374 - 8.375 - <para>Enabling the <literal role="hg-ext">fetch</literal> 8.376 - extension is easy. Edit your <filename 8.377 - role="special">.hgrc</filename>, and either go to the <literal 8.378 - role="rc-extensions">extensions</literal> section or create an 8.379 - <literal role="rc-extensions">extensions</literal> section. Then 8.380 - add a line that simply reads <quote><literal>fetch 8.381 - </literal></quote>.</para> 8.382 - <programlisting>[extensions] 8.383 -fetch =</programlisting> 8.384 - <para>(Normally, on the right-hand side of the 8.385 - <quote><literal>=</literal></quote> would appear the location of 8.386 - the extension, but since the <literal 8.387 - role="hg-ext">fetch</literal> extension is in the standard 8.388 - distribution, Mercurial knows where to search for it.)</para> 8.389 - 8.390 - </sect1> 8.391 -</chapter> 8.392 - 8.393 -<!-- 8.394 -local variables: 8.395 -sgml-parent-document: ("00book.xml" "book" "chapter") 8.396 -end: 8.397 --->
9.1 --- a/en/ch04-concepts.xml Wed Mar 18 00:08:22 2009 -0700 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,726 +0,0 @@ 9.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 9.5 - 9.6 -<chapter id="chap:concepts"> 9.7 - <?dbhtml filename="behind-the-scenes.html"?> 9.8 - <title>Behind the scenes</title> 9.9 - 9.10 - <para>Unlike many revision control systems, the concepts upon which 9.11 - Mercurial is built are simple enough that it's easy to understand 9.12 - how the software really works. Knowing this certainly isn't 9.13 - necessary, but I find it useful to have a <quote>mental 9.14 - model</quote> of what's going on.</para> 9.15 - 9.16 - <para>This understanding gives me confidence that Mercurial has been 9.17 - carefully designed to be both <emphasis>safe</emphasis> and 9.18 - <emphasis>efficient</emphasis>. And just as importantly, if it's 9.19 - easy for me to retain a good idea of what the software is doing 9.20 - when I perform a revision control task, I'm less likely to be 9.21 - surprised by its behaviour.</para> 9.22 - 9.23 - <para>In this chapter, we'll initially cover the core concepts 9.24 - behind Mercurial's design, then continue to discuss some of the 9.25 - interesting details of its implementation.</para> 9.26 - 9.27 - <sect1> 9.28 - <title>Mercurial's historical record</title> 9.29 - 9.30 - <sect2> 9.31 - <title>Tracking the history of a single file</title> 9.32 - 9.33 - <para>When Mercurial tracks modifications to a file, it stores 9.34 - the history of that file in a metadata object called a 9.35 - <emphasis>filelog</emphasis>. Each entry in the filelog 9.36 - contains enough information to reconstruct one revision of the 9.37 - file that is being tracked. Filelogs are stored as files in 9.38 - the <filename role="special" 9.39 - class="directory">.hg/store/data</filename> directory. A 9.40 - filelog contains two kinds of information: revision data, and 9.41 - an index to help Mercurial to find a revision 9.42 - efficiently.</para> 9.43 - 9.44 - <para>A file that is large, or has a lot of history, has its 9.45 - filelog stored in separate data 9.46 - (<quote><literal>.d</literal></quote> suffix) and index 9.47 - (<quote><literal>.i</literal></quote> suffix) files. For 9.48 - small files without much history, the revision data and index 9.49 - are combined in a single <quote><literal>.i</literal></quote> 9.50 - file. The correspondence between a file in the working 9.51 - directory and the filelog that tracks its history in the 9.52 - repository is illustrated in figure <xref 9.53 - linkend="fig:concepts:filelog"/>.</para> 9.54 - 9.55 - <informalfigure id="fig:concepts:filelog"> 9.56 - <mediaobject><imageobject><imagedata 9.57 - fileref="filelog"/></imageobject><textobject><phrase>XXX 9.58 - add text</phrase></textobject> 9.59 - <caption><para>Relationships between files in working 9.60 - directory and filelogs in 9.61 - repository</para></caption></mediaobject> 9.62 - </informalfigure> 9.63 - 9.64 - </sect2> 9.65 - <sect2> 9.66 - <title>Managing tracked files</title> 9.67 - 9.68 - <para>Mercurial uses a structure called a 9.69 - <emphasis>manifest</emphasis> to collect together information 9.70 - about the files that it tracks. Each entry in the manifest 9.71 - contains information about the files present in a single 9.72 - changeset. An entry records which files are present in the 9.73 - changeset, the revision of each file, and a few other pieces 9.74 - of file metadata.</para> 9.75 - 9.76 - </sect2> 9.77 - <sect2> 9.78 - <title>Recording changeset information</title> 9.79 - 9.80 - <para>The <emphasis>changelog</emphasis> contains information 9.81 - about each changeset. Each revision records who committed a 9.82 - change, the changeset comment, other pieces of 9.83 - changeset-related information, and the revision of the 9.84 - manifest to use.</para> 9.85 - 9.86 - </sect2> 9.87 - <sect2> 9.88 - <title>Relationships between revisions</title> 9.89 - 9.90 - <para>Within a changelog, a manifest, or a filelog, each 9.91 - revision stores a pointer to its immediate parent (or to its 9.92 - two parents, if it's a merge revision). As I mentioned above, 9.93 - there are also relationships between revisions 9.94 - <emphasis>across</emphasis> these structures, and they are 9.95 - hierarchical in nature.</para> 9.96 - 9.97 - <para>For every changeset in a repository, there is exactly one 9.98 - revision stored in the changelog. Each revision of the 9.99 - changelog contains a pointer to a single revision of the 9.100 - manifest. A revision of the manifest stores a pointer to a 9.101 - single revision of each filelog tracked when that changeset 9.102 - was created. These relationships are illustrated in figure 9.103 - <xref linkend="fig:concepts:metadata"/>.</para> 9.104 - 9.105 - <informalfigure id="fig:concepts:metadata"> 9.106 - <mediaobject><imageobject><imagedata 9.107 - fileref="metadata"/></imageobject><textobject><phrase>XXX 9.108 - add text</phrase></textobject><caption><para>Metadata 9.109 - relationships</para></caption> 9.110 - </mediaobject> 9.111 - </informalfigure> 9.112 - 9.113 - <para>As the illustration shows, there is 9.114 - <emphasis>not</emphasis> a <quote>one to one</quote> 9.115 - relationship between revisions in the changelog, manifest, or 9.116 - filelog. If the manifest hasn't changed between two 9.117 - changesets, the changelog entries for those changesets will 9.118 - point to the same revision of the manifest. If a file that 9.119 - Mercurial tracks hasn't changed between two changesets, the 9.120 - entry for that file in the two revisions of the manifest will 9.121 - point to the same revision of its filelog.</para> 9.122 - 9.123 - </sect2> 9.124 - </sect1> 9.125 - <sect1> 9.126 - <title>Safe, efficient storage</title> 9.127 - 9.128 - <para>The underpinnings of changelogs, manifests, and filelogs are 9.129 - provided by a single structure called the 9.130 - <emphasis>revlog</emphasis>.</para> 9.131 - 9.132 - <sect2> 9.133 - <title>Efficient storage</title> 9.134 - 9.135 - <para>The revlog provides efficient storage of revisions using a 9.136 - <emphasis>delta</emphasis> mechanism. Instead of storing a 9.137 - complete copy of a file for each revision, it stores the 9.138 - changes needed to transform an older revision into the new 9.139 - revision. For many kinds of file data, these deltas are 9.140 - typically a fraction of a percent of the size of a full copy 9.141 - of a file.</para> 9.142 - 9.143 - <para>Some obsolete revision control systems can only work with 9.144 - deltas of text files. They must either store binary files as 9.145 - complete snapshots or encoded into a text representation, both 9.146 - of which are wasteful approaches. Mercurial can efficiently 9.147 - handle deltas of files with arbitrary binary contents; it 9.148 - doesn't need to treat text as special.</para> 9.149 - 9.150 - </sect2> 9.151 - <sect2 id="sec:concepts:txn"> 9.152 - <title>Safe operation</title> 9.153 - 9.154 - <para>Mercurial only ever <emphasis>appends</emphasis> data to 9.155 - the end of a revlog file. It never modifies a section of a 9.156 - file after it has written it. This is both more robust and 9.157 - efficient than schemes that need to modify or rewrite 9.158 - data.</para> 9.159 - 9.160 - <para>In addition, Mercurial treats every write as part of a 9.161 - <emphasis>transaction</emphasis> that can span a number of 9.162 - files. A transaction is <emphasis>atomic</emphasis>: either 9.163 - the entire transaction succeeds and its effects are all 9.164 - visible to readers in one go, or the whole thing is undone. 9.165 - This guarantee of atomicity means that if you're running two 9.166 - copies of Mercurial, where one is reading data and one is 9.167 - writing it, the reader will never see a partially written 9.168 - result that might confuse it.</para> 9.169 - 9.170 - <para>The fact that Mercurial only appends to files makes it 9.171 - easier to provide this transactional guarantee. The easier it 9.172 - is to do stuff like this, the more confident you should be 9.173 - that it's done correctly.</para> 9.174 - 9.175 - </sect2> 9.176 - <sect2> 9.177 - <title>Fast retrieval</title> 9.178 - 9.179 - <para>Mercurial cleverly avoids a pitfall common to all earlier 9.180 - revision control systems: the problem of <emphasis>inefficient 9.181 - retrieval</emphasis>. Most revision control systems store 9.182 - the contents of a revision as an incremental series of 9.183 - modifications against a <quote>snapshot</quote>. To 9.184 - reconstruct a specific revision, you must first read the 9.185 - snapshot, and then every one of the revisions between the 9.186 - snapshot and your target revision. The more history that a 9.187 - file accumulates, the more revisions you must read, hence the 9.188 - longer it takes to reconstruct a particular revision.</para> 9.189 - 9.190 - <informalfigure id="fig:concepts:snapshot"> 9.191 - <mediaobject><imageobject><imagedata 9.192 - fileref="snapshot"/></imageobject><textobject><phrase>XXX 9.193 - add text</phrase></textobject><caption><para>Snapshot of 9.194 - a revlog, with incremental 9.195 - deltas</para></caption></mediaobject> 9.196 - </informalfigure> 9.197 - 9.198 - <para>The innovation that Mercurial applies to this problem is 9.199 - simple but effective. Once the cumulative amount of delta 9.200 - information stored since the last snapshot exceeds a fixed 9.201 - threshold, it stores a new snapshot (compressed, of course), 9.202 - instead of another delta. This makes it possible to 9.203 - reconstruct <emphasis>any</emphasis> revision of a file 9.204 - quickly. This approach works so well that it has since been 9.205 - copied by several other revision control systems.</para> 9.206 - 9.207 - <para>Figure <xref linkend="fig:concepts:snapshot"/> illustrates 9.208 - the idea. In an entry in a revlog's index file, Mercurial 9.209 - stores the range of entries from the data file that it must 9.210 - read to reconstruct a particular revision.</para> 9.211 - 9.212 - <sect3> 9.213 - <title>Aside: the influence of video compression</title> 9.214 - 9.215 - <para>If you're familiar with video compression or have ever 9.216 - watched a TV feed through a digital cable or satellite 9.217 - service, you may know that most video compression schemes 9.218 - store each frame of video as a delta against its predecessor 9.219 - frame. In addition, these schemes use <quote>lossy</quote> 9.220 - compression techniques to increase the compression ratio, so 9.221 - visual errors accumulate over the course of a number of 9.222 - inter-frame deltas.</para> 9.223 - 9.224 - <para>Because it's possible for a video stream to <quote>drop 9.225 - out</quote> occasionally due to signal glitches, and to 9.226 - limit the accumulation of artefacts introduced by the lossy 9.227 - compression process, video encoders periodically insert a 9.228 - complete frame (called a <quote>key frame</quote>) into the 9.229 - video stream; the next delta is generated against that 9.230 - frame. This means that if the video signal gets 9.231 - interrupted, it will resume once the next key frame is 9.232 - received. Also, the accumulation of encoding errors 9.233 - restarts anew with each key frame.</para> 9.234 - 9.235 - </sect3> 9.236 - </sect2> 9.237 - <sect2> 9.238 - <title>Identification and strong integrity</title> 9.239 - 9.240 - <para>Along with delta or snapshot information, a revlog entry 9.241 - contains a cryptographic hash of the data that it represents. 9.242 - This makes it difficult to forge the contents of a revision, 9.243 - and easy to detect accidental corruption.</para> 9.244 - 9.245 - <para>Hashes provide more than a mere check against corruption; 9.246 - they are used as the identifiers for revisions. The changeset 9.247 - identification hashes that you see as an end user are from 9.248 - revisions of the changelog. Although filelogs and the 9.249 - manifest also use hashes, Mercurial only uses these behind the 9.250 - scenes.</para> 9.251 - 9.252 - <para>Mercurial verifies that hashes are correct when it 9.253 - retrieves file revisions and when it pulls changes from 9.254 - another repository. If it encounters an integrity problem, it 9.255 - will complain and stop whatever it's doing.</para> 9.256 - 9.257 - <para>In addition to the effect it has on retrieval efficiency, 9.258 - Mercurial's use of periodic snapshots makes it more robust 9.259 - against partial data corruption. If a revlog becomes partly 9.260 - corrupted due to a hardware error or system bug, it's often 9.261 - possible to reconstruct some or most revisions from the 9.262 - uncorrupted sections of the revlog, both before and after the 9.263 - corrupted section. This would not be possible with a 9.264 - delta-only storage model.</para> 9.265 - 9.266 - </sect2> 9.267 - </sect1> 9.268 - <sect1> 9.269 - <title>Revision history, branching, and merging</title> 9.270 - 9.271 - <para>Every entry in a Mercurial revlog knows the identity of its 9.272 - immediate ancestor revision, usually referred to as its 9.273 - <emphasis>parent</emphasis>. In fact, a revision contains room 9.274 - for not one parent, but two. Mercurial uses a special hash, 9.275 - called the <quote>null ID</quote>, to represent the idea 9.276 - <quote>there is no parent here</quote>. This hash is simply a 9.277 - string of zeroes.</para> 9.278 - 9.279 - <para>In figure <xref linkend="fig:concepts:revlog"/>, you can see 9.280 - an example of the conceptual structure of a revlog. Filelogs, 9.281 - manifests, and changelogs all have this same structure; they 9.282 - differ only in the kind of data stored in each delta or 9.283 - snapshot.</para> 9.284 - 9.285 - <para>The first revision in a revlog (at the bottom of the image) 9.286 - has the null ID in both of its parent slots. For a 9.287 - <quote>normal</quote> revision, its first parent slot contains 9.288 - the ID of its parent revision, and its second contains the null 9.289 - ID, indicating that the revision has only one real parent. Any 9.290 - two revisions that have the same parent ID are branches. A 9.291 - revision that represents a merge between branches has two normal 9.292 - revision IDs in its parent slots.</para> 9.293 - 9.294 - <informalfigure id="fig:concepts:revlog"> 9.295 - <mediaobject><imageobject><imagedata 9.296 - fileref="revlog"/></imageobject><textobject><phrase>XXX 9.297 - add text</phrase></textobject></mediaobject> 9.298 - </informalfigure> 9.299 - 9.300 - </sect1> 9.301 - <sect1> 9.302 - <title>The working directory</title> 9.303 - 9.304 - <para>In the working directory, Mercurial stores a snapshot of the 9.305 - files from the repository as of a particular changeset.</para> 9.306 - 9.307 - <para>The working directory <quote>knows</quote> which changeset 9.308 - it contains. When you update the working directory to contain a 9.309 - particular changeset, Mercurial looks up the appropriate 9.310 - revision of the manifest to find out which files it was tracking 9.311 - at the time that changeset was committed, and which revision of 9.312 - each file was then current. It then recreates a copy of each of 9.313 - those files, with the same contents it had when the changeset 9.314 - was committed.</para> 9.315 - 9.316 - <para>The <emphasis>dirstate</emphasis> contains Mercurial's 9.317 - knowledge of the working directory. This details which 9.318 - changeset the working directory is updated to, and all of the 9.319 - files that Mercurial is tracking in the working 9.320 - directory.</para> 9.321 - 9.322 - <para>Just as a revision of a revlog has room for two parents, so 9.323 - that it can represent either a normal revision (with one parent) 9.324 - or a merge of two earlier revisions, the dirstate has slots for 9.325 - two parents. When you use the <command role="hg-cmd">hg 9.326 - update</command> command, the changeset that you update to is 9.327 - stored in the <quote>first parent</quote> slot, and the null ID 9.328 - in the second. When you <command role="hg-cmd">hg 9.329 - merge</command> with another changeset, the first parent 9.330 - remains unchanged, and the second parent is filled in with the 9.331 - changeset you're merging with. The <command role="hg-cmd">hg 9.332 - parents</command> command tells you what the parents of the 9.333 - dirstate are.</para> 9.334 - 9.335 - <sect2> 9.336 - <title>What happens when you commit</title> 9.337 - 9.338 - <para>The dirstate stores parent information for more than just 9.339 - book-keeping purposes. Mercurial uses the parents of the 9.340 - dirstate as <emphasis>the parents of a new 9.341 - changeset</emphasis> when you perform a commit.</para> 9.342 - 9.343 - <informalfigure id="fig:concepts:wdir"> 9.344 - <mediaobject><imageobject><imagedata 9.345 - fileref="wdir"/></imageobject><textobject><phrase>XXX 9.346 - add text</phrase></textobject><caption><para>The working 9.347 - directory can have two 9.348 - parents</para></caption></mediaobject> 9.349 - </informalfigure> 9.350 - 9.351 - <para>Figure <xref linkend="fig:concepts:wdir"/> shows the 9.352 - normal state of the working directory, where it has a single 9.353 - changeset as parent. That changeset is the 9.354 - <emphasis>tip</emphasis>, the newest changeset in the 9.355 - repository that has no children.</para> 9.356 - 9.357 - <informalfigure id="fig:concepts:wdir-after-commit"> 9.358 - <mediaobject><imageobject><imagedata 9.359 - fileref="wdir-after-commit"/></imageobject><textobject><phrase>XXX 9.360 - add text</phrase></textobject><caption><para>The working 9.361 - directory gains new parents after a 9.362 - commit</para></caption></mediaobject> 9.363 - </informalfigure> 9.364 - 9.365 - <para>It's useful to think of the working directory as 9.366 - <quote>the changeset I'm about to commit</quote>. Any files 9.367 - that you tell Mercurial that you've added, removed, renamed, 9.368 - or copied will be reflected in that changeset, as will 9.369 - modifications to any files that Mercurial is already tracking; 9.370 - the new changeset will have the parents of the working 9.371 - directory as its parents.</para> 9.372 - 9.373 - <para>After a commit, Mercurial will update the parents of the 9.374 - working directory, so that the first parent is the ID of the 9.375 - new changeset, and the second is the null ID. This is shown 9.376 - in figure <xref linkend="fig:concepts:wdir-after-commit"/>. 9.377 - Mercurial 9.378 - doesn't touch any of the files in the working directory when 9.379 - you commit; it just modifies the dirstate to note its new 9.380 - parents.</para> 9.381 - 9.382 - </sect2> 9.383 - <sect2> 9.384 - <title>Creating a new head</title> 9.385 - 9.386 - <para>It's perfectly normal to update the working directory to a 9.387 - changeset other than the current tip. For example, you might 9.388 - want to know what your project looked like last Tuesday, or 9.389 - you could be looking through changesets to see which one 9.390 - introduced a bug. In cases like this, the natural thing to do 9.391 - is update the working directory to the changeset you're 9.392 - interested in, and then examine the files in the working 9.393 - directory directly to see their contents as they were when you 9.394 - committed that changeset. The effect of this is shown in 9.395 - figure <xref linkend="fig:concepts:wdir-pre-branch"/>.</para> 9.396 - 9.397 - <informalfigure id="fig:concepts:wdir-pre-branch"> 9.398 - <mediaobject><imageobject><imagedata 9.399 - fileref="wdir-pre-branch"/></imageobject><textobject><phrase>XXX 9.400 - add text</phrase></textobject><caption><para>The working 9.401 - directory, updated to an older 9.402 - changeset</para></caption></mediaobject> 9.403 - </informalfigure> 9.404 - 9.405 - <para>Having updated the working directory to an older 9.406 - changeset, what happens if you make some changes, and then 9.407 - commit? Mercurial behaves in the same way as I outlined 9.408 - above. The parents of the working directory become the 9.409 - parents of the new changeset. This new changeset has no 9.410 - children, so it becomes the new tip. And the repository now 9.411 - contains two changesets that have no children; we call these 9.412 - <emphasis>heads</emphasis>. You can see the structure that 9.413 - this creates in figure <xref 9.414 - linkend="fig:concepts:wdir-branch"/>.</para> 9.415 - 9.416 - <informalfigure id="fig:concepts:wdir-branch"> 9.417 - <mediaobject><imageobject><imagedata 9.418 - fileref="wdir-branch"/></imageobject><textobject><phrase>XXX 9.419 - add text</phrase></textobject><caption><para>After a 9.420 - commit made while synced to an older 9.421 - changeset</para></caption></mediaobject> 9.422 - </informalfigure> 9.423 - 9.424 - <note> 9.425 - <para> If you're new to Mercurial, you should keep in mind a 9.426 - common <quote>error</quote>, which is to use the <command 9.427 - role="hg-cmd">hg pull</command> command without any 9.428 - options. By default, the <command role="hg-cmd">hg 9.429 - pull</command> command <emphasis>does not</emphasis> 9.430 - update the working directory, so you'll bring new changesets 9.431 - into your repository, but the working directory will stay 9.432 - synced at the same changeset as before the pull. If you 9.433 - make some changes and commit afterwards, you'll thus create 9.434 - a new head, because your working directory isn't synced to 9.435 - whatever the current tip is.</para> 9.436 - 9.437 - <para> I put the word <quote>error</quote> in quotes because 9.438 - all that you need to do to rectify this situation is 9.439 - <command role="hg-cmd">hg merge</command>, then <command 9.440 - role="hg-cmd">hg commit</command>. In other words, this 9.441 - almost never has negative consequences; it just surprises 9.442 - people. I'll discuss other ways to avoid this behaviour, 9.443 - and why Mercurial behaves in this initially surprising way, 9.444 - later on.</para> 9.445 - </note> 9.446 - 9.447 - </sect2> 9.448 - <sect2> 9.449 - <title>Merging heads</title> 9.450 - 9.451 - <para>When you run the <command role="hg-cmd">hg merge</command> 9.452 - command, Mercurial leaves the first parent of the working 9.453 - directory unchanged, and sets the second parent to the 9.454 - changeset you're merging with, as shown in figure <xref 9.455 - linkend="fig:concepts:wdir-merge"/>.</para> 9.456 - 9.457 - <informalfigure id="fig:concepts:wdir-merge"> 9.458 - <mediaobject><imageobject><imagedata 9.459 - fileref="wdir-merge"/></imageobject><textobject><phrase>XXX 9.460 - add text</phrase></textobject><caption><para>Merging two 9.461 - heads</para></caption></mediaobject> 9.462 - </informalfigure> 9.463 - 9.464 - <para>Mercurial also has to modify the working directory, to 9.465 - merge the files managed in the two changesets. Simplified a 9.466 - little, the merging process goes like this, for every file in 9.467 - the manifests of both changesets.</para> 9.468 - <itemizedlist> 9.469 - <listitem><para>If neither changeset has modified a file, do 9.470 - nothing with that file.</para> 9.471 - </listitem> 9.472 - <listitem><para>If one changeset has modified a file, and the 9.473 - other hasn't, create the modified copy of the file in the 9.474 - working directory.</para> 9.475 - </listitem> 9.476 - <listitem><para>If one changeset has removed a file, and the 9.477 - other hasn't (or has also deleted it), delete the file 9.478 - from the working directory.</para> 9.479 - </listitem> 9.480 - <listitem><para>If one changeset has removed a file, but the 9.481 - other has modified the file, ask the user what to do: keep 9.482 - the modified file, or remove it?</para> 9.483 - </listitem> 9.484 - <listitem><para>If both changesets have modified a file, 9.485 - invoke an external merge program to choose the new 9.486 - contents for the merged file. This may require input from 9.487 - the user.</para> 9.488 - </listitem> 9.489 - <listitem><para>If one changeset has modified a file, and the 9.490 - other has renamed or copied the file, make sure that the 9.491 - changes follow the new name of the file.</para> 9.492 - </listitem></itemizedlist> 9.493 - <para>There are more details&emdash;merging has plenty of corner 9.494 - cases&emdash;but these are the most common choices that are 9.495 - involved in a merge. As you can see, most cases are 9.496 - completely automatic, and indeed most merges finish 9.497 - automatically, without requiring your input to resolve any 9.498 - conflicts.</para> 9.499 - 9.500 - <para>When you're thinking about what happens when you commit 9.501 - after a merge, once again the working directory is <quote>the 9.502 - changeset I'm about to commit</quote>. After the <command 9.503 - role="hg-cmd">hg merge</command> command completes, the 9.504 - working directory has two parents; these will become the 9.505 - parents of the new changeset.</para> 9.506 - 9.507 - <para>Mercurial lets you perform multiple merges, but you must 9.508 - commit the results of each individual merge as you go. This 9.509 - is necessary because Mercurial only tracks two parents for 9.510 - both revisions and the working directory. While it would be 9.511 - technically possible to merge multiple changesets at once, the 9.512 - prospect of user confusion and making a terrible mess of a 9.513 - merge immediately becomes overwhelming.</para> 9.514 - 9.515 - </sect2> 9.516 - </sect1> 9.517 - <sect1> 9.518 - <title>Other interesting design features</title> 9.519 - 9.520 - <para>In the sections above, I've tried to highlight some of the 9.521 - most important aspects of Mercurial's design, to illustrate that 9.522 - it pays careful attention to reliability and performance. 9.523 - However, the attention to detail doesn't stop there. There are 9.524 - a number of other aspects of Mercurial's construction that I 9.525 - personally find interesting. I'll detail a few of them here, 9.526 - separate from the <quote>big ticket</quote> items above, so that 9.527 - if you're interested, you can gain a better idea of the amount 9.528 - of thinking that goes into a well-designed system.</para> 9.529 - 9.530 - <sect2> 9.531 - <title>Clever compression</title> 9.532 - 9.533 - <para>When appropriate, Mercurial will store both snapshots and 9.534 - deltas in compressed form. It does this by always 9.535 - <emphasis>trying to</emphasis> compress a snapshot or delta, 9.536 - but only storing the compressed version if it's smaller than 9.537 - the uncompressed version.</para> 9.538 - 9.539 - <para>This means that Mercurial does <quote>the right 9.540 - thing</quote> when storing a file whose native form is 9.541 - compressed, such as a <literal>zip</literal> archive or a JPEG 9.542 - image. When these types of files are compressed a second 9.543 - time, the resulting file is usually bigger than the 9.544 - once-compressed form, and so Mercurial will store the plain 9.545 - <literal>zip</literal> or JPEG.</para> 9.546 - 9.547 - <para>Deltas between revisions of a compressed file are usually 9.548 - larger than snapshots of the file, and Mercurial again does 9.549 - <quote>the right thing</quote> in these cases. It finds that 9.550 - such a delta exceeds the threshold at which it should store a 9.551 - complete snapshot of the file, so it stores the snapshot, 9.552 - again saving space compared to a naive delta-only 9.553 - approach.</para> 9.554 - 9.555 - <sect3> 9.556 - <title>Network recompression</title> 9.557 - 9.558 - <para>When storing revisions on disk, Mercurial uses the 9.559 - <quote>deflate</quote> compression algorithm (the same one 9.560 - used by the popular <literal>zip</literal> archive format), 9.561 - which balances good speed with a respectable compression 9.562 - ratio. However, when transmitting revision data over a 9.563 - network connection, Mercurial uncompresses the compressed 9.564 - revision data.</para> 9.565 - 9.566 - <para>If the connection is over HTTP, Mercurial recompresses 9.567 - the entire stream of data using a compression algorithm that 9.568 - gives a better compression ratio (the Burrows-Wheeler 9.569 - algorithm from the widely used <literal>bzip2</literal> 9.570 - compression package). This combination of algorithm and 9.571 - compression of the entire stream (instead of a revision at a 9.572 - time) substantially reduces the number of bytes to be 9.573 - transferred, yielding better network performance over almost 9.574 - all kinds of network.</para> 9.575 - 9.576 - <para>(If the connection is over <command>ssh</command>, 9.577 - Mercurial <emphasis>doesn't</emphasis> recompress the 9.578 - stream, because <command>ssh</command> can already do this 9.579 - itself.)</para> 9.580 - 9.581 - </sect3> 9.582 - </sect2> 9.583 - <sect2> 9.584 - <title>Read/write ordering and atomicity</title> 9.585 - 9.586 - <para>Appending to files isn't the whole story when it comes to 9.587 - guaranteeing that a reader won't see a partial write. If you 9.588 - recall figure <xref linkend="fig:concepts:metadata"/>, 9.589 - revisions in the 9.590 - changelog point to revisions in the manifest, and revisions in 9.591 - the manifest point to revisions in filelogs. This hierarchy 9.592 - is deliberate.</para> 9.593 - 9.594 - <para>A writer starts a transaction by writing filelog and 9.595 - manifest data, and doesn't write any changelog data until 9.596 - those are finished. A reader starts by reading changelog 9.597 - data, then manifest data, followed by filelog data.</para> 9.598 - 9.599 - <para>Since the writer has always finished writing filelog and 9.600 - manifest data before it writes to the changelog, a reader will 9.601 - never read a pointer to a partially written manifest revision 9.602 - from the changelog, and it will never read a pointer to a 9.603 - partially written filelog revision from the manifest.</para> 9.604 - 9.605 - </sect2> 9.606 - <sect2> 9.607 - <title>Concurrent access</title> 9.608 - 9.609 - <para>The read/write ordering and atomicity guarantees mean that 9.610 - Mercurial never needs to <emphasis>lock</emphasis> a 9.611 - repository when it's reading data, even if the repository is 9.612 - being written to while the read is occurring. This has a big 9.613 - effect on scalability; you can have an arbitrary number of 9.614 - Mercurial processes safely reading data from a repository 9.615 - safely all at once, no matter whether it's being written to or 9.616 - not.</para> 9.617 - 9.618 - <para>The lockless nature of reading means that if you're 9.619 - sharing a repository on a multi-user system, you don't need to 9.620 - grant other local users permission to 9.621 - <emphasis>write</emphasis> to your repository in order for 9.622 - them to be able to clone it or pull changes from it; they only 9.623 - need <emphasis>read</emphasis> permission. (This is 9.624 - <emphasis>not</emphasis> a common feature among revision 9.625 - control systems, so don't take it for granted! Most require 9.626 - readers to be able to lock a repository to access it safely, 9.627 - and this requires write permission on at least one directory, 9.628 - which of course makes for all kinds of nasty and annoying 9.629 - security and administrative problems.)</para> 9.630 - 9.631 - <para>Mercurial uses locks to ensure that only one process can 9.632 - write to a repository at a time (the locking mechanism is safe 9.633 - even over filesystems that are notoriously hostile to locking, 9.634 - such as NFS). If a repository is locked, a writer will wait 9.635 - for a while to retry if the repository becomes unlocked, but 9.636 - if the repository remains locked for too long, the process 9.637 - attempting to write will time out after a while. This means 9.638 - that your daily automated scripts won't get stuck forever and 9.639 - pile up if a system crashes unnoticed, for example. (Yes, the 9.640 - timeout is configurable, from zero to infinity.)</para> 9.641 - 9.642 - <sect3> 9.643 - <title>Safe dirstate access</title> 9.644 - 9.645 - <para>As with revision data, Mercurial doesn't take a lock to 9.646 - read the dirstate file; it does acquire a lock to write it. 9.647 - To avoid the possibility of reading a partially written copy 9.648 - of the dirstate file, Mercurial writes to a file with a 9.649 - unique name in the same directory as the dirstate file, then 9.650 - renames the temporary file atomically to 9.651 - <filename>dirstate</filename>. The file named 9.652 - <filename>dirstate</filename> is thus guaranteed to be 9.653 - complete, not partially written.</para> 9.654 - 9.655 - </sect3> 9.656 - </sect2> 9.657 - <sect2> 9.658 - <title>Avoiding seeks</title> 9.659 - 9.660 - <para>Critical to Mercurial's performance is the avoidance of 9.661 - seeks of the disk head, since any seek is far more expensive 9.662 - than even a comparatively large read operation.</para> 9.663 - 9.664 - <para>This is why, for example, the dirstate is stored in a 9.665 - single file. If there were a dirstate file per directory that 9.666 - Mercurial tracked, the disk would seek once per directory. 9.667 - Instead, Mercurial reads the entire single dirstate file in 9.668 - one step.</para> 9.669 - 9.670 - <para>Mercurial also uses a <quote>copy on write</quote> scheme 9.671 - when cloning a repository on local storage. Instead of 9.672 - copying every revlog file from the old repository into the new 9.673 - repository, it makes a <quote>hard link</quote>, which is a 9.674 - shorthand way to say <quote>these two names point to the same 9.675 - file</quote>. When Mercurial is about to write to one of a 9.676 - revlog's files, it checks to see if the number of names 9.677 - pointing at the file is greater than one. If it is, more than 9.678 - one repository is using the file, so Mercurial makes a new 9.679 - copy of the file that is private to this repository.</para> 9.680 - 9.681 - <para>A few revision control developers have pointed out that 9.682 - this idea of making a complete private copy of a file is not 9.683 - very efficient in its use of storage. While this is true, 9.684 - storage is cheap, and this method gives the highest 9.685 - performance while deferring most book-keeping to the operating 9.686 - system. An alternative scheme would most likely reduce 9.687 - performance and increase the complexity of the software, each 9.688 - of which is much more important to the <quote>feel</quote> of 9.689 - day-to-day use.</para> 9.690 - 9.691 - </sect2> 9.692 - <sect2> 9.693 - <title>Other contents of the dirstate</title> 9.694 - 9.695 - <para>Because Mercurial doesn't force you to tell it when you're 9.696 - modifying a file, it uses the dirstate to store some extra 9.697 - information so it can determine efficiently whether you have 9.698 - modified a file. For each file in the working directory, it 9.699 - stores the time that it last modified the file itself, and the 9.700 - size of the file at that time.</para> 9.701 - 9.702 - <para>When you explicitly <command role="hg-cmd">hg 9.703 - add</command>, <command role="hg-cmd">hg remove</command>, 9.704 - <command role="hg-cmd">hg rename</command> or <command 9.705 - role="hg-cmd">hg copy</command> files, Mercurial updates the 9.706 - dirstate so that it knows what to do with those files when you 9.707 - commit.</para> 9.708 - 9.709 - <para>When Mercurial is checking the states of files in the 9.710 - working directory, it first checks a file's modification time. 9.711 - If that has not changed, the file must not have been modified. 9.712 - If the file's size has changed, the file must have been 9.713 - modified. If the modification time has changed, but the size 9.714 - has not, only then does Mercurial need to read the actual 9.715 - contents of the file to see if they've changed. Storing these 9.716 - few extra pieces of information dramatically reduces the 9.717 - amount of data that Mercurial needs to read, which yields 9.718 - large performance improvements compared to other revision 9.719 - control systems.</para> 9.720 - 9.721 - </sect2> 9.722 - </sect1> 9.723 -</chapter> 9.724 - 9.725 -<!-- 9.726 -local variables: 9.727 -sgml-parent-document: ("00book.xml" "book" "chapter") 9.728 -end: 9.729 --->
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/en/ch04-daily.xml Thu Mar 19 20:54:12 2009 -0700 10.3 @@ -0,0 +1,544 @@ 10.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 10.5 + 10.6 +<chapter id="chap:daily"> 10.7 + <?dbhtml filename="mercurial-in-daily-use.html"?> 10.8 + <title>Mercurial in daily use</title> 10.9 + 10.10 + <sect1> 10.11 + <title>Telling Mercurial which files to track</title> 10.12 + 10.13 + <para>Mercurial does not work with files in your repository unless 10.14 + you tell it to manage them. The <command role="hg-cmd">hg 10.15 + status</command> command will tell you which files Mercurial 10.16 + doesn't know about; it uses a 10.17 + <quote><literal>?</literal></quote> to display such 10.18 + files.</para> 10.19 + 10.20 + <para>To tell Mercurial to track a file, use the <command 10.21 + role="hg-cmd">hg add</command> command. Once you have added a 10.22 + file, the entry in the output of <command role="hg-cmd">hg 10.23 + status</command> for that file changes from 10.24 + <quote><literal>?</literal></quote> to 10.25 + <quote><literal>A</literal></quote>.</para> 10.26 + 10.27 + &interaction.daily.files.add; 10.28 + 10.29 + <para>After you run a <command role="hg-cmd">hg commit</command>, 10.30 + the files that you added before the commit will no longer be 10.31 + listed in the output of <command role="hg-cmd">hg 10.32 + status</command>. The reason for this is that <command 10.33 + role="hg-cmd">hg status</command> only tells you about 10.34 + <quote>interesting</quote> files&emdash;those that you have 10.35 + modified or told Mercurial to do something with&emdash;by 10.36 + default. If you have a repository that contains thousands of 10.37 + files, you will rarely want to know about files that Mercurial 10.38 + is tracking, but that have not changed. (You can still get this 10.39 + information; we'll return to this later.)</para> 10.40 + 10.41 + <para>Once you add a file, Mercurial doesn't do anything with it 10.42 + immediately. Instead, it will take a snapshot of the file's 10.43 + state the next time you perform a commit. It will then continue 10.44 + to track the changes you make to the file every time you commit, 10.45 + until you remove the file.</para> 10.46 + 10.47 + <sect2> 10.48 + <title>Explicit versus implicit file naming</title> 10.49 + 10.50 + <para>A useful behaviour that Mercurial has is that if you pass 10.51 + the name of a directory to a command, every Mercurial command 10.52 + will treat this as <quote>I want to operate on every file in 10.53 + this directory and its subdirectories</quote>.</para> 10.54 + 10.55 + &interaction.daily.files.add-dir; 10.56 + 10.57 + <para>Notice in this example that Mercurial printed the names of 10.58 + the files it added, whereas it didn't do so when we added the 10.59 + file named <filename>a</filename> in the earlier 10.60 + example.</para> 10.61 + 10.62 + <para>What's going on is that in the former case, we explicitly 10.63 + named the file to add on the command line, so the assumption 10.64 + that Mercurial makes in such cases is that you know what you 10.65 + were doing, and it doesn't print any output.</para> 10.66 + 10.67 + <para>However, when we <emphasis>imply</emphasis> the names of 10.68 + files by giving the name of a directory, Mercurial takes the 10.69 + extra step of printing the name of each file that it does 10.70 + something with. This makes it more clear what is happening, 10.71 + and reduces the likelihood of a silent and nasty surprise. 10.72 + This behaviour is common to most Mercurial commands.</para> 10.73 + 10.74 + </sect2> 10.75 + <sect2> 10.76 + <title>Aside: Mercurial tracks files, not directories</title> 10.77 + 10.78 + <para>Mercurial does not track directory information. Instead, 10.79 + it tracks the path to a file. Before creating a file, it 10.80 + first creates any missing directory components of the path. 10.81 + After it deletes a file, it then deletes any empty directories 10.82 + that were in the deleted file's path. This sounds like a 10.83 + trivial distinction, but it has one minor practical 10.84 + consequence: it is not possible to represent a completely 10.85 + empty directory in Mercurial.</para> 10.86 + 10.87 + <para>Empty directories are rarely useful, and there are 10.88 + unintrusive workarounds that you can use to achieve an 10.89 + appropriate effect. The developers of Mercurial thus felt 10.90 + that the complexity that would be required to manage empty 10.91 + directories was not worth the limited benefit this feature 10.92 + would bring.</para> 10.93 + 10.94 + <para>If you need an empty directory in your repository, there 10.95 + are a few ways to achieve this. One is to create a directory, 10.96 + then <command role="hg-cmd">hg add</command> a 10.97 + <quote>hidden</quote> file to that directory. On Unix-like 10.98 + systems, any file name that begins with a period 10.99 + (<quote><literal>.</literal></quote>) is treated as hidden by 10.100 + most commands and GUI tools. This approach is illustrated 10.101 + below.</para> 10.102 + 10.103 +&interaction.daily.files.hidden; 10.104 + 10.105 + <para>Another way to tackle a need for an empty directory is to 10.106 + simply create one in your automated build scripts before they 10.107 + will need it.</para> 10.108 + 10.109 + </sect2> 10.110 + </sect1> 10.111 + <sect1> 10.112 + <title>How to stop tracking a file</title> 10.113 + 10.114 + <para>Once you decide that a file no longer belongs in your 10.115 + repository, use the <command role="hg-cmd">hg remove</command> 10.116 + command; this deletes the file, and tells Mercurial to stop 10.117 + tracking it. A removed file is represented in the output of 10.118 + <command role="hg-cmd">hg status</command> with a 10.119 + <quote><literal>R</literal></quote>.</para> 10.120 + 10.121 + &interaction.daily.files.remove; 10.122 + 10.123 + <para>After you <command role="hg-cmd">hg remove</command> a file, 10.124 + Mercurial will no longer track changes to that file, even if you 10.125 + recreate a file with the same name in your working directory. 10.126 + If you do recreate a file with the same name and want Mercurial 10.127 + to track the new file, simply <command role="hg-cmd">hg 10.128 + add</command> it. Mercurial will know that the newly added 10.129 + file is not related to the old file of the same name.</para> 10.130 + 10.131 + <sect2> 10.132 + <title>Removing a file does not affect its history</title> 10.133 + 10.134 + <para>It is important to understand that removing a file has 10.135 + only two effects.</para> 10.136 + <itemizedlist> 10.137 + <listitem><para>It removes the current version of the file 10.138 + from the working directory.</para> 10.139 + </listitem> 10.140 + <listitem><para>It stops Mercurial from tracking changes to 10.141 + the file, from the time of the next commit.</para> 10.142 + </listitem></itemizedlist> 10.143 + <para>Removing a file <emphasis>does not</emphasis> in any way 10.144 + alter the <emphasis>history</emphasis> of the file.</para> 10.145 + 10.146 + <para>If you update the working directory to a changeset in 10.147 + which a file that you have removed was still tracked, it will 10.148 + reappear in the working directory, with the contents it had 10.149 + when you committed that changeset. If you then update the 10.150 + working directory to a later changeset, in which the file had 10.151 + been removed, Mercurial will once again remove the file from 10.152 + the working directory.</para> 10.153 + 10.154 + </sect2> 10.155 + <sect2> 10.156 + <title>Missing files</title> 10.157 + 10.158 + <para>Mercurial considers a file that you have deleted, but not 10.159 + used <command role="hg-cmd">hg remove</command> to delete, to 10.160 + be <emphasis>missing</emphasis>. A missing file is 10.161 + represented with <quote><literal>!</literal></quote> in the 10.162 + output of <command role="hg-cmd">hg status</command>. 10.163 + Mercurial commands will not generally do anything with missing 10.164 + files.</para> 10.165 + 10.166 + &interaction.daily.files.missing; 10.167 + 10.168 + <para>If your repository contains a file that <command 10.169 + role="hg-cmd">hg status</command> reports as missing, and 10.170 + you want the file to stay gone, you can run <command 10.171 + role="hg-cmd">hg remove <option 10.172 + role="hg-opt-remove">--after</option></command> at any 10.173 + time later on, to tell Mercurial that you really did mean to 10.174 + remove the file.</para> 10.175 + 10.176 + &interaction.daily.files.remove-after; 10.177 + 10.178 + <para>On the other hand, if you deleted the missing file by 10.179 + accident, give <command role="hg-cmd">hg revert</command> the 10.180 + name of the file to recover. It will reappear, in unmodified 10.181 + form.</para> 10.182 + 10.183 +&interaction.daily.files.recover-missing; 10.184 + 10.185 + </sect2> 10.186 + <sect2> 10.187 + <title>Aside: why tell Mercurial explicitly to remove a 10.188 + file?</title> 10.189 + 10.190 + <para>You might wonder why Mercurial requires you to explicitly 10.191 + tell it that you are deleting a file. Early during the 10.192 + development of Mercurial, it let you delete a file however you 10.193 + pleased; Mercurial would notice the absence of the file 10.194 + automatically when you next ran a <command role="hg-cmd">hg 10.195 + commit</command>, and stop tracking the file. In practice, 10.196 + this made it too easy to accidentally remove a file without 10.197 + noticing.</para> 10.198 + 10.199 + </sect2> 10.200 + <sect2> 10.201 + <title>Useful shorthand&emdash;adding and removing files in one 10.202 + step</title> 10.203 + 10.204 + <para>Mercurial offers a combination command, <command 10.205 + role="hg-cmd">hg addremove</command>, that adds untracked 10.206 + files and marks missing files as removed.</para> 10.207 + 10.208 + &interaction.daily.files.addremove; 10.209 + 10.210 + <para>The <command role="hg-cmd">hg commit</command> command 10.211 + also provides a <option role="hg-opt-commit">-A</option> 10.212 + option that performs this same add-and-remove, immediately 10.213 + followed by a commit.</para> 10.214 + 10.215 + &interaction.daily.files.commit-addremove; 10.216 + 10.217 + </sect2> 10.218 + </sect1> 10.219 + <sect1> 10.220 + <title>Copying files</title> 10.221 + 10.222 + <para>Mercurial provides a <command role="hg-cmd">hg 10.223 + copy</command> command that lets you make a new copy of a 10.224 + file. When you copy a file using this command, Mercurial makes 10.225 + a record of the fact that the new file is a copy of the original 10.226 + file. It treats these copied files specially when you merge 10.227 + your work with someone else's.</para> 10.228 + 10.229 + <sect2> 10.230 + <title>The results of copying during a merge</title> 10.231 + 10.232 + <para>What happens during a merge is that changes 10.233 + <quote>follow</quote> a copy. To best illustrate what this 10.234 + means, let's create an example. We'll start with the usual 10.235 + tiny repository that contains a single file.</para> 10.236 + 10.237 + &interaction.daily.copy.init; 10.238 + 10.239 + <para>We need to do some work in 10.240 + parallel, so that we'll have something to merge. So let's 10.241 + clone our repository.</para> 10.242 + 10.243 + &interaction.daily.copy.clone; 10.244 + 10.245 + <para>Back in our initial repository, let's use the <command 10.246 + role="hg-cmd">hg copy</command> command to make a copy of 10.247 + the first file we created.</para> 10.248 + 10.249 + &interaction.daily.copy.copy; 10.250 + 10.251 + <para>If we look at the output of the <command role="hg-cmd">hg 10.252 + status</command> command afterwards, the copied file looks 10.253 + just like a normal added file.</para> 10.254 + 10.255 + &interaction.daily.copy.status; 10.256 + 10.257 + <para>But if we pass the <option 10.258 + role="hg-opt-status">-C</option> option to <command 10.259 + role="hg-cmd">hg status</command>, it prints another line of 10.260 + output: this is the file that our newly-added file was copied 10.261 + <emphasis>from</emphasis>.</para> 10.262 + 10.263 + &interaction.daily.copy.status-copy; 10.264 + 10.265 + <para>Now, back in the repository we cloned, let's make a change 10.266 + in parallel. We'll add a line of content to the original file 10.267 + that we created.</para> 10.268 + 10.269 + &interaction.daily.copy.other; 10.270 + 10.271 + <para>Now we have a modified <filename>file</filename> in this 10.272 + repository. When we pull the changes from the first 10.273 + repository, and merge the two heads, Mercurial will propagate 10.274 + the changes that we made locally to <filename>file</filename> 10.275 + into its copy, <filename>new-file</filename>.</para> 10.276 + 10.277 + &interaction.daily.copy.merge; 10.278 + 10.279 + </sect2> 10.280 + <sect2 id="sec:daily:why-copy"> 10.281 + <title>Why should changes follow copies?</title> 10.282 + 10.283 + <para>This behaviour, of changes to a file propagating out to 10.284 + copies of the file, might seem esoteric, but in most cases 10.285 + it's highly desirable.</para> 10.286 + 10.287 + <para>First of all, remember that this propagation 10.288 + <emphasis>only</emphasis> happens when you merge. So if you 10.289 + <command role="hg-cmd">hg copy</command> a file, and 10.290 + subsequently modify the original file during the normal course 10.291 + of your work, nothing will happen.</para> 10.292 + 10.293 + <para>The second thing to know is that modifications will only 10.294 + propagate across a copy as long as the repository that you're 10.295 + pulling changes from <emphasis>doesn't know</emphasis> about 10.296 + the copy.</para> 10.297 + 10.298 + <para>The reason that Mercurial does this is as follows. Let's 10.299 + say I make an important bug fix in a source file, and commit 10.300 + my changes. Meanwhile, you've decided to <command 10.301 + role="hg-cmd">hg copy</command> the file in your repository, 10.302 + without knowing about the bug or having seen the fix, and you 10.303 + have started hacking on your copy of the file.</para> 10.304 + 10.305 + <para>If you pulled and merged my changes, and Mercurial 10.306 + <emphasis>didn't</emphasis> propagate changes across copies, 10.307 + your source file would now contain the bug, and unless you 10.308 + remembered to propagate the bug fix by hand, the bug would 10.309 + <emphasis>remain</emphasis> in your copy of the file.</para> 10.310 + 10.311 + <para>By automatically propagating the change that fixed the bug 10.312 + from the original file to the copy, Mercurial prevents this 10.313 + class of problem. To my knowledge, Mercurial is the 10.314 + <emphasis>only</emphasis> revision control system that 10.315 + propagates changes across copies like this.</para> 10.316 + 10.317 + <para>Once your change history has a record that the copy and 10.318 + subsequent merge occurred, there's usually no further need to 10.319 + propagate changes from the original file to the copied file, 10.320 + and that's why Mercurial only propagates changes across copies 10.321 + until this point, and no further.</para> 10.322 + 10.323 + </sect2> 10.324 + <sect2> 10.325 + <title>How to make changes <emphasis>not</emphasis> follow a 10.326 + copy</title> 10.327 + 10.328 + <para>If, for some reason, you decide that this business of 10.329 + automatically propagating changes across copies is not for 10.330 + you, simply use your system's normal file copy command (on 10.331 + Unix-like systems, that's <command>cp</command>) to make a 10.332 + copy of a file, then <command role="hg-cmd">hg add</command> 10.333 + the new copy by hand. Before you do so, though, please do 10.334 + reread section <xref linkend="sec:daily:why-copy"/>, and make 10.335 + an informed 10.336 + decision that this behaviour is not appropriate to your 10.337 + specific case.</para> 10.338 + 10.339 + </sect2> 10.340 + <sect2> 10.341 + <title>Behaviour of the <command role="hg-cmd">hg copy</command> 10.342 + command</title> 10.343 + 10.344 + <para>When you use the <command role="hg-cmd">hg copy</command> 10.345 + command, Mercurial makes a copy of each source file as it 10.346 + currently stands in the working directory. This means that if 10.347 + you make some modifications to a file, then <command 10.348 + role="hg-cmd">hg copy</command> it without first having 10.349 + committed those changes, the new copy will also contain the 10.350 + modifications you have made up until that point. (I find this 10.351 + behaviour a little counterintuitive, which is why I mention it 10.352 + here.)</para> 10.353 + 10.354 + <para>The <command role="hg-cmd">hg copy</command> command acts 10.355 + similarly to the Unix <command>cp</command> command (you can 10.356 + use the <command role="hg-cmd">hg cp</command> alias if you 10.357 + prefer). The last argument is the 10.358 + <emphasis>destination</emphasis>, and all prior arguments are 10.359 + <emphasis>sources</emphasis>. If you pass it a single file as 10.360 + the source, and the destination does not exist, it creates a 10.361 + new file with that name.</para> 10.362 + 10.363 + &interaction.daily.copy.simple; 10.364 + 10.365 + <para>If the destination is a directory, Mercurial copies its 10.366 + sources into that directory.</para> 10.367 + 10.368 + &interaction.daily.copy.dir-dest; 10.369 + 10.370 + <para>Copying a directory is 10.371 + recursive, and preserves the directory structure of the 10.372 + source.</para> 10.373 + 10.374 + &interaction.daily.copy.dir-src; 10.375 + 10.376 + <para>If the source and destination are both directories, the 10.377 + source tree is recreated in the destination directory.</para> 10.378 + 10.379 + &interaction.daily.copy.dir-src-dest; 10.380 + 10.381 + <para>As with the <command role="hg-cmd">hg rename</command> 10.382 + command, if you copy a file manually and then want Mercurial 10.383 + to know that you've copied the file, simply use the <option 10.384 + role="hg-opt-copy">--after</option> option to <command 10.385 + role="hg-cmd">hg copy</command>.</para> 10.386 + 10.387 + &interaction.daily.copy.after; 10.388 + 10.389 + </sect2> 10.390 + </sect1> 10.391 + <sect1> 10.392 + <title>Renaming files</title> 10.393 + 10.394 + <para>It's rather more common to need to rename a file than to 10.395 + make a copy of it. The reason I discussed the <command 10.396 + role="hg-cmd">hg copy</command> command before talking about 10.397 + renaming files is that Mercurial treats a rename in essentially 10.398 + the same way as a copy. Therefore, knowing what Mercurial does 10.399 + when you copy a file tells you what to expect when you rename a 10.400 + file.</para> 10.401 + 10.402 + <para>When you use the <command role="hg-cmd">hg rename</command> 10.403 + command, Mercurial makes a copy of each source file, then 10.404 + deletes it and marks the file as removed.</para> 10.405 + 10.406 + &interaction.daily.rename.rename; 10.407 + 10.408 + <para>The <command role="hg-cmd">hg status</command> command shows 10.409 + the newly copied file as added, and the copied-from file as 10.410 + removed.</para> 10.411 + 10.412 + &interaction.daily.rename.status; 10.413 + 10.414 + <para>As with the results of a <command role="hg-cmd">hg 10.415 + copy</command>, we must use the <option 10.416 + role="hg-opt-status">-C</option> option to <command 10.417 + role="hg-cmd">hg status</command> to see that the added file 10.418 + is really being tracked by Mercurial as a copy of the original, 10.419 + now removed, file.</para> 10.420 + 10.421 + &interaction.daily.rename.status-copy; 10.422 + 10.423 + <para>As with <command role="hg-cmd">hg remove</command> and 10.424 + <command role="hg-cmd">hg copy</command>, you can tell Mercurial 10.425 + about a rename after the fact using the <option 10.426 + role="hg-opt-rename">--after</option> option. In most other 10.427 + respects, the behaviour of the <command role="hg-cmd">hg 10.428 + rename</command> command, and the options it accepts, are 10.429 + similar to the <command role="hg-cmd">hg copy</command> 10.430 + command.</para> 10.431 + 10.432 + <sect2> 10.433 + <title>Renaming files and merging changes</title> 10.434 + 10.435 + <para>Since Mercurial's rename is implemented as 10.436 + copy-and-remove, the same propagation of changes happens when 10.437 + you merge after a rename as after a copy.</para> 10.438 + 10.439 + <para>If I modify a file, and you rename it to a new name, and 10.440 + then we merge our respective changes, my modifications to the 10.441 + file under its original name will be propagated into the file 10.442 + under its new name. (This is something you might expect to 10.443 + <quote>simply work,</quote> but not all revision control 10.444 + systems actually do this.)</para> 10.445 + 10.446 + <para>Whereas having changes follow a copy is a feature where 10.447 + you can perhaps nod and say <quote>yes, that might be 10.448 + useful,</quote> it should be clear that having them follow a 10.449 + rename is definitely important. Without this facility, it 10.450 + would simply be too easy for changes to become orphaned when 10.451 + files are renamed.</para> 10.452 + 10.453 + </sect2> 10.454 + <sect2> 10.455 + <title>Divergent renames and merging</title> 10.456 + 10.457 + <para>The case of diverging names occurs when two developers 10.458 + start with a file&emdash;let's call it 10.459 + <filename>foo</filename>&emdash;in their respective 10.460 + repositories.</para> 10.461 + 10.462 + &interaction.rename.divergent.clone; 10.463 + 10.464 + <para>Anne renames the file to <filename>bar</filename>.</para> 10.465 + 10.466 + &interaction.rename.divergent.rename.anne; 10.467 + 10.468 + <para>Meanwhile, Bob renames it to 10.469 + <filename>quux</filename>.</para> 10.470 + 10.471 + &interaction.rename.divergent.rename.bob; 10.472 + 10.473 + <para>I like to think of this as a conflict because each 10.474 + developer has expressed different intentions about what the 10.475 + file ought to be named.</para> 10.476 + 10.477 + <para>What do you think should happen when they merge their 10.478 + work? Mercurial's actual behaviour is that it always preserves 10.479 + <emphasis>both</emphasis> names when it merges changesets that 10.480 + contain divergent renames.</para> 10.481 + 10.482 + &interaction.rename.divergent.merge; 10.483 + 10.484 + <para>Notice that Mercurial does warn about the divergent 10.485 + renames, but it leaves it up to you to do something about the 10.486 + divergence after the merge.</para> 10.487 + 10.488 + </sect2> 10.489 + <sect2> 10.490 + <title>Convergent renames and merging</title> 10.491 + 10.492 + <para>Another kind of rename conflict occurs when two people 10.493 + choose to rename different <emphasis>source</emphasis> files 10.494 + to the same <emphasis>destination</emphasis>. In this case, 10.495 + Mercurial runs its normal merge machinery, and lets you guide 10.496 + it to a suitable resolution.</para> 10.497 + 10.498 + </sect2> 10.499 + <sect2> 10.500 + <title>Other name-related corner cases</title> 10.501 + 10.502 + <para>Mercurial has a longstanding bug in which it fails to 10.503 + handle a merge where one side has a file with a given name, 10.504 + while another has a directory with the same name. This is 10.505 + documented as <ulink role="hg-bug" 10.506 + url="http://www.selenic.com/mercurial/bts/issue29">issue 10.507 + 29</ulink>.</para> 10.508 + 10.509 + &interaction.issue29.go; 10.510 + 10.511 + </sect2> 10.512 + </sect1> 10.513 + <sect1> 10.514 + <title>Recovering from mistakes</title> 10.515 + 10.516 + <para>Mercurial has some useful commands that will help you to 10.517 + recover from some common mistakes.</para> 10.518 + 10.519 + <para>The <command role="hg-cmd">hg revert</command> command lets 10.520 + you undo changes that you have made to your working directory. 10.521 + For example, if you <command role="hg-cmd">hg add</command> a 10.522 + file by accident, just run <command role="hg-cmd">hg 10.523 + revert</command> with the name of the file you added, and 10.524 + while the file won't be touched in any way, it won't be tracked 10.525 + for adding by Mercurial any longer, either. You can also use 10.526 + <command role="hg-cmd">hg revert</command> to get rid of 10.527 + erroneous changes to a file.</para> 10.528 + 10.529 + <para>It's useful to remember that the <command role="hg-cmd">hg 10.530 + revert</command> command is useful for changes that you have 10.531 + not yet committed. Once you've committed a change, if you 10.532 + decide it was a mistake, you can still do something about it, 10.533 + though your options may be more limited.</para> 10.534 + 10.535 + <para>For more information about the <command role="hg-cmd">hg 10.536 + revert</command> command, and details about how to deal with 10.537 + changes you have already committed, see chapter <xref 10.538 + linkend="chap:undo"/>.</para> 10.539 + 10.540 + </sect1> 10.541 +</chapter> 10.542 + 10.543 +<!-- 10.544 +local variables: 10.545 +sgml-parent-document: ("00book.xml" "book" "chapter") 10.546 +end: 10.547 +-->
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/en/ch05-collab.xml Thu Mar 19 20:54:12 2009 -0700 11.3 @@ -0,0 +1,1434 @@ 11.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 11.5 + 11.6 +<chapter id="cha:collab"> 11.7 + <?dbhtml filename="collaborating-with-other-people.html"?> 11.8 + <title>Collaborating with other people</title> 11.9 + 11.10 + <para>As a completely decentralised tool, Mercurial doesn't impose 11.11 + any policy on how people ought to work with each other. However, 11.12 + if you're new to distributed revision control, it helps to have 11.13 + some tools and examples in mind when you're thinking about 11.14 + possible workflow models.</para> 11.15 + 11.16 + <sect1> 11.17 + <title>Mercurial's web interface</title> 11.18 + 11.19 + <para>Mercurial has a powerful web interface that provides several 11.20 + useful capabilities.</para> 11.21 + 11.22 + <para>For interactive use, the web interface lets you browse a 11.23 + single repository or a collection of repositories. You can view 11.24 + the history of a repository, examine each change (comments and 11.25 + diffs), and view the contents of each directory and file.</para> 11.26 + 11.27 + <para>Also for human consumption, the web interface provides an 11.28 + RSS feed of the changes in a repository. This lets you 11.29 + <quote>subscribe</quote> to a repository using your favourite 11.30 + feed reader, and be automatically notified of activity in that 11.31 + repository as soon as it happens. I find this capability much 11.32 + more convenient than the model of subscribing to a mailing list 11.33 + to which notifications are sent, as it requires no additional 11.34 + configuration on the part of whoever is serving the 11.35 + repository.</para> 11.36 + 11.37 + <para>The web interface also lets remote users clone a repository, 11.38 + pull changes from it, and (when the server is configured to 11.39 + permit it) push changes back to it. Mercurial's HTTP tunneling 11.40 + protocol aggressively compresses data, so that it works 11.41 + efficiently even over low-bandwidth network connections.</para> 11.42 + 11.43 + <para>The easiest way to get started with the web interface is to 11.44 + use your web browser to visit an existing repository, such as 11.45 + the master Mercurial repository at <ulink 11.46 + url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para> 11.47 + 11.48 + <para>If you're interested in providing a web interface to your 11.49 + own repositories, Mercurial provides two ways to do this. The 11.50 + first is using the <command role="hg-cmd">hg serve</command> 11.51 + command, which is best suited to short-term 11.52 + <quote>lightweight</quote> serving. See section <xref 11.53 + linkend="sec:collab:serve"/> below for details of how to use 11.54 + this command. If you have a long-lived repository that you'd 11.55 + like to make permanently available, Mercurial has built-in 11.56 + support for the CGI (Common Gateway Interface) standard, which 11.57 + all common web servers support. See section <xref 11.58 + linkend="sec:collab:cgi"/> for details of CGI 11.59 + configuration.</para> 11.60 + 11.61 + </sect1> 11.62 + <sect1> 11.63 + <title>Collaboration models</title> 11.64 + 11.65 + <para>With a suitably flexible tool, making decisions about 11.66 + workflow is much more of a social engineering challenge than a 11.67 + technical one. Mercurial imposes few limitations on how you can 11.68 + structure the flow of work in a project, so it's up to you and 11.69 + your group to set up and live with a model that matches your own 11.70 + particular needs.</para> 11.71 + 11.72 + <sect2> 11.73 + <title>Factors to keep in mind</title> 11.74 + 11.75 + <para>The most important aspect of any model that you must keep 11.76 + in mind is how well it matches the needs and capabilities of 11.77 + the people who will be using it. This might seem 11.78 + self-evident; even so, you still can't afford to forget it for 11.79 + a moment.</para> 11.80 + 11.81 + <para>I once put together a workflow model that seemed to make 11.82 + perfect sense to me, but that caused a considerable amount of 11.83 + consternation and strife within my development team. In spite 11.84 + of my attempts to explain why we needed a complex set of 11.85 + branches, and how changes ought to flow between them, a few 11.86 + team members revolted. Even though they were smart people, 11.87 + they didn't want to pay attention to the constraints we were 11.88 + operating under, or face the consequences of those constraints 11.89 + in the details of the model that I was advocating.</para> 11.90 + 11.91 + <para>Don't sweep foreseeable social or technical problems under 11.92 + the rug. Whatever scheme you put into effect, you should plan 11.93 + for mistakes and problem scenarios. Consider adding automated 11.94 + machinery to prevent, or quickly recover from, trouble that 11.95 + you can anticipate. As an example, if you intend to have a 11.96 + branch with not-for-release changes in it, you'd do well to 11.97 + think early about the possibility that someone might 11.98 + accidentally merge those changes into a release branch. You 11.99 + could avoid this particular problem by writing a hook that 11.100 + prevents changes from being merged from an inappropriate 11.101 + branch.</para> 11.102 + 11.103 + </sect2> 11.104 + <sect2> 11.105 + <title>Informal anarchy</title> 11.106 + 11.107 + <para>I wouldn't suggest an <quote>anything goes</quote> 11.108 + approach as something sustainable, but it's a model that's 11.109 + easy to grasp, and it works perfectly well in a few unusual 11.110 + situations.</para> 11.111 + 11.112 + <para>As one example, many projects have a loose-knit group of 11.113 + collaborators who rarely physically meet each other. Some 11.114 + groups like to overcome the isolation of working at a distance 11.115 + by organising occasional <quote>sprints</quote>. In a sprint, 11.116 + a number of people get together in a single location (a 11.117 + company's conference room, a hotel meeting room, that kind of 11.118 + place) and spend several days more or less locked in there, 11.119 + hacking intensely on a handful of projects.</para> 11.120 + 11.121 + <para>A sprint is the perfect place to use the <command 11.122 + role="hg-cmd">hg serve</command> command, since <command 11.123 + role="hg-cmd">hg serve</command> does not require any fancy 11.124 + server infrastructure. You can get started with <command 11.125 + role="hg-cmd">hg serve</command> in moments, by reading 11.126 + section <xref linkend="sec:collab:serve"/> below. Then simply 11.127 + tell 11.128 + the person next to you that you're running a server, send the 11.129 + URL to them in an instant message, and you immediately have a 11.130 + quick-turnaround way to work together. They can type your URL 11.131 + into their web browser and quickly review your changes; or 11.132 + they can pull a bugfix from you and verify it; or they can 11.133 + clone a branch containing a new feature and try it out.</para> 11.134 + 11.135 + <para>The charm, and the problem, with doing things in an ad hoc 11.136 + fashion like this is that only people who know about your 11.137 + changes, and where they are, can see them. Such an informal 11.138 + approach simply doesn't scale beyond a handful people, because 11.139 + each individual needs to know about $n$ different repositories 11.140 + to pull from.</para> 11.141 + 11.142 + </sect2> 11.143 + <sect2> 11.144 + <title>A single central repository</title> 11.145 + 11.146 + <para>For smaller projects migrating from a centralised revision 11.147 + control tool, perhaps the easiest way to get started is to 11.148 + have changes flow through a single shared central repository. 11.149 + This is also the most common <quote>building block</quote> for 11.150 + more ambitious workflow schemes.</para> 11.151 + 11.152 + <para>Contributors start by cloning a copy of this repository. 11.153 + They can pull changes from it whenever they need to, and some 11.154 + (perhaps all) developers have permission to push a change back 11.155 + when they're ready for other people to see it.</para> 11.156 + 11.157 + <para>Under this model, it can still often make sense for people 11.158 + to pull changes directly from each other, without going 11.159 + through the central repository. Consider a case in which I 11.160 + have a tentative bug fix, but I am worried that if I were to 11.161 + publish it to the central repository, it might subsequently 11.162 + break everyone else's trees as they pull it. To reduce the 11.163 + potential for damage, I can ask you to clone my repository 11.164 + into a temporary repository of your own and test it. This 11.165 + lets us put off publishing the potentially unsafe change until 11.166 + it has had a little testing.</para> 11.167 + 11.168 + <para>In this kind of scenario, people usually use the 11.169 + <command>ssh</command> protocol to securely push changes to 11.170 + the central repository, as documented in section <xref 11.171 + linkend="sec:collab:ssh"/>. It's also 11.172 + usual to publish a read-only copy of the repository over HTTP 11.173 + using CGI, as in section <xref linkend="sec:collab:cgi"/>. 11.174 + Publishing over HTTP 11.175 + satisfies the needs of people who don't have push access, and 11.176 + those who want to use web browsers to browse the repository's 11.177 + history.</para> 11.178 + 11.179 + </sect2> 11.180 + <sect2> 11.181 + <title>Working with multiple branches</title> 11.182 + 11.183 + <para>Projects of any significant size naturally tend to make 11.184 + progress on several fronts simultaneously. In the case of 11.185 + software, it's common for a project to go through periodic 11.186 + official releases. A release might then go into 11.187 + <quote>maintenance mode</quote> for a while after its first 11.188 + publication; maintenance releases tend to contain only bug 11.189 + fixes, not new features. In parallel with these maintenance 11.190 + releases, one or more future releases may be under 11.191 + development. People normally use the word 11.192 + <quote>branch</quote> to refer to one of these many slightly 11.193 + different directions in which development is 11.194 + proceeding.</para> 11.195 + 11.196 + <para>Mercurial is particularly well suited to managing a number 11.197 + of simultaneous, but not identical, branches. Each 11.198 + <quote>development direction</quote> can live in its own 11.199 + central repository, and you can merge changes from one to 11.200 + another as the need arises. Because repositories are 11.201 + independent of each other, unstable changes in a development 11.202 + branch will never affect a stable branch unless someone 11.203 + explicitly merges those changes in.</para> 11.204 + 11.205 + <para>Here's an example of how this can work in practice. Let's 11.206 + say you have one <quote>main branch</quote> on a central 11.207 + server.</para> 11.208 + 11.209 + &interaction.branching.init; 11.210 + 11.211 + <para>People clone it, make changes locally, test them, and push 11.212 + them back.</para> 11.213 + 11.214 + <para>Once the main branch reaches a release milestone, you can 11.215 + use the <command role="hg-cmd">hg tag</command> command to 11.216 + give a permanent name to the milestone revision.</para> 11.217 + 11.218 + &interaction.branching.tag; 11.219 + 11.220 + <para>Let's say some ongoing 11.221 + development occurs on the main branch.</para> 11.222 + 11.223 + &interaction.branching.main; 11.224 + 11.225 + <para>Using the tag that was recorded at the milestone, people 11.226 + who clone that repository at any time in the future can use 11.227 + <command role="hg-cmd">hg update</command> to get a copy of 11.228 + the working directory exactly as it was when that tagged 11.229 + revision was committed.</para> 11.230 + 11.231 + &interaction.branching.update; 11.232 + 11.233 + <para>In addition, immediately after the main branch is tagged, 11.234 + someone can then clone the main branch on the server to a new 11.235 + <quote>stable</quote> branch, also on the server.</para> 11.236 + 11.237 + &interaction.branching.clone; 11.238 + 11.239 + <para>Someone who needs to make a change to the stable branch 11.240 + can then clone <emphasis>that</emphasis> repository, make 11.241 + their changes, commit, and push their changes back there.</para> 11.242 + 11.243 + &interaction.branching.stable; 11.244 + 11.245 + <para>Because Mercurial repositories are independent, and 11.246 + Mercurial doesn't move changes around automatically, the 11.247 + stable and main branches are <emphasis>isolated</emphasis> 11.248 + from each other. The changes that you made on the main branch 11.249 + don't <quote>leak</quote> to the stable branch, and vice 11.250 + versa.</para> 11.251 + 11.252 + <para>You'll often want all of your bugfixes on the stable 11.253 + branch to show up on the main branch, too. Rather than 11.254 + rewrite a bugfix on the main branch, you can simply pull and 11.255 + merge changes from the stable to the main branch, and 11.256 + Mercurial will bring those bugfixes in for you.</para> 11.257 + 11.258 + &interaction.branching.merge; 11.259 + 11.260 + <para>The main branch will still contain changes that are not on 11.261 + the stable branch, but it will also contain all of the 11.262 + bugfixes from the stable branch. The stable branch remains 11.263 + unaffected by these changes.</para> 11.264 + 11.265 + </sect2> 11.266 + <sect2> 11.267 + <title>Feature branches</title> 11.268 + 11.269 + <para>For larger projects, an effective way to manage change is 11.270 + to break up a team into smaller groups. Each group has a 11.271 + shared branch of its own, cloned from a single 11.272 + <quote>master</quote> branch used by the entire project. 11.273 + People working on an individual branch are typically quite 11.274 + isolated from developments on other branches.</para> 11.275 + 11.276 + <informalfigure id="fig:collab:feature-branches"> 11.277 + <mediaobject><imageobject><imagedata 11.278 + fileref="feature-branches"/></imageobject><textobject><phrase>XXX 11.279 + add text</phrase></textobject><caption><para>Feature 11.280 + branches</para></caption></mediaobject> 11.281 + </informalfigure> 11.282 + 11.283 + <para>When a particular feature is deemed to be in suitable 11.284 + shape, someone on that feature team pulls and merges from the 11.285 + master branch into the feature branch, then pushes back up to 11.286 + the master branch.</para> 11.287 + 11.288 + </sect2> 11.289 + <sect2> 11.290 + <title>The release train</title> 11.291 + 11.292 + <para>Some projects are organised on a <quote>train</quote> 11.293 + basis: a release is scheduled to happen every few months, and 11.294 + whatever features are ready when the <quote>train</quote> is 11.295 + ready to leave are allowed in.</para> 11.296 + 11.297 + <para>This model resembles working with feature branches. The 11.298 + difference is that when a feature branch misses a train, 11.299 + someone on the feature team pulls and merges the changes that 11.300 + went out on that train release into the feature branch, and 11.301 + the team continues its work on top of that release so that 11.302 + their feature can make the next release.</para> 11.303 + 11.304 + </sect2> 11.305 + <sect2> 11.306 + <title>The Linux kernel model</title> 11.307 + 11.308 + <para>The development of the Linux kernel has a shallow 11.309 + hierarchical structure, surrounded by a cloud of apparent 11.310 + chaos. Because most Linux developers use 11.311 + <command>git</command>, a distributed revision control tool 11.312 + with capabilities similar to Mercurial, it's useful to 11.313 + describe the way work flows in that environment; if you like 11.314 + the ideas, the approach translates well across tools.</para> 11.315 + 11.316 + <para>At the center of the community sits Linus Torvalds, the 11.317 + creator of Linux. He publishes a single source repository 11.318 + that is considered the <quote>authoritative</quote> current 11.319 + tree by the entire developer community. Anyone can clone 11.320 + Linus's tree, but he is very choosy about whose trees he pulls 11.321 + from.</para> 11.322 + 11.323 + <para>Linus has a number of <quote>trusted lieutenants</quote>. 11.324 + As a general rule, he pulls whatever changes they publish, in 11.325 + most cases without even reviewing those changes. Some of 11.326 + those lieutenants are generally agreed to be 11.327 + <quote>maintainers</quote>, responsible for specific 11.328 + subsystems within the kernel. If a random kernel hacker wants 11.329 + to make a change to a subsystem that they want to end up in 11.330 + Linus's tree, they must find out who the subsystem's 11.331 + maintainer is, and ask that maintainer to take their change. 11.332 + If the maintainer reviews their changes and agrees to take 11.333 + them, they'll pass them along to Linus in due course.</para> 11.334 + 11.335 + <para>Individual lieutenants have their own approaches to 11.336 + reviewing, accepting, and publishing changes; and for deciding 11.337 + when to feed them to Linus. In addition, there are several 11.338 + well known branches that people use for different purposes. 11.339 + For example, a few people maintain <quote>stable</quote> 11.340 + repositories of older versions of the kernel, to which they 11.341 + apply critical fixes as needed. Some maintainers publish 11.342 + multiple trees: one for experimental changes; one for changes 11.343 + that they are about to feed upstream; and so on. Others just 11.344 + publish a single tree.</para> 11.345 + 11.346 + <para>This model has two notable features. The first is that 11.347 + it's <quote>pull only</quote>. You have to ask, convince, or 11.348 + beg another developer to take a change from you, because there 11.349 + are almost no trees to which more than one person can push, 11.350 + and there's no way to push changes into a tree that someone 11.351 + else controls.</para> 11.352 + 11.353 + <para>The second is that it's based on reputation and acclaim. 11.354 + If you're an unknown, Linus will probably ignore changes from 11.355 + you without even responding. But a subsystem maintainer will 11.356 + probably review them, and will likely take them if they pass 11.357 + their criteria for suitability. The more <quote>good</quote> 11.358 + changes you contribute to a maintainer, the more likely they 11.359 + are to trust your judgment and accept your changes. If you're 11.360 + well-known and maintain a long-lived branch for something 11.361 + Linus hasn't yet accepted, people with similar interests may 11.362 + pull your changes regularly to keep up with your work.</para> 11.363 + 11.364 + <para>Reputation and acclaim don't necessarily cross subsystem 11.365 + or <quote>people</quote> boundaries. If you're a respected 11.366 + but specialised storage hacker, and you try to fix a 11.367 + networking bug, that change will receive a level of scrutiny 11.368 + from a network maintainer comparable to a change from a 11.369 + complete stranger.</para> 11.370 + 11.371 + <para>To people who come from more orderly project backgrounds, 11.372 + the comparatively chaotic Linux kernel development process 11.373 + often seems completely insane. It's subject to the whims of 11.374 + individuals; people make sweeping changes whenever they deem 11.375 + it appropriate; and the pace of development is astounding. 11.376 + And yet Linux is a highly successful, well-regarded piece of 11.377 + software.</para> 11.378 + 11.379 + </sect2> 11.380 + <sect2> 11.381 + <title>Pull-only versus shared-push collaboration</title> 11.382 + 11.383 + <para>A perpetual source of heat in the open source community is 11.384 + whether a development model in which people only ever pull 11.385 + changes from others is <quote>better than</quote> one in which 11.386 + multiple people can push changes to a shared 11.387 + repository.</para> 11.388 + 11.389 + <para>Typically, the backers of the shared-push model use tools 11.390 + that actively enforce this approach. If you're using a 11.391 + centralised revision control tool such as Subversion, there's 11.392 + no way to make a choice over which model you'll use: the tool 11.393 + gives you shared-push, and if you want to do anything else, 11.394 + you'll have to roll your own approach on top (such as applying 11.395 + a patch by hand).</para> 11.396 + 11.397 + <para>A good distributed revision control tool, such as 11.398 + Mercurial, will support both models. You and your 11.399 + collaborators can then structure how you work together based 11.400 + on your own needs and preferences, not on what contortions 11.401 + your tools force you into.</para> 11.402 + 11.403 + </sect2> 11.404 + <sect2> 11.405 + <title>Where collaboration meets branch management</title> 11.406 + 11.407 + <para>Once you and your team set up some shared repositories and 11.408 + start propagating changes back and forth between local and 11.409 + shared repos, you begin to face a related, but slightly 11.410 + different challenge: that of managing the multiple directions 11.411 + in which your team may be moving at once. Even though this 11.412 + subject is intimately related to how your team collaborates, 11.413 + it's dense enough to merit treatment of its own, in chapter 11.414 + <xref linkend="chap:branch"/>.</para> 11.415 + 11.416 + </sect2> 11.417 + </sect1> 11.418 + <sect1> 11.419 + <title>The technical side of sharing</title> 11.420 + 11.421 + <para>The remainder of this chapter is devoted to the question of 11.422 + serving data to your collaborators.</para> 11.423 + 11.424 + </sect1> 11.425 + <sect1 id="sec:collab:serve"> 11.426 + <title>Informal sharing with <command role="hg-cmd">hg 11.427 + serve</command></title> 11.428 + 11.429 + <para>Mercurial's <command role="hg-cmd">hg serve</command> 11.430 + command is wonderfully suited to small, tight-knit, and 11.431 + fast-paced group environments. It also provides a great way to 11.432 + get a feel for using Mercurial commands over a network.</para> 11.433 + 11.434 + <para>Run <command role="hg-cmd">hg serve</command> inside a 11.435 + repository, and in under a second it will bring up a specialised 11.436 + HTTP server; this will accept connections from any client, and 11.437 + serve up data for that repository until you terminate it. 11.438 + Anyone who knows the URL of the server you just started, and can 11.439 + talk to your computer over the network, can then use a web 11.440 + browser or Mercurial to read data from that repository. A URL 11.441 + for a <command role="hg-cmd">hg serve</command> instance running 11.442 + on a laptop is likely to look something like 11.443 + <literal>http://my-laptop.local:8000/</literal>.</para> 11.444 + 11.445 + <para>The <command role="hg-cmd">hg serve</command> command is 11.446 + <emphasis>not</emphasis> a general-purpose web server. It can do 11.447 + only two things:</para> 11.448 + <itemizedlist> 11.449 + <listitem><para>Allow people to browse the history of the 11.450 + repository it's serving, from their normal web 11.451 + browsers.</para> 11.452 + </listitem> 11.453 + <listitem><para>Speak Mercurial's wire protocol, so that people 11.454 + can <command role="hg-cmd">hg clone</command> or <command 11.455 + role="hg-cmd">hg pull</command> changes from that 11.456 + repository.</para> 11.457 + </listitem></itemizedlist> 11.458 + <para>In particular, <command role="hg-cmd">hg serve</command> 11.459 + won't allow remote users to <emphasis>modify</emphasis> your 11.460 + repository. It's intended for read-only use.</para> 11.461 + 11.462 + <para>If you're getting started with Mercurial, there's nothing to 11.463 + prevent you from using <command role="hg-cmd">hg serve</command> 11.464 + to serve up a repository on your own computer, then use commands 11.465 + like <command role="hg-cmd">hg clone</command>, <command 11.466 + role="hg-cmd">hg incoming</command>, and so on to talk to that 11.467 + server as if the repository was hosted remotely. This can help 11.468 + you to quickly get acquainted with using commands on 11.469 + network-hosted repositories.</para> 11.470 + 11.471 + <sect2> 11.472 + <title>A few things to keep in mind</title> 11.473 + 11.474 + <para>Because it provides unauthenticated read access to all 11.475 + clients, you should only use <command role="hg-cmd">hg 11.476 + serve</command> in an environment where you either don't 11.477 + care, or have complete control over, who can access your 11.478 + network and pull data from your repository.</para> 11.479 + 11.480 + <para>The <command role="hg-cmd">hg serve</command> command 11.481 + knows nothing about any firewall software you might have 11.482 + installed on your system or network. It cannot detect or 11.483 + control your firewall software. If other people are unable to 11.484 + talk to a running <command role="hg-cmd">hg serve</command> 11.485 + instance, the second thing you should do 11.486 + (<emphasis>after</emphasis> you make sure that they're using 11.487 + the correct URL) is check your firewall configuration.</para> 11.488 + 11.489 + <para>By default, <command role="hg-cmd">hg serve</command> 11.490 + listens for incoming connections on port 8000. If another 11.491 + process is already listening on the port you want to use, you 11.492 + can specify a different port to listen on using the <option 11.493 + role="hg-opt-serve">-p</option> option.</para> 11.494 + 11.495 + <para>Normally, when <command role="hg-cmd">hg serve</command> 11.496 + starts, it prints no output, which can be a bit unnerving. If 11.497 + you'd like to confirm that it is indeed running correctly, and 11.498 + find out what URL you should send to your collaborators, start 11.499 + it with the <option role="hg-opt-global">-v</option> 11.500 + option.</para> 11.501 + 11.502 + </sect2> 11.503 + </sect1> 11.504 + <sect1 id="sec:collab:ssh"> 11.505 + <title>Using the Secure Shell (ssh) protocol</title> 11.506 + 11.507 + <para>You can pull and push changes securely over a network 11.508 + connection using the Secure Shell (<literal>ssh</literal>) 11.509 + protocol. To use this successfully, you may have to do a little 11.510 + bit of configuration on the client or server sides.</para> 11.511 + 11.512 + <para>If you're not familiar with ssh, it's a network protocol 11.513 + that lets you securely communicate with another computer. To 11.514 + use it with Mercurial, you'll be setting up one or more user 11.515 + accounts on a server so that remote users can log in and execute 11.516 + commands.</para> 11.517 + 11.518 + <para>(If you <emphasis>are</emphasis> familiar with ssh, you'll 11.519 + probably find some of the material that follows to be elementary 11.520 + in nature.)</para> 11.521 + 11.522 + <sect2> 11.523 + <title>How to read and write ssh URLs</title> 11.524 + 11.525 + <para>An ssh URL tends to look like this:</para> 11.526 + <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting> 11.527 + <orderedlist> 11.528 + <listitem><para>The <quote><literal>ssh://</literal></quote> 11.529 + part tells Mercurial to use the ssh protocol.</para> 11.530 + </listitem> 11.531 + <listitem><para>The <quote><literal>bos@</literal></quote> 11.532 + component indicates what username to log into the server 11.533 + as. You can leave this out if the remote username is the 11.534 + same as your local username.</para> 11.535 + </listitem> 11.536 + <listitem><para>The 11.537 + <quote><literal>hg.serpentine.com</literal></quote> gives 11.538 + the hostname of the server to log into.</para> 11.539 + </listitem> 11.540 + <listitem><para>The <quote>:22</quote> identifies the port 11.541 + number to connect to the server on. The default port is 11.542 + 22, so you only need to specify a colon and port number if 11.543 + you're <emphasis>not</emphasis> using port 22.</para> 11.544 + </listitem> 11.545 + <listitem><para>The remainder of the URL is the local path to 11.546 + the repository on the server.</para> 11.547 + </listitem></orderedlist> 11.548 + 11.549 + <para>There's plenty of scope for confusion with the path 11.550 + component of ssh URLs, as there is no standard way for tools 11.551 + to interpret it. Some programs behave differently than others 11.552 + when dealing with these paths. This isn't an ideal situation, 11.553 + but it's unlikely to change. Please read the following 11.554 + paragraphs carefully.</para> 11.555 + 11.556 + <para>Mercurial treats the path to a repository on the server as 11.557 + relative to the remote user's home directory. For example, if 11.558 + user <literal>foo</literal> on the server has a home directory 11.559 + of <filename class="directory">/home/foo</filename>, then an 11.560 + ssh URL that contains a path component of <filename 11.561 + class="directory">bar</filename> <emphasis>really</emphasis> 11.562 + refers to the directory <filename 11.563 + class="directory">/home/foo/bar</filename>.</para> 11.564 + 11.565 + <para>If you want to specify a path relative to another user's 11.566 + home directory, you can use a path that starts with a tilde 11.567 + character followed by the user's name (let's call them 11.568 + <literal>otheruser</literal>), like this.</para> 11.569 + <programlisting>ssh://server/~otheruser/hg/repo</programlisting> 11.570 + 11.571 + <para>And if you really want to specify an 11.572 + <emphasis>absolute</emphasis> path on the server, begin the 11.573 + path component with two slashes, as in this example.</para> 11.574 + <programlisting>ssh://server//absolute/path</programlisting> 11.575 + 11.576 + </sect2> 11.577 + <sect2> 11.578 + <title>Finding an ssh client for your system</title> 11.579 + 11.580 + <para>Almost every Unix-like system comes with OpenSSH 11.581 + preinstalled. If you're using such a system, run 11.582 + <literal>which ssh</literal> to find out if the 11.583 + <command>ssh</command> command is installed (it's usually in 11.584 + <filename class="directory">/usr/bin</filename>). In the 11.585 + unlikely event that it isn't present, take a look at your 11.586 + system documentation to figure out how to install it.</para> 11.587 + 11.588 + <para>On Windows, you'll first need to download a suitable ssh 11.589 + client. There are two alternatives.</para> 11.590 + <itemizedlist> 11.591 + <listitem><para>Simon Tatham's excellent PuTTY package 11.592 + <citation>web:putty</citation> provides a complete suite 11.593 + of ssh client commands.</para> 11.594 + </listitem> 11.595 + <listitem><para>If you have a high tolerance for pain, you can 11.596 + use the Cygwin port of OpenSSH.</para> 11.597 + </listitem></itemizedlist> 11.598 + <para>In either case, you'll need to edit your <filename 11.599 + role="special">hg.ini</filename> file to 11.600 + tell Mercurial where to find the actual client command. For 11.601 + example, if you're using PuTTY, you'll need to use the 11.602 + <command>plink</command> command as a command-line ssh 11.603 + client.</para> 11.604 + <programlisting>[ui] 11.605 +ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"</programlisting> 11.606 + 11.607 + <note> 11.608 + <para> The path to <command>plink</command> shouldn't contain 11.609 + any whitespace characters, or Mercurial may not be able to 11.610 + run it correctly (so putting it in <filename 11.611 + class="directory">C:\Program Files</filename> is probably 11.612 + not a good idea).</para> 11.613 + </note> 11.614 + 11.615 + </sect2> 11.616 + <sect2> 11.617 + <title>Generating a key pair</title> 11.618 + 11.619 + <para>To avoid the need to repetitively type a password every 11.620 + time you need to use your ssh client, I recommend generating a 11.621 + key pair. On a Unix-like system, the 11.622 + <command>ssh-keygen</command> command will do the trick. On 11.623 + Windows, if you're using PuTTY, the 11.624 + <command>puttygen</command> command is what you'll 11.625 + need.</para> 11.626 + 11.627 + <para>When you generate a key pair, it's usually 11.628 + <emphasis>highly</emphasis> advisable to protect it with a 11.629 + passphrase. (The only time that you might not want to do this 11.630 + is when you're using the ssh protocol for automated tasks on a 11.631 + secure network.)</para> 11.632 + 11.633 + <para>Simply generating a key pair isn't enough, however. 11.634 + You'll need to add the public key to the set of authorised 11.635 + keys for whatever user you're logging in remotely as. For 11.636 + servers using OpenSSH (the vast majority), this will mean 11.637 + adding the public key to a list in a file called <filename 11.638 + role="special">authorized_keys</filename> in their <filename 11.639 + role="special" class="directory">.ssh</filename> 11.640 + directory.</para> 11.641 + 11.642 + <para>On a Unix-like system, your public key will have a 11.643 + <filename>.pub</filename> extension. If you're using 11.644 + <command>puttygen</command> on Windows, you can save the 11.645 + public key to a file of your choosing, or paste it from the 11.646 + window it's displayed in straight into the <filename 11.647 + role="special">authorized_keys</filename> file.</para> 11.648 + 11.649 + </sect2> 11.650 + <sect2> 11.651 + <title>Using an authentication agent</title> 11.652 + 11.653 + <para>An authentication agent is a daemon that stores 11.654 + passphrases in memory (so it will forget passphrases if you 11.655 + log out and log back in again). An ssh client will notice if 11.656 + it's running, and query it for a passphrase. If there's no 11.657 + authentication agent running, or the agent doesn't store the 11.658 + necessary passphrase, you'll have to type your passphrase 11.659 + every time Mercurial tries to communicate with a server on 11.660 + your behalf (e.g. whenever you pull or push changes).</para> 11.661 + 11.662 + <para>The downside of storing passphrases in an agent is that 11.663 + it's possible for a well-prepared attacker to recover the 11.664 + plain text of your passphrases, in some cases even if your 11.665 + system has been power-cycled. You should make your own 11.666 + judgment as to whether this is an acceptable risk. It 11.667 + certainly saves a lot of repeated typing.</para> 11.668 + 11.669 + <para>On Unix-like systems, the agent is called 11.670 + <command>ssh-agent</command>, and it's often run automatically 11.671 + for you when you log in. You'll need to use the 11.672 + <command>ssh-add</command> command to add passphrases to the 11.673 + agent's store. On Windows, if you're using PuTTY, the 11.674 + <command>pageant</command> command acts as the agent. It adds 11.675 + an icon to your system tray that will let you manage stored 11.676 + passphrases.</para> 11.677 + 11.678 + </sect2> 11.679 + <sect2> 11.680 + <title>Configuring the server side properly</title> 11.681 + 11.682 + <para>Because ssh can be fiddly to set up if you're new to it, 11.683 + there's a variety of things that can go wrong. Add Mercurial 11.684 + on top, and there's plenty more scope for head-scratching. 11.685 + Most of these potential problems occur on the server side, not 11.686 + the client side. The good news is that once you've gotten a 11.687 + configuration working, it will usually continue to work 11.688 + indefinitely.</para> 11.689 + 11.690 + <para>Before you try using Mercurial to talk to an ssh server, 11.691 + it's best to make sure that you can use the normal 11.692 + <command>ssh</command> or <command>putty</command> command to 11.693 + talk to the server first. If you run into problems with using 11.694 + these commands directly, Mercurial surely won't work. Worse, 11.695 + it will obscure the underlying problem. Any time you want to 11.696 + debug ssh-related Mercurial problems, you should drop back to 11.697 + making sure that plain ssh client commands work first, 11.698 + <emphasis>before</emphasis> you worry about whether there's a 11.699 + problem with Mercurial.</para> 11.700 + 11.701 + <para>The first thing to be sure of on the server side is that 11.702 + you can actually log in from another machine at all. If you 11.703 + can't use <command>ssh</command> or <command>putty</command> 11.704 + to log in, the error message you get may give you a few hints 11.705 + as to what's wrong. The most common problems are as 11.706 + follows.</para> 11.707 + <itemizedlist> 11.708 + <listitem><para>If you get a <quote>connection refused</quote> 11.709 + error, either there isn't an SSH daemon running on the 11.710 + server at all, or it's inaccessible due to firewall 11.711 + configuration.</para> 11.712 + </listitem> 11.713 + <listitem><para>If you get a <quote>no route to host</quote> 11.714 + error, you either have an incorrect address for the server 11.715 + or a seriously locked down firewall that won't admit its 11.716 + existence at all.</para> 11.717 + </listitem> 11.718 + <listitem><para>If you get a <quote>permission denied</quote> 11.719 + error, you may have mistyped the username on the server, 11.720 + or you could have mistyped your key's passphrase or the 11.721 + remote user's password.</para> 11.722 + </listitem></itemizedlist> 11.723 + <para>In summary, if you're having trouble talking to the 11.724 + server's ssh daemon, first make sure that one is running at 11.725 + all. On many systems it will be installed, but disabled, by 11.726 + default. Once you're done with this step, you should then 11.727 + check that the server's firewall is configured to allow 11.728 + incoming connections on the port the ssh daemon is listening 11.729 + on (usually 22). Don't worry about more exotic possibilities 11.730 + for misconfiguration until you've checked these two 11.731 + first.</para> 11.732 + 11.733 + <para>If you're using an authentication agent on the client side 11.734 + to store passphrases for your keys, you ought to be able to 11.735 + log into the server without being prompted for a passphrase or 11.736 + a password. If you're prompted for a passphrase, there are a 11.737 + few possible culprits.</para> 11.738 + <itemizedlist> 11.739 + <listitem><para>You might have forgotten to use 11.740 + <command>ssh-add</command> or <command>pageant</command> 11.741 + to store the passphrase.</para> 11.742 + </listitem> 11.743 + <listitem><para>You might have stored the passphrase for the 11.744 + wrong key.</para> 11.745 + </listitem></itemizedlist> 11.746 + <para>If you're being prompted for the remote user's password, 11.747 + there are another few possible problems to check.</para> 11.748 + <itemizedlist> 11.749 + <listitem><para>Either the user's home directory or their 11.750 + <filename role="special" class="directory">.ssh</filename> 11.751 + directory might have excessively liberal permissions. As 11.752 + a result, the ssh daemon will not trust or read their 11.753 + <filename role="special">authorized_keys</filename> file. 11.754 + For example, a group-writable home or <filename 11.755 + role="special" class="directory">.ssh</filename> 11.756 + directory will often cause this symptom.</para> 11.757 + </listitem> 11.758 + <listitem><para>The user's <filename 11.759 + role="special">authorized_keys</filename> file may have 11.760 + a problem. If anyone other than the user owns or can write 11.761 + to that file, the ssh daemon will not trust or read 11.762 + it.</para> 11.763 + </listitem></itemizedlist> 11.764 + 11.765 + <para>In the ideal world, you should be able to run the 11.766 + following command successfully, and it should print exactly 11.767 + one line of output, the current date and time.</para> 11.768 + <programlisting>ssh myserver date</programlisting> 11.769 + 11.770 + <para>If, on your server, you have login scripts that print 11.771 + banners or other junk even when running non-interactive 11.772 + commands like this, you should fix them before you continue, 11.773 + so that they only print output if they're run interactively. 11.774 + Otherwise these banners will at least clutter up Mercurial's 11.775 + output. Worse, they could potentially cause problems with 11.776 + running Mercurial commands remotely. Mercurial makes tries to 11.777 + detect and ignore banners in non-interactive 11.778 + <command>ssh</command> sessions, but it is not foolproof. (If 11.779 + you're editing your login scripts on your server, the usual 11.780 + way to see if a login script is running in an interactive 11.781 + shell is to check the return code from the command 11.782 + <literal>tty -s</literal>.)</para> 11.783 + 11.784 + <para>Once you've verified that plain old ssh is working with 11.785 + your server, the next step is to ensure that Mercurial runs on 11.786 + the server. The following command should run 11.787 + successfully:</para> 11.788 + 11.789 + <programlisting>ssh myserver hg version</programlisting> 11.790 + 11.791 + <para>If you see an error message instead of normal <command 11.792 + role="hg-cmd">hg version</command> output, this is usually 11.793 + because you haven't installed Mercurial to <filename 11.794 + class="directory">/usr/bin</filename>. Don't worry if this 11.795 + is the case; you don't need to do that. But you should check 11.796 + for a few possible problems.</para> 11.797 + <itemizedlist> 11.798 + <listitem><para>Is Mercurial really installed on the server at 11.799 + all? I know this sounds trivial, but it's worth 11.800 + checking!</para> 11.801 + </listitem> 11.802 + <listitem><para>Maybe your shell's search path (usually set 11.803 + via the <envar>PATH</envar> environment variable) is 11.804 + simply misconfigured.</para> 11.805 + </listitem> 11.806 + <listitem><para>Perhaps your <envar>PATH</envar> environment 11.807 + variable is only being set to point to the location of the 11.808 + <command>hg</command> executable if the login session is 11.809 + interactive. This can happen if you're setting the path 11.810 + in the wrong shell login script. See your shell's 11.811 + documentation for details.</para> 11.812 + </listitem> 11.813 + <listitem><para>The <envar>PYTHONPATH</envar> environment 11.814 + variable may need to contain the path to the Mercurial 11.815 + Python modules. It might not be set at all; it could be 11.816 + incorrect; or it may be set only if the login is 11.817 + interactive.</para> 11.818 + </listitem></itemizedlist> 11.819 + 11.820 + <para>If you can run <command role="hg-cmd">hg version</command> 11.821 + over an ssh connection, well done! You've got the server and 11.822 + client sorted out. You should now be able to use Mercurial to 11.823 + access repositories hosted by that username on that server. 11.824 + If you run into problems with Mercurial and ssh at this point, 11.825 + try using the <option role="hg-opt-global">--debug</option> 11.826 + option to get a clearer picture of what's going on.</para> 11.827 + 11.828 + </sect2> 11.829 + <sect2> 11.830 + <title>Using compression with ssh</title> 11.831 + 11.832 + <para>Mercurial does not compress data when it uses the ssh 11.833 + protocol, because the ssh protocol can transparently compress 11.834 + data. However, the default behaviour of ssh clients is 11.835 + <emphasis>not</emphasis> to request compression.</para> 11.836 + 11.837 + <para>Over any network other than a fast LAN (even a wireless 11.838 + network), using compression is likely to significantly speed 11.839 + up Mercurial's network operations. For example, over a WAN, 11.840 + someone measured compression as reducing the amount of time 11.841 + required to clone a particularly large repository from 51 11.842 + minutes to 17 minutes.</para> 11.843 + 11.844 + <para>Both <command>ssh</command> and <command>plink</command> 11.845 + accept a <option role="cmd-opt-ssh">-C</option> option which 11.846 + turns on compression. You can easily edit your <filename 11.847 + role="special">~/.hgrc</filename> to enable compression for 11.848 + all of Mercurial's uses of the ssh protocol.</para> 11.849 + <programlisting>[ui] 11.850 +ssh = ssh -C</programlisting> 11.851 + 11.852 + <para>If you use <command>ssh</command>, you can configure it to 11.853 + always use compression when talking to your server. To do 11.854 + this, edit your <filename 11.855 + role="special">.ssh/config</filename> file (which may not 11.856 + yet exist), as follows.</para> 11.857 + <programlisting>Host hg 11.858 + Compression yes 11.859 + HostName hg.example.com</programlisting> 11.860 + <para>This defines an alias, <literal>hg</literal>. When you 11.861 + use it on the <command>ssh</command> command line or in a 11.862 + Mercurial <literal>ssh</literal>-protocol URL, it will cause 11.863 + <command>ssh</command> to connect to 11.864 + <literal>hg.example.com</literal> and use compression. This 11.865 + gives you both a shorter name to type and compression, each of 11.866 + which is a good thing in its own right.</para> 11.867 + 11.868 + </sect2> 11.869 + </sect1> 11.870 + <sect1 id="sec:collab:cgi"> 11.871 + <title>Serving over HTTP using CGI</title> 11.872 + 11.873 + <para>Depending on how ambitious you are, configuring Mercurial's 11.874 + CGI interface can take anything from a few moments to several 11.875 + hours.</para> 11.876 + 11.877 + <para>We'll begin with the simplest of examples, and work our way 11.878 + towards a more complex configuration. Even for the most basic 11.879 + case, you're almost certainly going to need to read and modify 11.880 + your web server's configuration.</para> 11.881 + 11.882 + <note> 11.883 + <para> Configuring a web server is a complex, fiddly, and 11.884 + highly system-dependent activity. I can't possibly give you 11.885 + instructions that will cover anything like all of the cases 11.886 + you will encounter. Please use your discretion and judgment in 11.887 + following the sections below. Be prepared to make plenty of 11.888 + mistakes, and to spend a lot of time reading your server's 11.889 + error logs.</para> 11.890 + </note> 11.891 + 11.892 + <sect2> 11.893 + <title>Web server configuration checklist</title> 11.894 + 11.895 + <para>Before you continue, do take a few moments to check a few 11.896 + aspects of your system's setup.</para> 11.897 + 11.898 + <orderedlist> 11.899 + <listitem><para>Do you have a web server installed at all? 11.900 + Mac OS X ships with Apache, but many other systems may not 11.901 + have a web server installed.</para> 11.902 + </listitem> 11.903 + <listitem><para>If you have a web server installed, is it 11.904 + actually running? On most systems, even if one is 11.905 + present, it will be disabled by default.</para> 11.906 + </listitem> 11.907 + <listitem><para>Is your server configured to allow you to run 11.908 + CGI programs in the directory where you plan to do so? 11.909 + Most servers default to explicitly disabling the ability 11.910 + to run CGI programs.</para> 11.911 + </listitem></orderedlist> 11.912 + 11.913 + <para>If you don't have a web server installed, and don't have 11.914 + substantial experience configuring Apache, you should consider 11.915 + using the <literal>lighttpd</literal> web server instead of 11.916 + Apache. Apache has a well-deserved reputation for baroque and 11.917 + confusing configuration. While <literal>lighttpd</literal> is 11.918 + less capable in some ways than Apache, most of these 11.919 + capabilities are not relevant to serving Mercurial 11.920 + repositories. And <literal>lighttpd</literal> is undeniably 11.921 + <emphasis>much</emphasis> easier to get started with than 11.922 + Apache.</para> 11.923 + 11.924 + </sect2> 11.925 + <sect2> 11.926 + <title>Basic CGI configuration</title> 11.927 + 11.928 + <para>On Unix-like systems, it's common for users to have a 11.929 + subdirectory named something like <filename 11.930 + class="directory">public_html</filename> in their home 11.931 + directory, from which they can serve up web pages. A file 11.932 + named <filename>foo</filename> in this directory will be 11.933 + accessible at a URL of the form 11.934 + <literal>http://www.example.com/username/foo</literal>.</para> 11.935 + 11.936 + <para>To get started, find the <filename 11.937 + role="special">hgweb.cgi</filename> script that should be 11.938 + present in your Mercurial installation. If you can't quickly 11.939 + find a local copy on your system, simply download one from the 11.940 + master Mercurial repository at <ulink 11.941 + url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para> 11.942 + 11.943 + <para>You'll need to copy this script into your <filename 11.944 + class="directory">public_html</filename> directory, and 11.945 + ensure that it's executable.</para> 11.946 + <programlisting>cp .../hgweb.cgi ~/public_html 11.947 +chmod 755 ~/public_html/hgweb.cgi</programlisting> 11.948 + <para>The <literal>755</literal> argument to 11.949 + <command>chmod</command> is a little more general than just 11.950 + making the script executable: it ensures that the script is 11.951 + executable by anyone, and that <quote>group</quote> and 11.952 + <quote>other</quote> write permissions are 11.953 + <emphasis>not</emphasis> set. If you were to leave those 11.954 + write permissions enabled, Apache's <literal>suexec</literal> 11.955 + subsystem would likely refuse to execute the script. In fact, 11.956 + <literal>suexec</literal> also insists that the 11.957 + <emphasis>directory</emphasis> in which the script resides 11.958 + must not be writable by others.</para> 11.959 + <programlisting>chmod 755 ~/public_html</programlisting> 11.960 + 11.961 + <sect3 id="sec:collab:wtf"> 11.962 + <title>What could <emphasis>possibly</emphasis> go 11.963 + wrong?</title> 11.964 + 11.965 + <para>Once you've copied the CGI script into place, go into a 11.966 + web browser, and try to open the URL <ulink 11.967 + url="http://myhostname/ 11.968 + myuser/hgweb.cgi">http://myhostname/ 11.969 + myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace 11.970 + yourself for instant failure. There's a high probability 11.971 + that trying to visit this URL will fail, and there are many 11.972 + possible reasons for this. In fact, you're likely to 11.973 + stumble over almost every one of the possible errors below, 11.974 + so please read carefully. The following are all of the 11.975 + problems I ran into on a system running Fedora 7, with a 11.976 + fresh installation of Apache, and a user account that I 11.977 + created specially to perform this exercise.</para> 11.978 + 11.979 + <para>Your web server may have per-user directories disabled. 11.980 + If you're using Apache, search your config file for a 11.981 + <literal>UserDir</literal> directive. If there's none 11.982 + present, per-user directories will be disabled. If one 11.983 + exists, but its value is <literal>disabled</literal>, then 11.984 + per-user directories will be disabled. Otherwise, the 11.985 + string after <literal>UserDir</literal> gives the name of 11.986 + the subdirectory that Apache will look in under your home 11.987 + directory, for example <filename 11.988 + class="directory">public_html</filename>.</para> 11.989 + 11.990 + <para>Your file access permissions may be too restrictive. 11.991 + The web server must be able to traverse your home directory 11.992 + and directories under your <filename 11.993 + class="directory">public_html</filename> directory, and 11.994 + read files under the latter too. Here's a quick recipe to 11.995 + help you to make your permissions more appropriate.</para> 11.996 + <programlisting>chmod 755 ~ 11.997 +find ~/public_html -type d -print0 | xargs -0r chmod 755 11.998 +find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting> 11.999 + 11.1000 + <para>The other possibility with permissions is that you might 11.1001 + get a completely empty window when you try to load the 11.1002 + script. In this case, it's likely that your access 11.1003 + permissions are <emphasis>too permissive</emphasis>. Apache's 11.1004 + <literal>suexec</literal> subsystem won't execute a script 11.1005 + that's group- or world-writable, for example.</para> 11.1006 + 11.1007 + <para>Your web server may be configured to disallow execution 11.1008 + of CGI programs in your per-user web directory. Here's 11.1009 + Apache's default per-user configuration from my Fedora 11.1010 + system.</para> 11.1011 + 11.1012 + &ch06-apache-config.lst; 11.1013 + 11.1014 + <para>If you find a similar-looking 11.1015 + <literal>Directory</literal> group in your Apache 11.1016 + configuration, the directive to look at inside it is 11.1017 + <literal>Options</literal>. Add <literal>ExecCGI</literal> 11.1018 + to the end of this list if it's missing, and restart the web 11.1019 + server.</para> 11.1020 + 11.1021 + <para>If you find that Apache serves you the text of the CGI 11.1022 + script instead of executing it, you may need to either 11.1023 + uncomment (if already present) or add a directive like 11.1024 + this.</para> 11.1025 + <programlisting>AddHandler cgi-script .cgi</programlisting> 11.1026 + 11.1027 + <para>The next possibility is that you might be served with a 11.1028 + colourful Python backtrace claiming that it can't import a 11.1029 + <literal>mercurial</literal>-related module. This is 11.1030 + actually progress! The server is now capable of executing 11.1031 + your CGI script. This error is only likely to occur if 11.1032 + you're running a private installation of Mercurial, instead 11.1033 + of a system-wide version. Remember that the web server runs 11.1034 + the CGI program without any of the environment variables 11.1035 + that you take for granted in an interactive session. If 11.1036 + this error happens to you, edit your copy of <filename 11.1037 + role="special">hgweb.cgi</filename> and follow the 11.1038 + directions inside it to correctly set your 11.1039 + <envar>PYTHONPATH</envar> environment variable.</para> 11.1040 + 11.1041 + <para>Finally, you are <emphasis>certain</emphasis> to by 11.1042 + served with another colourful Python backtrace: this one 11.1043 + will complain that it can't find <filename 11.1044 + class="directory">/path/to/repository</filename>. Edit 11.1045 + your <filename role="special">hgweb.cgi</filename> script 11.1046 + and replace the <filename 11.1047 + class="directory">/path/to/repository</filename> string 11.1048 + with the complete path to the repository you want to serve 11.1049 + up.</para> 11.1050 + 11.1051 + <para>At this point, when you try to reload the page, you 11.1052 + should be presented with a nice HTML view of your 11.1053 + repository's history. Whew!</para> 11.1054 + 11.1055 + </sect3> 11.1056 + <sect3> 11.1057 + <title>Configuring lighttpd</title> 11.1058 + 11.1059 + <para>To be exhaustive in my experiments, I tried configuring 11.1060 + the increasingly popular <literal>lighttpd</literal> web 11.1061 + server to serve the same repository as I described with 11.1062 + Apache above. I had already overcome all of the problems I 11.1063 + outlined with Apache, many of which are not server-specific. 11.1064 + As a result, I was fairly sure that my file and directory 11.1065 + permissions were good, and that my <filename 11.1066 + role="special">hgweb.cgi</filename> script was properly 11.1067 + edited.</para> 11.1068 + 11.1069 + <para>Once I had Apache running, getting 11.1070 + <literal>lighttpd</literal> to serve the repository was a 11.1071 + snap (in other words, even if you're trying to use 11.1072 + <literal>lighttpd</literal>, you should read the Apache 11.1073 + section). I first had to edit the 11.1074 + <literal>mod_access</literal> section of its config file to 11.1075 + enable <literal>mod_cgi</literal> and 11.1076 + <literal>mod_userdir</literal>, both of which were disabled 11.1077 + by default on my system. I then added a few lines to the 11.1078 + end of the config file, to configure these modules.</para> 11.1079 + <programlisting>userdir.path = "public_html" 11.1080 +cgi.assign = (".cgi" => "" )</programlisting> 11.1081 + <para>With this done, <literal>lighttpd</literal> ran 11.1082 + immediately for me. If I had configured 11.1083 + <literal>lighttpd</literal> before Apache, I'd almost 11.1084 + certainly have run into many of the same system-level 11.1085 + configuration problems as I did with Apache. However, I 11.1086 + found <literal>lighttpd</literal> to be noticeably easier to 11.1087 + configure than Apache, even though I've used Apache for over 11.1088 + a decade, and this was my first exposure to 11.1089 + <literal>lighttpd</literal>.</para> 11.1090 + 11.1091 + </sect3> 11.1092 + </sect2> 11.1093 + <sect2> 11.1094 + <title>Sharing multiple repositories with one CGI script</title> 11.1095 + 11.1096 + <para>The <filename role="special">hgweb.cgi</filename> script 11.1097 + only lets you publish a single repository, which is an 11.1098 + annoying restriction. If you want to publish more than one 11.1099 + without wracking yourself with multiple copies of the same 11.1100 + script, each with different names, a better choice is to use 11.1101 + the <filename role="special">hgwebdir.cgi</filename> 11.1102 + script.</para> 11.1103 + 11.1104 + <para>The procedure to configure <filename 11.1105 + role="special">hgwebdir.cgi</filename> is only a little more 11.1106 + involved than for <filename 11.1107 + role="special">hgweb.cgi</filename>. First, you must obtain 11.1108 + a copy of the script. If you don't have one handy, you can 11.1109 + download a copy from the master Mercurial repository at <ulink 11.1110 + url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para> 11.1111 + 11.1112 + <para>You'll need to copy this script into your <filename 11.1113 + class="directory">public_html</filename> directory, and 11.1114 + ensure that it's executable.</para> 11.1115 + <programlisting>cp .../hgwebdir.cgi ~/public_html 11.1116 +chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting> 11.1117 + <para>With basic configuration out of the way, try to visit 11.1118 + <ulink url="http://myhostname/ 11.1119 + myuser/hgwebdir.cgi">http://myhostname/ 11.1120 + myuser/hgwebdir.cgi</ulink> in your browser. It should 11.1121 + display an empty list of repositories. If you get a blank 11.1122 + window or error message, try walking through the list of 11.1123 + potential problems in section <xref 11.1124 + linkend="sec:collab:wtf"/>.</para> 11.1125 + 11.1126 + <para>The <filename role="special">hgwebdir.cgi</filename> 11.1127 + script relies on an external configuration file. By default, 11.1128 + it searches for a file named <filename 11.1129 + role="special">hgweb.config</filename> in the same directory 11.1130 + as itself. You'll need to create this file, and make it 11.1131 + world-readable. The format of the file is similar to a 11.1132 + Windows <quote>ini</quote> file, as understood by Python's 11.1133 + <literal>ConfigParser</literal> 11.1134 + <citation>web:configparser</citation> module.</para> 11.1135 + 11.1136 + <para>The easiest way to configure <filename 11.1137 + role="special">hgwebdir.cgi</filename> is with a section 11.1138 + named <literal>collections</literal>. This will automatically 11.1139 + publish <emphasis>every</emphasis> repository under the 11.1140 + directories you name. The section should look like 11.1141 + this:</para> 11.1142 + <programlisting>[collections] 11.1143 +/my/root = /my/root</programlisting> 11.1144 + <para>Mercurial interprets this by looking at the directory name 11.1145 + on the <emphasis>right</emphasis> hand side of the 11.1146 + <quote><literal>=</literal></quote> sign; finding repositories 11.1147 + in that directory hierarchy; and using the text on the 11.1148 + <emphasis>left</emphasis> to strip off matching text from the 11.1149 + names it will actually list in the web interface. The 11.1150 + remaining component of a path after this stripping has 11.1151 + occurred is called a <quote>virtual path</quote>.</para> 11.1152 + 11.1153 + <para>Given the example above, if we have a repository whose 11.1154 + local path is <filename 11.1155 + class="directory">/my/root/this/repo</filename>, the CGI 11.1156 + script will strip the leading <filename 11.1157 + class="directory">/my/root</filename> from the name, and 11.1158 + publish the repository with a virtual path of <filename 11.1159 + class="directory">this/repo</filename>. If the base URL for 11.1160 + our CGI script is <ulink url="http://myhostname/ 11.1161 + myuser/hgwebdir.cgi">http://myhostname/ 11.1162 + myuser/hgwebdir.cgi</ulink>, the complete URL for that 11.1163 + repository will be <ulink url="http://myhostname/ 11.1164 + myuser/hgwebdir.cgi/this/repo">http://myhostname/ 11.1165 + myuser/hgwebdir.cgi/this/repo</ulink>.</para> 11.1166 + 11.1167 + <para>If we replace <filename 11.1168 + class="directory">/my/root</filename> on the left hand side 11.1169 + of this example with <filename 11.1170 + class="directory">/my</filename>, then <filename 11.1171 + role="special">hgwebdir.cgi</filename> will only strip off 11.1172 + <filename class="directory">/my</filename> from the repository 11.1173 + name, and will give us a virtual path of <filename 11.1174 + class="directory">root/this/repo</filename> instead of 11.1175 + <filename class="directory">this/repo</filename>.</para> 11.1176 + 11.1177 + <para>The <filename role="special">hgwebdir.cgi</filename> 11.1178 + script will recursively search each directory listed in the 11.1179 + <literal>collections</literal> section of its configuration 11.1180 + file, but it will <literal>not</literal> recurse into the 11.1181 + repositories it finds.</para> 11.1182 + 11.1183 + <para>The <literal>collections</literal> mechanism makes it easy 11.1184 + to publish many repositories in a <quote>fire and 11.1185 + forget</quote> manner. You only need to set up the CGI 11.1186 + script and configuration file one time. Afterwards, you can 11.1187 + publish or unpublish a repository at any time by simply moving 11.1188 + it into, or out of, the directory hierarchy in which you've 11.1189 + configured <filename role="special">hgwebdir.cgi</filename> to 11.1190 + look.</para> 11.1191 + 11.1192 + <sect3> 11.1193 + <title>Explicitly specifying which repositories to 11.1194 + publish</title> 11.1195 + 11.1196 + <para>In addition to the <literal>collections</literal> 11.1197 + mechanism, the <filename 11.1198 + role="special">hgwebdir.cgi</filename> script allows you 11.1199 + to publish a specific list of repositories. To do so, 11.1200 + create a <literal>paths</literal> section, with contents of 11.1201 + the following form.</para> 11.1202 + <programlisting>[paths] 11.1203 +repo1 = /my/path/to/some/repo 11.1204 +repo2 = /some/path/to/another</programlisting> 11.1205 + <para>In this case, the virtual path (the component that will 11.1206 + appear in a URL) is on the left hand side of each 11.1207 + definition, while the path to the repository is on the 11.1208 + right. Notice that there does not need to be any 11.1209 + relationship between the virtual path you choose and the 11.1210 + location of a repository in your filesystem.</para> 11.1211 + 11.1212 + <para>If you wish, you can use both the 11.1213 + <literal>collections</literal> and <literal>paths</literal> 11.1214 + mechanisms simultaneously in a single configuration 11.1215 + file.</para> 11.1216 + 11.1217 + <note> 11.1218 + <para> If multiple repositories have the same virtual path, 11.1219 + <filename role="special">hgwebdir.cgi</filename> will not 11.1220 + report an error. Instead, it will behave 11.1221 + unpredictably.</para> 11.1222 + </note> 11.1223 + 11.1224 + </sect3> 11.1225 + </sect2> 11.1226 + <sect2> 11.1227 + <title>Downloading source archives</title> 11.1228 + 11.1229 + <para>Mercurial's web interface lets users download an archive 11.1230 + of any revision. This archive will contain a snapshot of the 11.1231 + working directory as of that revision, but it will not contain 11.1232 + a copy of the repository data.</para> 11.1233 + 11.1234 + <para>By default, this feature is not enabled. To enable it, 11.1235 + you'll need to add an <envar 11.1236 + role="rc-item-web">allow_archive</envar> item to the 11.1237 + <literal role="rc-web">web</literal> section of your <filename 11.1238 + role="special">~/.hgrc</filename>.</para> 11.1239 + 11.1240 + </sect2> 11.1241 + <sect2> 11.1242 + <title>Web configuration options</title> 11.1243 + 11.1244 + <para>Mercurial's web interfaces (the <command role="hg-cmd">hg 11.1245 + serve</command> command, and the <filename 11.1246 + role="special">hgweb.cgi</filename> and <filename 11.1247 + role="special">hgwebdir.cgi</filename> scripts) have a 11.1248 + number of configuration options that you can set. These 11.1249 + belong in a section named <literal 11.1250 + role="rc-web">web</literal>.</para> 11.1251 + <itemizedlist> 11.1252 + <listitem><para><envar 11.1253 + role="rc-item-web">allow_archive</envar>: Determines 11.1254 + which (if any) archive download mechanisms Mercurial 11.1255 + supports. If you enable this feature, users of the web 11.1256 + interface will be able to download an archive of whatever 11.1257 + revision of a repository they are viewing. To enable the 11.1258 + archive feature, this item must take the form of a 11.1259 + sequence of words drawn from the list below.</para> 11.1260 + <itemizedlist> 11.1261 + <listitem><para><literal>bz2</literal>: A 11.1262 + <command>tar</command> archive, compressed using 11.1263 + <literal>bzip2</literal> compression. This has the 11.1264 + best compression ratio, but uses the most CPU time on 11.1265 + the server.</para> 11.1266 + </listitem> 11.1267 + <listitem><para><literal>gz</literal>: A 11.1268 + <command>tar</command> archive, compressed using 11.1269 + <literal>gzip</literal> compression.</para> 11.1270 + </listitem> 11.1271 + <listitem><para><literal>zip</literal>: A 11.1272 + <command>zip</command> archive, compressed using LZW 11.1273 + compression. This format has the worst compression 11.1274 + ratio, but is widely used in the Windows world.</para> 11.1275 + </listitem> 11.1276 + </itemizedlist> 11.1277 + <para> If you provide an empty list, or don't have an 11.1278 + <envar role="rc-item-web">allow_archive</envar> entry at 11.1279 + all, this feature will be disabled. Here is an example of 11.1280 + how to enable all three supported formats.</para> 11.1281 + <programlisting>[web] 11.1282 +allow_archive = bz2 gz zip</programlisting> 11.1283 + </listitem> 11.1284 + <listitem><para><envar role="rc-item-web">allowpull</envar>: 11.1285 + Boolean. Determines whether the web interface allows 11.1286 + remote users to <command role="hg-cmd">hg pull</command> 11.1287 + and <command role="hg-cmd">hg clone</command> this 11.1288 + repository over HTTP. If set to <literal>no</literal> or 11.1289 + <literal>false</literal>, only the 11.1290 + <quote>human-oriented</quote> portion of the web interface 11.1291 + is available.</para> 11.1292 + </listitem> 11.1293 + <listitem><para><envar role="rc-item-web">contact</envar>: 11.1294 + String. A free-form (but preferably brief) string 11.1295 + identifying the person or group in charge of the 11.1296 + repository. This often contains the name and email 11.1297 + address of a person or mailing list. It often makes sense 11.1298 + to place this entry in a repository's own <filename 11.1299 + role="special">.hg/hgrc</filename> file, but it can make 11.1300 + sense to use in a global <filename 11.1301 + role="special">~/.hgrc</filename> if every repository 11.1302 + has a single maintainer.</para> 11.1303 + </listitem> 11.1304 + <listitem><para><envar role="rc-item-web">maxchanges</envar>: 11.1305 + Integer. The default maximum number of changesets to 11.1306 + display in a single page of output.</para> 11.1307 + </listitem> 11.1308 + <listitem><para><envar role="rc-item-web">maxfiles</envar>: 11.1309 + Integer. The default maximum number of modified files to 11.1310 + display in a single page of output.</para> 11.1311 + </listitem> 11.1312 + <listitem><para><envar role="rc-item-web">stripes</envar>: 11.1313 + Integer. If the web interface displays alternating 11.1314 + <quote>stripes</quote> to make it easier to visually align 11.1315 + rows when you are looking at a table, this number controls 11.1316 + the number of rows in each stripe.</para> 11.1317 + </listitem> 11.1318 + <listitem><para><envar role="rc-item-web">style</envar>: 11.1319 + Controls the template Mercurial uses to display the web 11.1320 + interface. Mercurial ships with two web templates, named 11.1321 + <literal>default</literal> and <literal>gitweb</literal> 11.1322 + (the latter is much more visually attractive). You can 11.1323 + also specify a custom template of your own; see chapter 11.1324 + <xref linkend="chap:template"/> for details. 11.1325 + Here, you can see how to enable the 11.1326 + <literal>gitweb</literal> style.</para> 11.1327 + <programlisting>[web] 11.1328 +style = gitweb</programlisting> 11.1329 + </listitem> 11.1330 + <listitem><para><envar role="rc-item-web">templates</envar>: 11.1331 + Path. The directory in which to search for template 11.1332 + files. By default, Mercurial searches in the directory in 11.1333 + which it was installed.</para> 11.1334 + </listitem></itemizedlist> 11.1335 + <para>If you are using <filename 11.1336 + role="special">hgwebdir.cgi</filename>, you can place a few 11.1337 + configuration items in a <literal role="rc-web">web</literal> 11.1338 + section of the <filename 11.1339 + role="special">hgweb.config</filename> file instead of a 11.1340 + <filename role="special">~/.hgrc</filename> file, for 11.1341 + convenience. These items are <envar 11.1342 + role="rc-item-web">motd</envar> and <envar 11.1343 + role="rc-item-web">style</envar>.</para> 11.1344 + 11.1345 + <sect3> 11.1346 + <title>Options specific to an individual repository</title> 11.1347 + 11.1348 + <para>A few <literal role="rc-web">web</literal> configuration 11.1349 + items ought to be placed in a repository's local <filename 11.1350 + role="special">.hg/hgrc</filename>, rather than a user's 11.1351 + or global <filename role="special">~/.hgrc</filename>.</para> 11.1352 + <itemizedlist> 11.1353 + <listitem><para><envar 11.1354 + role="rc-item-web">description</envar>: String. A 11.1355 + free-form (but preferably brief) string that describes 11.1356 + the contents or purpose of the repository.</para> 11.1357 + </listitem> 11.1358 + <listitem><para><envar role="rc-item-web">name</envar>: 11.1359 + String. The name to use for the repository in the web 11.1360 + interface. This overrides the default name, which is 11.1361 + the last component of the repository's path.</para> 11.1362 + </listitem></itemizedlist> 11.1363 + 11.1364 + </sect3> 11.1365 + <sect3> 11.1366 + <title>Options specific to the <command role="hg-cmd">hg 11.1367 + serve</command> command</title> 11.1368 + 11.1369 + <para>Some of the items in the <literal 11.1370 + role="rc-web">web</literal> section of a <filename 11.1371 + role="special">~/.hgrc</filename> file are only for use 11.1372 + with the <command role="hg-cmd">hg serve</command> 11.1373 + command.</para> 11.1374 + <itemizedlist> 11.1375 + <listitem><para><envar role="rc-item-web">accesslog</envar>: 11.1376 + Path. The name of a file into which to write an access 11.1377 + log. By default, the <command role="hg-cmd">hg 11.1378 + serve</command> command writes this information to 11.1379 + standard output, not to a file. Log entries are written 11.1380 + in the standard <quote>combined</quote> file format used 11.1381 + by almost all web servers.</para> 11.1382 + </listitem> 11.1383 + <listitem><para><envar role="rc-item-web">address</envar>: 11.1384 + String. The local address on which the server should 11.1385 + listen for incoming connections. By default, the server 11.1386 + listens on all addresses.</para> 11.1387 + </listitem> 11.1388 + <listitem><para><envar role="rc-item-web">errorlog</envar>: 11.1389 + Path. The name of a file into which to write an error 11.1390 + log. By default, the <command role="hg-cmd">hg 11.1391 + serve</command> command writes this information to 11.1392 + standard error, not to a file.</para> 11.1393 + </listitem> 11.1394 + <listitem><para><envar role="rc-item-web">ipv6</envar>: 11.1395 + Boolean. Whether to use the IPv6 protocol. By default, 11.1396 + IPv6 is not used.</para> 11.1397 + </listitem> 11.1398 + <listitem><para><envar role="rc-item-web">port</envar>: 11.1399 + Integer. The TCP port number on which the server should 11.1400 + listen. The default port number used is 8000.</para> 11.1401 + </listitem></itemizedlist> 11.1402 + 11.1403 + </sect3> 11.1404 + <sect3> 11.1405 + <title>Choosing the right <filename 11.1406 + role="special">~/.hgrc</filename> file to add <literal 11.1407 + role="rc-web">web</literal> items to</title> 11.1408 + 11.1409 + <para>It is important to remember that a web server like 11.1410 + Apache or <literal>lighttpd</literal> will run under a user 11.1411 + ID that is different to yours. CGI scripts run by your 11.1412 + server, such as <filename 11.1413 + role="special">hgweb.cgi</filename>, will usually also run 11.1414 + under that user ID.</para> 11.1415 + 11.1416 + <para>If you add <literal role="rc-web">web</literal> items to 11.1417 + your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that 11.1418 + <filename role="special">~/.hgrc</filename> file. Those 11.1419 + settings will thus only affect the behaviour of the <command 11.1420 + role="hg-cmd">hg serve</command> command when you run it. 11.1421 + To cause CGI scripts to see your settings, either create a 11.1422 + <filename role="special">~/.hgrc</filename> file in the 11.1423 + home directory of the user ID that runs your web server, or 11.1424 + add those settings to a system-wide <filename 11.1425 + role="special">~/.hgrc</filename> file.</para> 11.1426 + 11.1427 + 11.1428 + </sect3> 11.1429 + </sect2> 11.1430 + </sect1> 11.1431 +</chapter> 11.1432 + 11.1433 +<!-- 11.1434 +local variables: 11.1435 +sgml-parent-document: ("00book.xml" "book" "chapter") 11.1436 +end: 11.1437 +-->
12.1 --- a/en/ch05-daily.xml Wed Mar 18 00:08:22 2009 -0700 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,544 +0,0 @@ 12.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 12.5 - 12.6 -<chapter id="chap:daily"> 12.7 - <?dbhtml filename="mercurial-in-daily-use.html"?> 12.8 - <title>Mercurial in daily use</title> 12.9 - 12.10 - <sect1> 12.11 - <title>Telling Mercurial which files to track</title> 12.12 - 12.13 - <para>Mercurial does not work with files in your repository unless 12.14 - you tell it to manage them. The <command role="hg-cmd">hg 12.15 - status</command> command will tell you which files Mercurial 12.16 - doesn't know about; it uses a 12.17 - <quote><literal>?</literal></quote> to display such 12.18 - files.</para> 12.19 - 12.20 - <para>To tell Mercurial to track a file, use the <command 12.21 - role="hg-cmd">hg add</command> command. Once you have added a 12.22 - file, the entry in the output of <command role="hg-cmd">hg 12.23 - status</command> for that file changes from 12.24 - <quote><literal>?</literal></quote> to 12.25 - <quote><literal>A</literal></quote>.</para> 12.26 - 12.27 - &interaction.daily.files.add; 12.28 - 12.29 - <para>After you run a <command role="hg-cmd">hg commit</command>, 12.30 - the files that you added before the commit will no longer be 12.31 - listed in the output of <command role="hg-cmd">hg 12.32 - status</command>. The reason for this is that <command 12.33 - role="hg-cmd">hg status</command> only tells you about 12.34 - <quote>interesting</quote> files&emdash;those that you have 12.35 - modified or told Mercurial to do something with&emdash;by 12.36 - default. If you have a repository that contains thousands of 12.37 - files, you will rarely want to know about files that Mercurial 12.38 - is tracking, but that have not changed. (You can still get this 12.39 - information; we'll return to this later.)</para> 12.40 - 12.41 - <para>Once you add a file, Mercurial doesn't do anything with it 12.42 - immediately. Instead, it will take a snapshot of the file's 12.43 - state the next time you perform a commit. It will then continue 12.44 - to track the changes you make to the file every time you commit, 12.45 - until you remove the file.</para> 12.46 - 12.47 - <sect2> 12.48 - <title>Explicit versus implicit file naming</title> 12.49 - 12.50 - <para>A useful behaviour that Mercurial has is that if you pass 12.51 - the name of a directory to a command, every Mercurial command 12.52 - will treat this as <quote>I want to operate on every file in 12.53 - this directory and its subdirectories</quote>.</para> 12.54 - 12.55 - &interaction.daily.files.add-dir; 12.56 - 12.57 - <para>Notice in this example that Mercurial printed the names of 12.58 - the files it added, whereas it didn't do so when we added the 12.59 - file named <filename>a</filename> in the earlier 12.60 - example.</para> 12.61 - 12.62 - <para>What's going on is that in the former case, we explicitly 12.63 - named the file to add on the command line, so the assumption 12.64 - that Mercurial makes in such cases is that you know what you 12.65 - were doing, and it doesn't print any output.</para> 12.66 - 12.67 - <para>However, when we <emphasis>imply</emphasis> the names of 12.68 - files by giving the name of a directory, Mercurial takes the 12.69 - extra step of printing the name of each file that it does 12.70 - something with. This makes it more clear what is happening, 12.71 - and reduces the likelihood of a silent and nasty surprise. 12.72 - This behaviour is common to most Mercurial commands.</para> 12.73 - 12.74 - </sect2> 12.75 - <sect2> 12.76 - <title>Aside: Mercurial tracks files, not directories</title> 12.77 - 12.78 - <para>Mercurial does not track directory information. Instead, 12.79 - it tracks the path to a file. Before creating a file, it 12.80 - first creates any missing directory components of the path. 12.81 - After it deletes a file, it then deletes any empty directories 12.82 - that were in the deleted file's path. This sounds like a 12.83 - trivial distinction, but it has one minor practical 12.84 - consequence: it is not possible to represent a completely 12.85 - empty directory in Mercurial.</para> 12.86 - 12.87 - <para>Empty directories are rarely useful, and there are 12.88 - unintrusive workarounds that you can use to achieve an 12.89 - appropriate effect. The developers of Mercurial thus felt 12.90 - that the complexity that would be required to manage empty 12.91 - directories was not worth the limited benefit this feature 12.92 - would bring.</para> 12.93 - 12.94 - <para>If you need an empty directory in your repository, there 12.95 - are a few ways to achieve this. One is to create a directory, 12.96 - then <command role="hg-cmd">hg add</command> a 12.97 - <quote>hidden</quote> file to that directory. On Unix-like 12.98 - systems, any file name that begins with a period 12.99 - (<quote><literal>.</literal></quote>) is treated as hidden by 12.100 - most commands and GUI tools. This approach is illustrated 12.101 - below.</para> 12.102 - 12.103 -&interaction.daily.files.hidden; 12.104 - 12.105 - <para>Another way to tackle a need for an empty directory is to 12.106 - simply create one in your automated build scripts before they 12.107 - will need it.</para> 12.108 - 12.109 - </sect2> 12.110 - </sect1> 12.111 - <sect1> 12.112 - <title>How to stop tracking a file</title> 12.113 - 12.114 - <para>Once you decide that a file no longer belongs in your 12.115 - repository, use the <command role="hg-cmd">hg remove</command> 12.116 - command; this deletes the file, and tells Mercurial to stop 12.117 - tracking it. A removed file is represented in the output of 12.118 - <command role="hg-cmd">hg status</command> with a 12.119 - <quote><literal>R</literal></quote>.</para> 12.120 - 12.121 - &interaction.daily.files.remove; 12.122 - 12.123 - <para>After you <command role="hg-cmd">hg remove</command> a file, 12.124 - Mercurial will no longer track changes to that file, even if you 12.125 - recreate a file with the same name in your working directory. 12.126 - If you do recreate a file with the same name and want Mercurial 12.127 - to track the new file, simply <command role="hg-cmd">hg 12.128 - add</command> it. Mercurial will know that the newly added 12.129 - file is not related to the old file of the same name.</para> 12.130 - 12.131 - <sect2> 12.132 - <title>Removing a file does not affect its history</title> 12.133 - 12.134 - <para>It is important to understand that removing a file has 12.135 - only two effects.</para> 12.136 - <itemizedlist> 12.137 - <listitem><para>It removes the current version of the file 12.138 - from the working directory.</para> 12.139 - </listitem> 12.140 - <listitem><para>It stops Mercurial from tracking changes to 12.141 - the file, from the time of the next commit.</para> 12.142 - </listitem></itemizedlist> 12.143 - <para>Removing a file <emphasis>does not</emphasis> in any way 12.144 - alter the <emphasis>history</emphasis> of the file.</para> 12.145 - 12.146 - <para>If you update the working directory to a changeset in 12.147 - which a file that you have removed was still tracked, it will 12.148 - reappear in the working directory, with the contents it had 12.149 - when you committed that changeset. If you then update the 12.150 - working directory to a later changeset, in which the file had 12.151 - been removed, Mercurial will once again remove the file from 12.152 - the working directory.</para> 12.153 - 12.154 - </sect2> 12.155 - <sect2> 12.156 - <title>Missing files</title> 12.157 - 12.158 - <para>Mercurial considers a file that you have deleted, but not 12.159 - used <command role="hg-cmd">hg remove</command> to delete, to 12.160 - be <emphasis>missing</emphasis>. A missing file is 12.161 - represented with <quote><literal>!</literal></quote> in the 12.162 - output of <command role="hg-cmd">hg status</command>. 12.163 - Mercurial commands will not generally do anything with missing 12.164 - files.</para> 12.165 - 12.166 - &interaction.daily.files.missing; 12.167 - 12.168 - <para>If your repository contains a file that <command 12.169 - role="hg-cmd">hg status</command> reports as missing, and 12.170 - you want the file to stay gone, you can run <command 12.171 - role="hg-cmd">hg remove <option 12.172 - role="hg-opt-remove">--after</option></command> at any 12.173 - time later on, to tell Mercurial that you really did mean to 12.174 - remove the file.</para> 12.175 - 12.176 - &interaction.daily.files.remove-after; 12.177 - 12.178 - <para>On the other hand, if you deleted the missing file by 12.179 - accident, give <command role="hg-cmd">hg revert</command> the 12.180 - name of the file to recover. It will reappear, in unmodified 12.181 - form.</para> 12.182 - 12.183 -&interaction.daily.files.recover-missing; 12.184 - 12.185 - </sect2> 12.186 - <sect2> 12.187 - <title>Aside: why tell Mercurial explicitly to remove a 12.188 - file?</title> 12.189 - 12.190 - <para>You might wonder why Mercurial requires you to explicitly 12.191 - tell it that you are deleting a file. Early during the 12.192 - development of Mercurial, it let you delete a file however you 12.193 - pleased; Mercurial would notice the absence of the file 12.194 - automatically when you next ran a <command role="hg-cmd">hg 12.195 - commit</command>, and stop tracking the file. In practice, 12.196 - this made it too easy to accidentally remove a file without 12.197 - noticing.</para> 12.198 - 12.199 - </sect2> 12.200 - <sect2> 12.201 - <title>Useful shorthand&emdash;adding and removing files in one 12.202 - step</title> 12.203 - 12.204 - <para>Mercurial offers a combination command, <command 12.205 - role="hg-cmd">hg addremove</command>, that adds untracked 12.206 - files and marks missing files as removed.</para> 12.207 - 12.208 - &interaction.daily.files.addremove; 12.209 - 12.210 - <para>The <command role="hg-cmd">hg commit</command> command 12.211 - also provides a <option role="hg-opt-commit">-A</option> 12.212 - option that performs this same add-and-remove, immediately 12.213 - followed by a commit.</para> 12.214 - 12.215 - &interaction.daily.files.commit-addremove; 12.216 - 12.217 - </sect2> 12.218 - </sect1> 12.219 - <sect1> 12.220 - <title>Copying files</title> 12.221 - 12.222 - <para>Mercurial provides a <command role="hg-cmd">hg 12.223 - copy</command> command that lets you make a new copy of a 12.224 - file. When you copy a file using this command, Mercurial makes 12.225 - a record of the fact that the new file is a copy of the original 12.226 - file. It treats these copied files specially when you merge 12.227 - your work with someone else's.</para> 12.228 - 12.229 - <sect2> 12.230 - <title>The results of copying during a merge</title> 12.231 - 12.232 - <para>What happens during a merge is that changes 12.233 - <quote>follow</quote> a copy. To best illustrate what this 12.234 - means, let's create an example. We'll start with the usual 12.235 - tiny repository that contains a single file.</para> 12.236 - 12.237 - &interaction.daily.copy.init; 12.238 - 12.239 - <para>We need to do some work in 12.240 - parallel, so that we'll have something to merge. So let's 12.241 - clone our repository.</para> 12.242 - 12.243 - &interaction.daily.copy.clone; 12.244 - 12.245 - <para>Back in our initial repository, let's use the <command 12.246 - role="hg-cmd">hg copy</command> command to make a copy of 12.247 - the first file we created.</para> 12.248 - 12.249 - &interaction.daily.copy.copy; 12.250 - 12.251 - <para>If we look at the output of the <command role="hg-cmd">hg 12.252 - status</command> command afterwards, the copied file looks 12.253 - just like a normal added file.</para> 12.254 - 12.255 - &interaction.daily.copy.status; 12.256 - 12.257 - <para>But if we pass the <option 12.258 - role="hg-opt-status">-C</option> option to <command 12.259 - role="hg-cmd">hg status</command>, it prints another line of 12.260 - output: this is the file that our newly-added file was copied 12.261 - <emphasis>from</emphasis>.</para> 12.262 - 12.263 - &interaction.daily.copy.status-copy; 12.264 - 12.265 - <para>Now, back in the repository we cloned, let's make a change 12.266 - in parallel. We'll add a line of content to the original file 12.267 - that we created.</para> 12.268 - 12.269 - &interaction.daily.copy.other; 12.270 - 12.271 - <para>Now we have a modified <filename>file</filename> in this 12.272 - repository. When we pull the changes from the first 12.273 - repository, and merge the two heads, Mercurial will propagate 12.274 - the changes that we made locally to <filename>file</filename> 12.275 - into its copy, <filename>new-file</filename>.</para> 12.276 - 12.277 - &interaction.daily.copy.merge; 12.278 - 12.279 - </sect2> 12.280 - <sect2 id="sec:daily:why-copy"> 12.281 - <title>Why should changes follow copies?</title> 12.282 - 12.283 - <para>This behaviour, of changes to a file propagating out to 12.284 - copies of the file, might seem esoteric, but in most cases 12.285 - it's highly desirable.</para> 12.286 - 12.287 - <para>First of all, remember that this propagation 12.288 - <emphasis>only</emphasis> happens when you merge. So if you 12.289 - <command role="hg-cmd">hg copy</command> a file, and 12.290 - subsequently modify the original file during the normal course 12.291 - of your work, nothing will happen.</para> 12.292 - 12.293 - <para>The second thing to know is that modifications will only 12.294 - propagate across a copy as long as the repository that you're 12.295 - pulling changes from <emphasis>doesn't know</emphasis> about 12.296 - the copy.</para> 12.297 - 12.298 - <para>The reason that Mercurial does this is as follows. Let's 12.299 - say I make an important bug fix in a source file, and commit 12.300 - my changes. Meanwhile, you've decided to <command 12.301 - role="hg-cmd">hg copy</command> the file in your repository, 12.302 - without knowing about the bug or having seen the fix, and you 12.303 - have started hacking on your copy of the file.</para> 12.304 - 12.305 - <para>If you pulled and merged my changes, and Mercurial 12.306 - <emphasis>didn't</emphasis> propagate changes across copies, 12.307 - your source file would now contain the bug, and unless you 12.308 - remembered to propagate the bug fix by hand, the bug would 12.309 - <emphasis>remain</emphasis> in your copy of the file.</para> 12.310 - 12.311 - <para>By automatically propagating the change that fixed the bug 12.312 - from the original file to the copy, Mercurial prevents this 12.313 - class of problem. To my knowledge, Mercurial is the 12.314 - <emphasis>only</emphasis> revision control system that 12.315 - propagates changes across copies like this.</para> 12.316 - 12.317 - <para>Once your change history has a record that the copy and 12.318 - subsequent merge occurred, there's usually no further need to 12.319 - propagate changes from the original file to the copied file, 12.320 - and that's why Mercurial only propagates changes across copies 12.321 - until this point, and no further.</para> 12.322 - 12.323 - </sect2> 12.324 - <sect2> 12.325 - <title>How to make changes <emphasis>not</emphasis> follow a 12.326 - copy</title> 12.327 - 12.328 - <para>If, for some reason, you decide that this business of 12.329 - automatically propagating changes across copies is not for 12.330 - you, simply use your system's normal file copy command (on 12.331 - Unix-like systems, that's <command>cp</command>) to make a 12.332 - copy of a file, then <command role="hg-cmd">hg add</command> 12.333 - the new copy by hand. Before you do so, though, please do 12.334 - reread section <xref linkend="sec:daily:why-copy"/>, and make 12.335 - an informed 12.336 - decision that this behaviour is not appropriate to your 12.337 - specific case.</para> 12.338 - 12.339 - </sect2> 12.340 - <sect2> 12.341 - <title>Behaviour of the <command role="hg-cmd">hg copy</command> 12.342 - command</title> 12.343 - 12.344 - <para>When you use the <command role="hg-cmd">hg copy</command> 12.345 - command, Mercurial makes a copy of each source file as it 12.346 - currently stands in the working directory. This means that if 12.347 - you make some modifications to a file, then <command 12.348 - role="hg-cmd">hg copy</command> it without first having 12.349 - committed those changes, the new copy will also contain the 12.350 - modifications you have made up until that point. (I find this 12.351 - behaviour a little counterintuitive, which is why I mention it 12.352 - here.)</para> 12.353 - 12.354 - <para>The <command role="hg-cmd">hg copy</command> command acts 12.355 - similarly to the Unix <command>cp</command> command (you can 12.356 - use the <command role="hg-cmd">hg cp</command> alias if you 12.357 - prefer). The last argument is the 12.358 - <emphasis>destination</emphasis>, and all prior arguments are 12.359 - <emphasis>sources</emphasis>. If you pass it a single file as 12.360 - the source, and the destination does not exist, it creates a 12.361 - new file with that name.</para> 12.362 - 12.363 - &interaction.daily.copy.simple; 12.364 - 12.365 - <para>If the destination is a directory, Mercurial copies its 12.366 - sources into that directory.</para> 12.367 - 12.368 - &interaction.daily.copy.dir-dest; 12.369 - 12.370 - <para>Copying a directory is 12.371 - recursive, and preserves the directory structure of the 12.372 - source.</para> 12.373 - 12.374 - &interaction.daily.copy.dir-src; 12.375 - 12.376 - <para>If the source and destination are both directories, the 12.377 - source tree is recreated in the destination directory.</para> 12.378 - 12.379 - &interaction.daily.copy.dir-src-dest; 12.380 - 12.381 - <para>As with the <command role="hg-cmd">hg rename</command> 12.382 - command, if you copy a file manually and then want Mercurial 12.383 - to know that you've copied the file, simply use the <option 12.384 - role="hg-opt-copy">--after</option> option to <command 12.385 - role="hg-cmd">hg copy</command>.</para> 12.386 - 12.387 - &interaction.daily.copy.after; 12.388 - 12.389 - </sect2> 12.390 - </sect1> 12.391 - <sect1> 12.392 - <title>Renaming files</title> 12.393 - 12.394 - <para>It's rather more common to need to rename a file than to 12.395 - make a copy of it. The reason I discussed the <command 12.396 - role="hg-cmd">hg copy</command> command before talking about 12.397 - renaming files is that Mercurial treats a rename in essentially 12.398 - the same way as a copy. Therefore, knowing what Mercurial does 12.399 - when you copy a file tells you what to expect when you rename a 12.400 - file.</para> 12.401 - 12.402 - <para>When you use the <command role="hg-cmd">hg rename</command> 12.403 - command, Mercurial makes a copy of each source file, then 12.404 - deletes it and marks the file as removed.</para> 12.405 - 12.406 - &interaction.daily.rename.rename; 12.407 - 12.408 - <para>The <command role="hg-cmd">hg status</command> command shows 12.409 - the newly copied file as added, and the copied-from file as 12.410 - removed.</para> 12.411 - 12.412 - &interaction.daily.rename.status; 12.413 - 12.414 - <para>As with the results of a <command role="hg-cmd">hg 12.415 - copy</command>, we must use the <option 12.416 - role="hg-opt-status">-C</option> option to <command 12.417 - role="hg-cmd">hg status</command> to see that the added file 12.418 - is really being tracked by Mercurial as a copy of the original, 12.419 - now removed, file.</para> 12.420 - 12.421 - &interaction.daily.rename.status-copy; 12.422 - 12.423 - <para>As with <command role="hg-cmd">hg remove</command> and 12.424 - <command role="hg-cmd">hg copy</command>, you can tell Mercurial 12.425 - about a rename after the fact using the <option 12.426 - role="hg-opt-rename">--after</option> option. In most other 12.427 - respects, the behaviour of the <command role="hg-cmd">hg 12.428 - rename</command> command, and the options it accepts, are 12.429 - similar to the <command role="hg-cmd">hg copy</command> 12.430 - command.</para> 12.431 - 12.432 - <sect2> 12.433 - <title>Renaming files and merging changes</title> 12.434 - 12.435 - <para>Since Mercurial's rename is implemented as 12.436 - copy-and-remove, the same propagation of changes happens when 12.437 - you merge after a rename as after a copy.</para> 12.438 - 12.439 - <para>If I modify a file, and you rename it to a new name, and 12.440 - then we merge our respective changes, my modifications to the 12.441 - file under its original name will be propagated into the file 12.442 - under its new name. (This is something you might expect to 12.443 - <quote>simply work,</quote> but not all revision control 12.444 - systems actually do this.)</para> 12.445 - 12.446 - <para>Whereas having changes follow a copy is a feature where 12.447 - you can perhaps nod and say <quote>yes, that might be 12.448 - useful,</quote> it should be clear that having them follow a 12.449 - rename is definitely important. Without this facility, it 12.450 - would simply be too easy for changes to become orphaned when 12.451 - files are renamed.</para> 12.452 - 12.453 - </sect2> 12.454 - <sect2> 12.455 - <title>Divergent renames and merging</title> 12.456 - 12.457 - <para>The case of diverging names occurs when two developers 12.458 - start with a file&emdash;let's call it 12.459 - <filename>foo</filename>&emdash;in their respective 12.460 - repositories.</para> 12.461 - 12.462 - &interaction.rename.divergent.clone; 12.463 - 12.464 - <para>Anne renames the file to <filename>bar</filename>.</para> 12.465 - 12.466 - &interaction.rename.divergent.rename.anne; 12.467 - 12.468 - <para>Meanwhile, Bob renames it to 12.469 - <filename>quux</filename>.</para> 12.470 - 12.471 - &interaction.rename.divergent.rename.bob; 12.472 - 12.473 - <para>I like to think of this as a conflict because each 12.474 - developer has expressed different intentions about what the 12.475 - file ought to be named.</para> 12.476 - 12.477 - <para>What do you think should happen when they merge their 12.478 - work? Mercurial's actual behaviour is that it always preserves 12.479 - <emphasis>both</emphasis> names when it merges changesets that 12.480 - contain divergent renames.</para> 12.481 - 12.482 - &interaction.rename.divergent.merge; 12.483 - 12.484 - <para>Notice that Mercurial does warn about the divergent 12.485 - renames, but it leaves it up to you to do something about the 12.486 - divergence after the merge.</para> 12.487 - 12.488 - </sect2> 12.489 - <sect2> 12.490 - <title>Convergent renames and merging</title> 12.491 - 12.492 - <para>Another kind of rename conflict occurs when two people 12.493 - choose to rename different <emphasis>source</emphasis> files 12.494 - to the same <emphasis>destination</emphasis>. In this case, 12.495 - Mercurial runs its normal merge machinery, and lets you guide 12.496 - it to a suitable resolution.</para> 12.497 - 12.498 - </sect2> 12.499 - <sect2> 12.500 - <title>Other name-related corner cases</title> 12.501 - 12.502 - <para>Mercurial has a longstanding bug in which it fails to 12.503 - handle a merge where one side has a file with a given name, 12.504 - while another has a directory with the same name. This is 12.505 - documented as <ulink role="hg-bug" 12.506 - url="http://www.selenic.com/mercurial/bts/issue29">issue 12.507 - 29</ulink>.</para> 12.508 - 12.509 - &interaction.issue29.go; 12.510 - 12.511 - </sect2> 12.512 - </sect1> 12.513 - <sect1> 12.514 - <title>Recovering from mistakes</title> 12.515 - 12.516 - <para>Mercurial has some useful commands that will help you to 12.517 - recover from some common mistakes.</para> 12.518 - 12.519 - <para>The <command role="hg-cmd">hg revert</command> command lets 12.520 - you undo changes that you have made to your working directory. 12.521 - For example, if you <command role="hg-cmd">hg add</command> a 12.522 - file by accident, just run <command role="hg-cmd">hg 12.523 - revert</command> with the name of the file you added, and 12.524 - while the file won't be touched in any way, it won't be tracked 12.525 - for adding by Mercurial any longer, either. You can also use 12.526 - <command role="hg-cmd">hg revert</command> to get rid of 12.527 - erroneous changes to a file.</para> 12.528 - 12.529 - <para>It's useful to remember that the <command role="hg-cmd">hg 12.530 - revert</command> command is useful for changes that you have 12.531 - not yet committed. Once you've committed a change, if you 12.532 - decide it was a mistake, you can still do something about it, 12.533 - though your options may be more limited.</para> 12.534 - 12.535 - <para>For more information about the <command role="hg-cmd">hg 12.536 - revert</command> command, and details about how to deal with 12.537 - changes you have already committed, see chapter <xref 12.538 - linkend="chap:undo"/>.</para> 12.539 - 12.540 - </sect1> 12.541 -</chapter> 12.542 - 12.543 -<!-- 12.544 -local variables: 12.545 -sgml-parent-document: ("00book.xml" "book" "chapter") 12.546 -end: 12.547 --->
13.1 --- a/en/ch06-collab.xml Wed Mar 18 00:08:22 2009 -0700 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,1434 +0,0 @@ 13.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 13.5 - 13.6 -<chapter id="cha:collab"> 13.7 - <?dbhtml filename="collaborating-with-other-people.html"?> 13.8 - <title>Collaborating with other people</title> 13.9 - 13.10 - <para>As a completely decentralised tool, Mercurial doesn't impose 13.11 - any policy on how people ought to work with each other. However, 13.12 - if you're new to distributed revision control, it helps to have 13.13 - some tools and examples in mind when you're thinking about 13.14 - possible workflow models.</para> 13.15 - 13.16 - <sect1> 13.17 - <title>Mercurial's web interface</title> 13.18 - 13.19 - <para>Mercurial has a powerful web interface that provides several 13.20 - useful capabilities.</para> 13.21 - 13.22 - <para>For interactive use, the web interface lets you browse a 13.23 - single repository or a collection of repositories. You can view 13.24 - the history of a repository, examine each change (comments and 13.25 - diffs), and view the contents of each directory and file.</para> 13.26 - 13.27 - <para>Also for human consumption, the web interface provides an 13.28 - RSS feed of the changes in a repository. This lets you 13.29 - <quote>subscribe</quote> to a repository using your favourite 13.30 - feed reader, and be automatically notified of activity in that 13.31 - repository as soon as it happens. I find this capability much 13.32 - more convenient than the model of subscribing to a mailing list 13.33 - to which notifications are sent, as it requires no additional 13.34 - configuration on the part of whoever is serving the 13.35 - repository.</para> 13.36 - 13.37 - <para>The web interface also lets remote users clone a repository, 13.38 - pull changes from it, and (when the server is configured to 13.39 - permit it) push changes back to it. Mercurial's HTTP tunneling 13.40 - protocol aggressively compresses data, so that it works 13.41 - efficiently even over low-bandwidth network connections.</para> 13.42 - 13.43 - <para>The easiest way to get started with the web interface is to 13.44 - use your web browser to visit an existing repository, such as 13.45 - the master Mercurial repository at <ulink 13.46 - url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para> 13.47 - 13.48 - <para>If you're interested in providing a web interface to your 13.49 - own repositories, Mercurial provides two ways to do this. The 13.50 - first is using the <command role="hg-cmd">hg serve</command> 13.51 - command, which is best suited to short-term 13.52 - <quote>lightweight</quote> serving. See section <xref 13.53 - linkend="sec:collab:serve"/> below for details of how to use 13.54 - this command. If you have a long-lived repository that you'd 13.55 - like to make permanently available, Mercurial has built-in 13.56 - support for the CGI (Common Gateway Interface) standard, which 13.57 - all common web servers support. See section <xref 13.58 - linkend="sec:collab:cgi"/> for details of CGI 13.59 - configuration.</para> 13.60 - 13.61 - </sect1> 13.62 - <sect1> 13.63 - <title>Collaboration models</title> 13.64 - 13.65 - <para>With a suitably flexible tool, making decisions about 13.66 - workflow is much more of a social engineering challenge than a 13.67 - technical one. Mercurial imposes few limitations on how you can 13.68 - structure the flow of work in a project, so it's up to you and 13.69 - your group to set up and live with a model that matches your own 13.70 - particular needs.</para> 13.71 - 13.72 - <sect2> 13.73 - <title>Factors to keep in mind</title> 13.74 - 13.75 - <para>The most important aspect of any model that you must keep 13.76 - in mind is how well it matches the needs and capabilities of 13.77 - the people who will be using it. This might seem 13.78 - self-evident; even so, you still can't afford to forget it for 13.79 - a moment.</para> 13.80 - 13.81 - <para>I once put together a workflow model that seemed to make 13.82 - perfect sense to me, but that caused a considerable amount of 13.83 - consternation and strife within my development team. In spite 13.84 - of my attempts to explain why we needed a complex set of 13.85 - branches, and how changes ought to flow between them, a few 13.86 - team members revolted. Even though they were smart people, 13.87 - they didn't want to pay attention to the constraints we were 13.88 - operating under, or face the consequences of those constraints 13.89 - in the details of the model that I was advocating.</para> 13.90 - 13.91 - <para>Don't sweep foreseeable social or technical problems under 13.92 - the rug. Whatever scheme you put into effect, you should plan 13.93 - for mistakes and problem scenarios. Consider adding automated 13.94 - machinery to prevent, or quickly recover from, trouble that 13.95 - you can anticipate. As an example, if you intend to have a 13.96 - branch with not-for-release changes in it, you'd do well to 13.97 - think early about the possibility that someone might 13.98 - accidentally merge those changes into a release branch. You 13.99 - could avoid this particular problem by writing a hook that 13.100 - prevents changes from being merged from an inappropriate 13.101 - branch.</para> 13.102 - 13.103 - </sect2> 13.104 - <sect2> 13.105 - <title>Informal anarchy</title> 13.106 - 13.107 - <para>I wouldn't suggest an <quote>anything goes</quote> 13.108 - approach as something sustainable, but it's a model that's 13.109 - easy to grasp, and it works perfectly well in a few unusual 13.110 - situations.</para> 13.111 - 13.112 - <para>As one example, many projects have a loose-knit group of 13.113 - collaborators who rarely physically meet each other. Some 13.114 - groups like to overcome the isolation of working at a distance 13.115 - by organising occasional <quote>sprints</quote>. In a sprint, 13.116 - a number of people get together in a single location (a 13.117 - company's conference room, a hotel meeting room, that kind of 13.118 - place) and spend several days more or less locked in there, 13.119 - hacking intensely on a handful of projects.</para> 13.120 - 13.121 - <para>A sprint is the perfect place to use the <command 13.122 - role="hg-cmd">hg serve</command> command, since <command 13.123 - role="hg-cmd">hg serve</command> does not require any fancy 13.124 - server infrastructure. You can get started with <command 13.125 - role="hg-cmd">hg serve</command> in moments, by reading 13.126 - section <xref linkend="sec:collab:serve"/> below. Then simply 13.127 - tell 13.128 - the person next to you that you're running a server, send the 13.129 - URL to them in an instant message, and you immediately have a 13.130 - quick-turnaround way to work together. They can type your URL 13.131 - into their web browser and quickly review your changes; or 13.132 - they can pull a bugfix from you and verify it; or they can 13.133 - clone a branch containing a new feature and try it out.</para> 13.134 - 13.135 - <para>The charm, and the problem, with doing things in an ad hoc 13.136 - fashion like this is that only people who know about your 13.137 - changes, and where they are, can see them. Such an informal 13.138 - approach simply doesn't scale beyond a handful people, because 13.139 - each individual needs to know about $n$ different repositories 13.140 - to pull from.</para> 13.141 - 13.142 - </sect2> 13.143 - <sect2> 13.144 - <title>A single central repository</title> 13.145 - 13.146 - <para>For smaller projects migrating from a centralised revision 13.147 - control tool, perhaps the easiest way to get started is to 13.148 - have changes flow through a single shared central repository. 13.149 - This is also the most common <quote>building block</quote> for 13.150 - more ambitious workflow schemes.</para> 13.151 - 13.152 - <para>Contributors start by cloning a copy of this repository. 13.153 - They can pull changes from it whenever they need to, and some 13.154 - (perhaps all) developers have permission to push a change back 13.155 - when they're ready for other people to see it.</para> 13.156 - 13.157 - <para>Under this model, it can still often make sense for people 13.158 - to pull changes directly from each other, without going 13.159 - through the central repository. Consider a case in which I 13.160 - have a tentative bug fix, but I am worried that if I were to 13.161 - publish it to the central repository, it might subsequently 13.162 - break everyone else's trees as they pull it. To reduce the 13.163 - potential for damage, I can ask you to clone my repository 13.164 - into a temporary repository of your own and test it. This 13.165 - lets us put off publishing the potentially unsafe change until 13.166 - it has had a little testing.</para> 13.167 - 13.168 - <para>In this kind of scenario, people usually use the 13.169 - <command>ssh</command> protocol to securely push changes to 13.170 - the central repository, as documented in section <xref 13.171 - linkend="sec:collab:ssh"/>. It's also 13.172 - usual to publish a read-only copy of the repository over HTTP 13.173 - using CGI, as in section <xref linkend="sec:collab:cgi"/>. 13.174 - Publishing over HTTP 13.175 - satisfies the needs of people who don't have push access, and 13.176 - those who want to use web browsers to browse the repository's 13.177 - history.</para> 13.178 - 13.179 - </sect2> 13.180 - <sect2> 13.181 - <title>Working with multiple branches</title> 13.182 - 13.183 - <para>Projects of any significant size naturally tend to make 13.184 - progress on several fronts simultaneously. In the case of 13.185 - software, it's common for a project to go through periodic 13.186 - official releases. A release might then go into 13.187 - <quote>maintenance mode</quote> for a while after its first 13.188 - publication; maintenance releases tend to contain only bug 13.189 - fixes, not new features. In parallel with these maintenance 13.190 - releases, one or more future releases may be under 13.191 - development. People normally use the word 13.192 - <quote>branch</quote> to refer to one of these many slightly 13.193 - different directions in which development is 13.194 - proceeding.</para> 13.195 - 13.196 - <para>Mercurial is particularly well suited to managing a number 13.197 - of simultaneous, but not identical, branches. Each 13.198 - <quote>development direction</quote> can live in its own 13.199 - central repository, and you can merge changes from one to 13.200 - another as the need arises. Because repositories are 13.201 - independent of each other, unstable changes in a development 13.202 - branch will never affect a stable branch unless someone 13.203 - explicitly merges those changes in.</para> 13.204 - 13.205 - <para>Here's an example of how this can work in practice. Let's 13.206 - say you have one <quote>main branch</quote> on a central 13.207 - server.</para> 13.208 - 13.209 - &interaction.branching.init; 13.210 - 13.211 - <para>People clone it, make changes locally, test them, and push 13.212 - them back.</para> 13.213 - 13.214 - <para>Once the main branch reaches a release milestone, you can 13.215 - use the <command role="hg-cmd">hg tag</command> command to 13.216 - give a permanent name to the milestone revision.</para> 13.217 - 13.218 - &interaction.branching.tag; 13.219 - 13.220 - <para>Let's say some ongoing 13.221 - development occurs on the main branch.</para> 13.222 - 13.223 - &interaction.branching.main; 13.224 - 13.225 - <para>Using the tag that was recorded at the milestone, people 13.226 - who clone that repository at any time in the future can use 13.227 - <command role="hg-cmd">hg update</command> to get a copy of 13.228 - the working directory exactly as it was when that tagged 13.229 - revision was committed.</para> 13.230 - 13.231 - &interaction.branching.update; 13.232 - 13.233 - <para>In addition, immediately after the main branch is tagged, 13.234 - someone can then clone the main branch on the server to a new 13.235 - <quote>stable</quote> branch, also on the server.</para> 13.236 - 13.237 - &interaction.branching.clone; 13.238 - 13.239 - <para>Someone who needs to make a change to the stable branch 13.240 - can then clone <emphasis>that</emphasis> repository, make 13.241 - their changes, commit, and push their changes back there.</para> 13.242 - 13.243 - &interaction.branching.stable; 13.244 - 13.245 - <para>Because Mercurial repositories are independent, and 13.246 - Mercurial doesn't move changes around automatically, the 13.247 - stable and main branches are <emphasis>isolated</emphasis> 13.248 - from each other. The changes that you made on the main branch 13.249 - don't <quote>leak</quote> to the stable branch, and vice 13.250 - versa.</para> 13.251 - 13.252 - <para>You'll often want all of your bugfixes on the stable 13.253 - branch to show up on the main branch, too. Rather than 13.254 - rewrite a bugfix on the main branch, you can simply pull and 13.255 - merge changes from the stable to the main branch, and 13.256 - Mercurial will bring those bugfixes in for you.</para> 13.257 - 13.258 - &interaction.branching.merge; 13.259 - 13.260 - <para>The main branch will still contain changes that are not on 13.261 - the stable branch, but it will also contain all of the 13.262 - bugfixes from the stable branch. The stable branch remains 13.263 - unaffected by these changes.</para> 13.264 - 13.265 - </sect2> 13.266 - <sect2> 13.267 - <title>Feature branches</title> 13.268 - 13.269 - <para>For larger projects, an effective way to manage change is 13.270 - to break up a team into smaller groups. Each group has a 13.271 - shared branch of its own, cloned from a single 13.272 - <quote>master</quote> branch used by the entire project. 13.273 - People working on an individual branch are typically quite 13.274 - isolated from developments on other branches.</para> 13.275 - 13.276 - <informalfigure id="fig:collab:feature-branches"> 13.277 - <mediaobject><imageobject><imagedata 13.278 - fileref="feature-branches"/></imageobject><textobject><phrase>XXX 13.279 - add text</phrase></textobject><caption><para>Feature 13.280 - branches</para></caption></mediaobject> 13.281 - </informalfigure> 13.282 - 13.283 - <para>When a particular feature is deemed to be in suitable 13.284 - shape, someone on that feature team pulls and merges from the 13.285 - master branch into the feature branch, then pushes back up to 13.286 - the master branch.</para> 13.287 - 13.288 - </sect2> 13.289 - <sect2> 13.290 - <title>The release train</title> 13.291 - 13.292 - <para>Some projects are organised on a <quote>train</quote> 13.293 - basis: a release is scheduled to happen every few months, and 13.294 - whatever features are ready when the <quote>train</quote> is 13.295 - ready to leave are allowed in.</para> 13.296 - 13.297 - <para>This model resembles working with feature branches. The 13.298 - difference is that when a feature branch misses a train, 13.299 - someone on the feature team pulls and merges the changes that 13.300 - went out on that train release into the feature branch, and 13.301 - the team continues its work on top of that release so that 13.302 - their feature can make the next release.</para> 13.303 - 13.304 - </sect2> 13.305 - <sect2> 13.306 - <title>The Linux kernel model</title> 13.307 - 13.308 - <para>The development of the Linux kernel has a shallow 13.309 - hierarchical structure, surrounded by a cloud of apparent 13.310 - chaos. Because most Linux developers use 13.311 - <command>git</command>, a distributed revision control tool 13.312 - with capabilities similar to Mercurial, it's useful to 13.313 - describe the way work flows in that environment; if you like 13.314 - the ideas, the approach translates well across tools.</para> 13.315 - 13.316 - <para>At the center of the community sits Linus Torvalds, the 13.317 - creator of Linux. He publishes a single source repository 13.318 - that is considered the <quote>authoritative</quote> current 13.319 - tree by the entire developer community. Anyone can clone 13.320 - Linus's tree, but he is very choosy about whose trees he pulls 13.321 - from.</para> 13.322 - 13.323 - <para>Linus has a number of <quote>trusted lieutenants</quote>. 13.324 - As a general rule, he pulls whatever changes they publish, in 13.325 - most cases without even reviewing those changes. Some of 13.326 - those lieutenants are generally agreed to be 13.327 - <quote>maintainers</quote>, responsible for specific 13.328 - subsystems within the kernel. If a random kernel hacker wants 13.329 - to make a change to a subsystem that they want to end up in 13.330 - Linus's tree, they must find out who the subsystem's 13.331 - maintainer is, and ask that maintainer to take their change. 13.332 - If the maintainer reviews their changes and agrees to take 13.333 - them, they'll pass them along to Linus in due course.</para> 13.334 - 13.335 - <para>Individual lieutenants have their own approaches to 13.336 - reviewing, accepting, and publishing changes; and for deciding 13.337 - when to feed them to Linus. In addition, there are several 13.338 - well known branches that people use for different purposes. 13.339 - For example, a few people maintain <quote>stable</quote> 13.340 - repositories of older versions of the kernel, to which they 13.341 - apply critical fixes as needed. Some maintainers publish 13.342 - multiple trees: one for experimental changes; one for changes 13.343 - that they are about to feed upstream; and so on. Others just 13.344 - publish a single tree.</para> 13.345 - 13.346 - <para>This model has two notable features. The first is that 13.347 - it's <quote>pull only</quote>. You have to ask, convince, or 13.348 - beg another developer to take a change from you, because there 13.349 - are almost no trees to which more than one person can push, 13.350 - and there's no way to push changes into a tree that someone 13.351 - else controls.</para> 13.352 - 13.353 - <para>The second is that it's based on reputation and acclaim. 13.354 - If you're an unknown, Linus will probably ignore changes from 13.355 - you without even responding. But a subsystem maintainer will 13.356 - probably review them, and will likely take them if they pass 13.357 - their criteria for suitability. The more <quote>good</quote> 13.358 - changes you contribute to a maintainer, the more likely they 13.359 - are to trust your judgment and accept your changes. If you're 13.360 - well-known and maintain a long-lived branch for something 13.361 - Linus hasn't yet accepted, people with similar interests may 13.362 - pull your changes regularly to keep up with your work.</para> 13.363 - 13.364 - <para>Reputation and acclaim don't necessarily cross subsystem 13.365 - or <quote>people</quote> boundaries. If you're a respected 13.366 - but specialised storage hacker, and you try to fix a 13.367 - networking bug, that change will receive a level of scrutiny 13.368 - from a network maintainer comparable to a change from a 13.369 - complete stranger.</para> 13.370 - 13.371 - <para>To people who come from more orderly project backgrounds, 13.372 - the comparatively chaotic Linux kernel development process 13.373 - often seems completely insane. It's subject to the whims of 13.374 - individuals; people make sweeping changes whenever they deem 13.375 - it appropriate; and the pace of development is astounding. 13.376 - And yet Linux is a highly successful, well-regarded piece of 13.377 - software.</para> 13.378 - 13.379 - </sect2> 13.380 - <sect2> 13.381 - <title>Pull-only versus shared-push collaboration</title> 13.382 - 13.383 - <para>A perpetual source of heat in the open source community is 13.384 - whether a development model in which people only ever pull 13.385 - changes from others is <quote>better than</quote> one in which 13.386 - multiple people can push changes to a shared 13.387 - repository.</para> 13.388 - 13.389 - <para>Typically, the backers of the shared-push model use tools 13.390 - that actively enforce this approach. If you're using a 13.391 - centralised revision control tool such as Subversion, there's 13.392 - no way to make a choice over which model you'll use: the tool 13.393 - gives you shared-push, and if you want to do anything else, 13.394 - you'll have to roll your own approach on top (such as applying 13.395 - a patch by hand).</para> 13.396 - 13.397 - <para>A good distributed revision control tool, such as 13.398 - Mercurial, will support both models. You and your 13.399 - collaborators can then structure how you work together based 13.400 - on your own needs and preferences, not on what contortions 13.401 - your tools force you into.</para> 13.402 - 13.403 - </sect2> 13.404 - <sect2> 13.405 - <title>Where collaboration meets branch management</title> 13.406 - 13.407 - <para>Once you and your team set up some shared repositories and 13.408 - start propagating changes back and forth between local and 13.409 - shared repos, you begin to face a related, but slightly 13.410 - different challenge: that of managing the multiple directions 13.411 - in which your team may be moving at once. Even though this 13.412 - subject is intimately related to how your team collaborates, 13.413 - it's dense enough to merit treatment of its own, in chapter 13.414 - <xref linkend="chap:branch"/>.</para> 13.415 - 13.416 - </sect2> 13.417 - </sect1> 13.418 - <sect1> 13.419 - <title>The technical side of sharing</title> 13.420 - 13.421 - <para>The remainder of this chapter is devoted to the question of 13.422 - serving data to your collaborators.</para> 13.423 - 13.424 - </sect1> 13.425 - <sect1 id="sec:collab:serve"> 13.426 - <title>Informal sharing with <command role="hg-cmd">hg 13.427 - serve</command></title> 13.428 - 13.429 - <para>Mercurial's <command role="hg-cmd">hg serve</command> 13.430 - command is wonderfully suited to small, tight-knit, and 13.431 - fast-paced group environments. It also provides a great way to 13.432 - get a feel for using Mercurial commands over a network.</para> 13.433 - 13.434 - <para>Run <command role="hg-cmd">hg serve</command> inside a 13.435 - repository, and in under a second it will bring up a specialised 13.436 - HTTP server; this will accept connections from any client, and 13.437 - serve up data for that repository until you terminate it. 13.438 - Anyone who knows the URL of the server you just started, and can 13.439 - talk to your computer over the network, can then use a web 13.440 - browser or Mercurial to read data from that repository. A URL 13.441 - for a <command role="hg-cmd">hg serve</command> instance running 13.442 - on a laptop is likely to look something like 13.443 - <literal>http://my-laptop.local:8000/</literal>.</para> 13.444 - 13.445 - <para>The <command role="hg-cmd">hg serve</command> command is 13.446 - <emphasis>not</emphasis> a general-purpose web server. It can do 13.447 - only two things:</para> 13.448 - <itemizedlist> 13.449 - <listitem><para>Allow people to browse the history of the 13.450 - repository it's serving, from their normal web 13.451 - browsers.</para> 13.452 - </listitem> 13.453 - <listitem><para>Speak Mercurial's wire protocol, so that people 13.454 - can <command role="hg-cmd">hg clone</command> or <command 13.455 - role="hg-cmd">hg pull</command> changes from that 13.456 - repository.</para> 13.457 - </listitem></itemizedlist> 13.458 - <para>In particular, <command role="hg-cmd">hg serve</command> 13.459 - won't allow remote users to <emphasis>modify</emphasis> your 13.460 - repository. It's intended for read-only use.</para> 13.461 - 13.462 - <para>If you're getting started with Mercurial, there's nothing to 13.463 - prevent you from using <command role="hg-cmd">hg serve</command> 13.464 - to serve up a repository on your own computer, then use commands 13.465 - like <command role="hg-cmd">hg clone</command>, <command 13.466 - role="hg-cmd">hg incoming</command>, and so on to talk to that 13.467 - server as if the repository was hosted remotely. This can help 13.468 - you to quickly get acquainted with using commands on 13.469 - network-hosted repositories.</para> 13.470 - 13.471 - <sect2> 13.472 - <title>A few things to keep in mind</title> 13.473 - 13.474 - <para>Because it provides unauthenticated read access to all 13.475 - clients, you should only use <command role="hg-cmd">hg 13.476 - serve</command> in an environment where you either don't 13.477 - care, or have complete control over, who can access your 13.478 - network and pull data from your repository.</para> 13.479 - 13.480 - <para>The <command role="hg-cmd">hg serve</command> command 13.481 - knows nothing about any firewall software you might have 13.482 - installed on your system or network. It cannot detect or 13.483 - control your firewall software. If other people are unable to 13.484 - talk to a running <command role="hg-cmd">hg serve</command> 13.485 - instance, the second thing you should do 13.486 - (<emphasis>after</emphasis> you make sure that they're using 13.487 - the correct URL) is check your firewall configuration.</para> 13.488 - 13.489 - <para>By default, <command role="hg-cmd">hg serve</command> 13.490 - listens for incoming connections on port 8000. If another 13.491 - process is already listening on the port you want to use, you 13.492 - can specify a different port to listen on using the <option 13.493 - role="hg-opt-serve">-p</option> option.</para> 13.494 - 13.495 - <para>Normally, when <command role="hg-cmd">hg serve</command> 13.496 - starts, it prints no output, which can be a bit unnerving. If 13.497 - you'd like to confirm that it is indeed running correctly, and 13.498 - find out what URL you should send to your collaborators, start 13.499 - it with the <option role="hg-opt-global">-v</option> 13.500 - option.</para> 13.501 - 13.502 - </sect2> 13.503 - </sect1> 13.504 - <sect1 id="sec:collab:ssh"> 13.505 - <title>Using the Secure Shell (ssh) protocol</title> 13.506 - 13.507 - <para>You can pull and push changes securely over a network 13.508 - connection using the Secure Shell (<literal>ssh</literal>) 13.509 - protocol. To use this successfully, you may have to do a little 13.510 - bit of configuration on the client or server sides.</para> 13.511 - 13.512 - <para>If you're not familiar with ssh, it's a network protocol 13.513 - that lets you securely communicate with another computer. To 13.514 - use it with Mercurial, you'll be setting up one or more user 13.515 - accounts on a server so that remote users can log in and execute 13.516 - commands.</para> 13.517 - 13.518 - <para>(If you <emphasis>are</emphasis> familiar with ssh, you'll 13.519 - probably find some of the material that follows to be elementary 13.520 - in nature.)</para> 13.521 - 13.522 - <sect2> 13.523 - <title>How to read and write ssh URLs</title> 13.524 - 13.525 - <para>An ssh URL tends to look like this:</para> 13.526 - <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting> 13.527 - <orderedlist> 13.528 - <listitem><para>The <quote><literal>ssh://</literal></quote> 13.529 - part tells Mercurial to use the ssh protocol.</para> 13.530 - </listitem> 13.531 - <listitem><para>The <quote><literal>bos@</literal></quote> 13.532 - component indicates what username to log into the server 13.533 - as. You can leave this out if the remote username is the 13.534 - same as your local username.</para> 13.535 - </listitem> 13.536 - <listitem><para>The 13.537 - <quote><literal>hg.serpentine.com</literal></quote> gives 13.538 - the hostname of the server to log into.</para> 13.539 - </listitem> 13.540 - <listitem><para>The <quote>:22</quote> identifies the port 13.541 - number to connect to the server on. The default port is 13.542 - 22, so you only need to specify a colon and port number if 13.543 - you're <emphasis>not</emphasis> using port 22.</para> 13.544 - </listitem> 13.545 - <listitem><para>The remainder of the URL is the local path to 13.546 - the repository on the server.</para> 13.547 - </listitem></orderedlist> 13.548 - 13.549 - <para>There's plenty of scope for confusion with the path 13.550 - component of ssh URLs, as there is no standard way for tools 13.551 - to interpret it. Some programs behave differently than others 13.552 - when dealing with these paths. This isn't an ideal situation, 13.553 - but it's unlikely to change. Please read the following 13.554 - paragraphs carefully.</para> 13.555 - 13.556 - <para>Mercurial treats the path to a repository on the server as 13.557 - relative to the remote user's home directory. For example, if 13.558 - user <literal>foo</literal> on the server has a home directory 13.559 - of <filename class="directory">/home/foo</filename>, then an 13.560 - ssh URL that contains a path component of <filename 13.561 - class="directory">bar</filename> <emphasis>really</emphasis> 13.562 - refers to the directory <filename 13.563 - class="directory">/home/foo/bar</filename>.</para> 13.564 - 13.565 - <para>If you want to specify a path relative to another user's 13.566 - home directory, you can use a path that starts with a tilde 13.567 - character followed by the user's name (let's call them 13.568 - <literal>otheruser</literal>), like this.</para> 13.569 - <programlisting>ssh://server/~otheruser/hg/repo</programlisting> 13.570 - 13.571 - <para>And if you really want to specify an 13.572 - <emphasis>absolute</emphasis> path on the server, begin the 13.573 - path component with two slashes, as in this example.</para> 13.574 - <programlisting>ssh://server//absolute/path</programlisting> 13.575 - 13.576 - </sect2> 13.577 - <sect2> 13.578 - <title>Finding an ssh client for your system</title> 13.579 - 13.580 - <para>Almost every Unix-like system comes with OpenSSH 13.581 - preinstalled. If you're using such a system, run 13.582 - <literal>which ssh</literal> to find out if the 13.583 - <command>ssh</command> command is installed (it's usually in 13.584 - <filename class="directory">/usr/bin</filename>). In the 13.585 - unlikely event that it isn't present, take a look at your 13.586 - system documentation to figure out how to install it.</para> 13.587 - 13.588 - <para>On Windows, you'll first need to download a suitable ssh 13.589 - client. There are two alternatives.</para> 13.590 - <itemizedlist> 13.591 - <listitem><para>Simon Tatham's excellent PuTTY package 13.592 - <citation>web:putty</citation> provides a complete suite 13.593 - of ssh client commands.</para> 13.594 - </listitem> 13.595 - <listitem><para>If you have a high tolerance for pain, you can 13.596 - use the Cygwin port of OpenSSH.</para> 13.597 - </listitem></itemizedlist> 13.598 - <para>In either case, you'll need to edit your <filename 13.599 - role="special">hg.ini</filename> file to 13.600 - tell Mercurial where to find the actual client command. For 13.601 - example, if you're using PuTTY, you'll need to use the 13.602 - <command>plink</command> command as a command-line ssh 13.603 - client.</para> 13.604 - <programlisting>[ui] 13.605 -ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"</programlisting> 13.606 - 13.607 - <note> 13.608 - <para> The path to <command>plink</command> shouldn't contain 13.609 - any whitespace characters, or Mercurial may not be able to 13.610 - run it correctly (so putting it in <filename 13.611 - class="directory">C:\Program Files</filename> is probably 13.612 - not a good idea).</para> 13.613 - </note> 13.614 - 13.615 - </sect2> 13.616 - <sect2> 13.617 - <title>Generating a key pair</title> 13.618 - 13.619 - <para>To avoid the need to repetitively type a password every 13.620 - time you need to use your ssh client, I recommend generating a 13.621 - key pair. On a Unix-like system, the 13.622 - <command>ssh-keygen</command> command will do the trick. On 13.623 - Windows, if you're using PuTTY, the 13.624 - <command>puttygen</command> command is what you'll 13.625 - need.</para> 13.626 - 13.627 - <para>When you generate a key pair, it's usually 13.628 - <emphasis>highly</emphasis> advisable to protect it with a 13.629 - passphrase. (The only time that you might not want to do this 13.630 - is when you're using the ssh protocol for automated tasks on a 13.631 - secure network.)</para> 13.632 - 13.633 - <para>Simply generating a key pair isn't enough, however. 13.634 - You'll need to add the public key to the set of authorised 13.635 - keys for whatever user you're logging in remotely as. For 13.636 - servers using OpenSSH (the vast majority), this will mean 13.637 - adding the public key to a list in a file called <filename 13.638 - role="special">authorized_keys</filename> in their <filename 13.639 - role="special" class="directory">.ssh</filename> 13.640 - directory.</para> 13.641 - 13.642 - <para>On a Unix-like system, your public key will have a 13.643 - <filename>.pub</filename> extension. If you're using 13.644 - <command>puttygen</command> on Windows, you can save the 13.645 - public key to a file of your choosing, or paste it from the 13.646 - window it's displayed in straight into the <filename 13.647 - role="special">authorized_keys</filename> file.</para> 13.648 - 13.649 - </sect2> 13.650 - <sect2> 13.651 - <title>Using an authentication agent</title> 13.652 - 13.653 - <para>An authentication agent is a daemon that stores 13.654 - passphrases in memory (so it will forget passphrases if you 13.655 - log out and log back in again). An ssh client will notice if 13.656 - it's running, and query it for a passphrase. If there's no 13.657 - authentication agent running, or the agent doesn't store the 13.658 - necessary passphrase, you'll have to type your passphrase 13.659 - every time Mercurial tries to communicate with a server on 13.660 - your behalf (e.g. whenever you pull or push changes).</para> 13.661 - 13.662 - <para>The downside of storing passphrases in an agent is that 13.663 - it's possible for a well-prepared attacker to recover the 13.664 - plain text of your passphrases, in some cases even if your 13.665 - system has been power-cycled. You should make your own 13.666 - judgment as to whether this is an acceptable risk. It 13.667 - certainly saves a lot of repeated typing.</para> 13.668 - 13.669 - <para>On Unix-like systems, the agent is called 13.670 - <command>ssh-agent</command>, and it's often run automatically 13.671 - for you when you log in. You'll need to use the 13.672 - <command>ssh-add</command> command to add passphrases to the 13.673 - agent's store. On Windows, if you're using PuTTY, the 13.674 - <command>pageant</command> command acts as the agent. It adds 13.675 - an icon to your system tray that will let you manage stored 13.676 - passphrases.</para> 13.677 - 13.678 - </sect2> 13.679 - <sect2> 13.680 - <title>Configuring the server side properly</title> 13.681 - 13.682 - <para>Because ssh can be fiddly to set up if you're new to it, 13.683 - there's a variety of things that can go wrong. Add Mercurial 13.684 - on top, and there's plenty more scope for head-scratching. 13.685 - Most of these potential problems occur on the server side, not 13.686 - the client side. The good news is that once you've gotten a 13.687 - configuration working, it will usually continue to work 13.688 - indefinitely.</para> 13.689 - 13.690 - <para>Before you try using Mercurial to talk to an ssh server, 13.691 - it's best to make sure that you can use the normal 13.692 - <command>ssh</command> or <command>putty</command> command to 13.693 - talk to the server first. If you run into problems with using 13.694 - these commands directly, Mercurial surely won't work. Worse, 13.695 - it will obscure the underlying problem. Any time you want to 13.696 - debug ssh-related Mercurial problems, you should drop back to 13.697 - making sure that plain ssh client commands work first, 13.698 - <emphasis>before</emphasis> you worry about whether there's a 13.699 - problem with Mercurial.</para> 13.700 - 13.701 - <para>The first thing to be sure of on the server side is that 13.702 - you can actually log in from another machine at all. If you 13.703 - can't use <command>ssh</command> or <command>putty</command> 13.704 - to log in, the error message you get may give you a few hints 13.705 - as to what's wrong. The most common problems are as 13.706 - follows.</para> 13.707 - <itemizedlist> 13.708 - <listitem><para>If you get a <quote>connection refused</quote> 13.709 - error, either there isn't an SSH daemon running on the 13.710 - server at all, or it's inaccessible due to firewall 13.711 - configuration.</para> 13.712 - </listitem> 13.713 - <listitem><para>If you get a <quote>no route to host</quote> 13.714 - error, you either have an incorrect address for the server 13.715 - or a seriously locked down firewall that won't admit its 13.716 - existence at all.</para> 13.717 - </listitem> 13.718 - <listitem><para>If you get a <quote>permission denied</quote> 13.719 - error, you may have mistyped the username on the server, 13.720 - or you could have mistyped your key's passphrase or the 13.721 - remote user's password.</para> 13.722 - </listitem></itemizedlist> 13.723 - <para>In summary, if you're having trouble talking to the 13.724 - server's ssh daemon, first make sure that one is running at 13.725 - all. On many systems it will be installed, but disabled, by 13.726 - default. Once you're done with this step, you should then 13.727 - check that the server's firewall is configured to allow 13.728 - incoming connections on the port the ssh daemon is listening 13.729 - on (usually 22). Don't worry about more exotic possibilities 13.730 - for misconfiguration until you've checked these two 13.731 - first.</para> 13.732 - 13.733 - <para>If you're using an authentication agent on the client side 13.734 - to store passphrases for your keys, you ought to be able to 13.735 - log into the server without being prompted for a passphrase or 13.736 - a password. If you're prompted for a passphrase, there are a 13.737 - few possible culprits.</para> 13.738 - <itemizedlist> 13.739 - <listitem><para>You might have forgotten to use 13.740 - <command>ssh-add</command> or <command>pageant</command> 13.741 - to store the passphrase.</para> 13.742 - </listitem> 13.743 - <listitem><para>You might have stored the passphrase for the 13.744 - wrong key.</para> 13.745 - </listitem></itemizedlist> 13.746 - <para>If you're being prompted for the remote user's password, 13.747 - there are another few possible problems to check.</para> 13.748 - <itemizedlist> 13.749 - <listitem><para>Either the user's home directory or their 13.750 - <filename role="special" class="directory">.ssh</filename> 13.751 - directory might have excessively liberal permissions. As 13.752 - a result, the ssh daemon will not trust or read their 13.753 - <filename role="special">authorized_keys</filename> file. 13.754 - For example, a group-writable home or <filename 13.755 - role="special" class="directory">.ssh</filename> 13.756 - directory will often cause this symptom.</para> 13.757 - </listitem> 13.758 - <listitem><para>The user's <filename 13.759 - role="special">authorized_keys</filename> file may have 13.760 - a problem. If anyone other than the user owns or can write 13.761 - to that file, the ssh daemon will not trust or read 13.762 - it.</para> 13.763 - </listitem></itemizedlist> 13.764 - 13.765 - <para>In the ideal world, you should be able to run the 13.766 - following command successfully, and it should print exactly 13.767 - one line of output, the current date and time.</para> 13.768 - <programlisting>ssh myserver date</programlisting> 13.769 - 13.770 - <para>If, on your server, you have login scripts that print 13.771 - banners or other junk even when running non-interactive 13.772 - commands like this, you should fix them before you continue, 13.773 - so that they only print output if they're run interactively. 13.774 - Otherwise these banners will at least clutter up Mercurial's 13.775 - output. Worse, they could potentially cause problems with 13.776 - running Mercurial commands remotely. Mercurial makes tries to 13.777 - detect and ignore banners in non-interactive 13.778 - <command>ssh</command> sessions, but it is not foolproof. (If 13.779 - you're editing your login scripts on your server, the usual 13.780 - way to see if a login script is running in an interactive 13.781 - shell is to check the return code from the command 13.782 - <literal>tty -s</literal>.)</para> 13.783 - 13.784 - <para>Once you've verified that plain old ssh is working with 13.785 - your server, the next step is to ensure that Mercurial runs on 13.786 - the server. The following command should run 13.787 - successfully:</para> 13.788 - 13.789 - <programlisting>ssh myserver hg version</programlisting> 13.790 - 13.791 - <para>If you see an error message instead of normal <command 13.792 - role="hg-cmd">hg version</command> output, this is usually 13.793 - because you haven't installed Mercurial to <filename 13.794 - class="directory">/usr/bin</filename>. Don't worry if this 13.795 - is the case; you don't need to do that. But you should check 13.796 - for a few possible problems.</para> 13.797 - <itemizedlist> 13.798 - <listitem><para>Is Mercurial really installed on the server at 13.799 - all? I know this sounds trivial, but it's worth 13.800 - checking!</para> 13.801 - </listitem> 13.802 - <listitem><para>Maybe your shell's search path (usually set 13.803 - via the <envar>PATH</envar> environment variable) is 13.804 - simply misconfigured.</para> 13.805 - </listitem> 13.806 - <listitem><para>Perhaps your <envar>PATH</envar> environment 13.807 - variable is only being set to point to the location of the 13.808 - <command>hg</command> executable if the login session is 13.809 - interactive. This can happen if you're setting the path 13.810 - in the wrong shell login script. See your shell's 13.811 - documentation for details.</para> 13.812 - </listitem> 13.813 - <listitem><para>The <envar>PYTHONPATH</envar> environment 13.814 - variable may need to contain the path to the Mercurial 13.815 - Python modules. It might not be set at all; it could be 13.816 - incorrect; or it may be set only if the login is 13.817 - interactive.</para> 13.818 - </listitem></itemizedlist> 13.819 - 13.820 - <para>If you can run <command role="hg-cmd">hg version</command> 13.821 - over an ssh connection, well done! You've got the server and 13.822 - client sorted out. You should now be able to use Mercurial to 13.823 - access repositories hosted by that username on that server. 13.824 - If you run into problems with Mercurial and ssh at this point, 13.825 - try using the <option role="hg-opt-global">--debug</option> 13.826 - option to get a clearer picture of what's going on.</para> 13.827 - 13.828 - </sect2> 13.829 - <sect2> 13.830 - <title>Using compression with ssh</title> 13.831 - 13.832 - <para>Mercurial does not compress data when it uses the ssh 13.833 - protocol, because the ssh protocol can transparently compress 13.834 - data. However, the default behaviour of ssh clients is 13.835 - <emphasis>not</emphasis> to request compression.</para> 13.836 - 13.837 - <para>Over any network other than a fast LAN (even a wireless 13.838 - network), using compression is likely to significantly speed 13.839 - up Mercurial's network operations. For example, over a WAN, 13.840 - someone measured compression as reducing the amount of time 13.841 - required to clone a particularly large repository from 51 13.842 - minutes to 17 minutes.</para> 13.843 - 13.844 - <para>Both <command>ssh</command> and <command>plink</command> 13.845 - accept a <option role="cmd-opt-ssh">-C</option> option which 13.846 - turns on compression. You can easily edit your <filename 13.847 - role="special">~/.hgrc</filename> to enable compression for 13.848 - all of Mercurial's uses of the ssh protocol.</para> 13.849 - <programlisting>[ui] 13.850 -ssh = ssh -C</programlisting> 13.851 - 13.852 - <para>If you use <command>ssh</command>, you can configure it to 13.853 - always use compression when talking to your server. To do 13.854 - this, edit your <filename 13.855 - role="special">.ssh/config</filename> file (which may not 13.856 - yet exist), as follows.</para> 13.857 - <programlisting>Host hg 13.858 - Compression yes 13.859 - HostName hg.example.com</programlisting> 13.860 - <para>This defines an alias, <literal>hg</literal>. When you 13.861 - use it on the <command>ssh</command> command line or in a 13.862 - Mercurial <literal>ssh</literal>-protocol URL, it will cause 13.863 - <command>ssh</command> to connect to 13.864 - <literal>hg.example.com</literal> and use compression. This 13.865 - gives you both a shorter name to type and compression, each of 13.866 - which is a good thing in its own right.</para> 13.867 - 13.868 - </sect2> 13.869 - </sect1> 13.870 - <sect1 id="sec:collab:cgi"> 13.871 - <title>Serving over HTTP using CGI</title> 13.872 - 13.873 - <para>Depending on how ambitious you are, configuring Mercurial's 13.874 - CGI interface can take anything from a few moments to several 13.875 - hours.</para> 13.876 - 13.877 - <para>We'll begin with the simplest of examples, and work our way 13.878 - towards a more complex configuration. Even for the most basic 13.879 - case, you're almost certainly going to need to read and modify 13.880 - your web server's configuration.</para> 13.881 - 13.882 - <note> 13.883 - <para> Configuring a web server is a complex, fiddly, and 13.884 - highly system-dependent activity. I can't possibly give you 13.885 - instructions that will cover anything like all of the cases 13.886 - you will encounter. Please use your discretion and judgment in 13.887 - following the sections below. Be prepared to make plenty of 13.888 - mistakes, and to spend a lot of time reading your server's 13.889 - error logs.</para> 13.890 - </note> 13.891 - 13.892 - <sect2> 13.893 - <title>Web server configuration checklist</title> 13.894 - 13.895 - <para>Before you continue, do take a few moments to check a few 13.896 - aspects of your system's setup.</para> 13.897 - 13.898 - <orderedlist> 13.899 - <listitem><para>Do you have a web server installed at all? 13.900 - Mac OS X ships with Apache, but many other systems may not 13.901 - have a web server installed.</para> 13.902 - </listitem> 13.903 - <listitem><para>If you have a web server installed, is it 13.904 - actually running? On most systems, even if one is 13.905 - present, it will be disabled by default.</para> 13.906 - </listitem> 13.907 - <listitem><para>Is your server configured to allow you to run 13.908 - CGI programs in the directory where you plan to do so? 13.909 - Most servers default to explicitly disabling the ability 13.910 - to run CGI programs.</para> 13.911 - </listitem></orderedlist> 13.912 - 13.913 - <para>If you don't have a web server installed, and don't have 13.914 - substantial experience configuring Apache, you should consider 13.915 - using the <literal>lighttpd</literal> web server instead of 13.916 - Apache. Apache has a well-deserved reputation for baroque and 13.917 - confusing configuration. While <literal>lighttpd</literal> is 13.918 - less capable in some ways than Apache, most of these 13.919 - capabilities are not relevant to serving Mercurial 13.920 - repositories. And <literal>lighttpd</literal> is undeniably 13.921 - <emphasis>much</emphasis> easier to get started with than 13.922 - Apache.</para> 13.923 - 13.924 - </sect2> 13.925 - <sect2> 13.926 - <title>Basic CGI configuration</title> 13.927 - 13.928 - <para>On Unix-like systems, it's common for users to have a 13.929 - subdirectory named something like <filename 13.930 - class="directory">public_html</filename> in their home 13.931 - directory, from which they can serve up web pages. A file 13.932 - named <filename>foo</filename> in this directory will be 13.933 - accessible at a URL of the form 13.934 - <literal>http://www.example.com/username/foo</literal>.</para> 13.935 - 13.936 - <para>To get started, find the <filename 13.937 - role="special">hgweb.cgi</filename> script that should be 13.938 - present in your Mercurial installation. If you can't quickly 13.939 - find a local copy on your system, simply download one from the 13.940 - master Mercurial repository at <ulink 13.941 - url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>.</para> 13.942 - 13.943 - <para>You'll need to copy this script into your <filename 13.944 - class="directory">public_html</filename> directory, and 13.945 - ensure that it's executable.</para> 13.946 - <programlisting>cp .../hgweb.cgi ~/public_html 13.947 -chmod 755 ~/public_html/hgweb.cgi</programlisting> 13.948 - <para>The <literal>755</literal> argument to 13.949 - <command>chmod</command> is a little more general than just 13.950 - making the script executable: it ensures that the script is 13.951 - executable by anyone, and that <quote>group</quote> and 13.952 - <quote>other</quote> write permissions are 13.953 - <emphasis>not</emphasis> set. If you were to leave those 13.954 - write permissions enabled, Apache's <literal>suexec</literal> 13.955 - subsystem would likely refuse to execute the script. In fact, 13.956 - <literal>suexec</literal> also insists that the 13.957 - <emphasis>directory</emphasis> in which the script resides 13.958 - must not be writable by others.</para> 13.959 - <programlisting>chmod 755 ~/public_html</programlisting> 13.960 - 13.961 - <sect3 id="sec:collab:wtf"> 13.962 - <title>What could <emphasis>possibly</emphasis> go 13.963 - wrong?</title> 13.964 - 13.965 - <para>Once you've copied the CGI script into place, go into a 13.966 - web browser, and try to open the URL <ulink 13.967 - url="http://myhostname/ 13.968 - myuser/hgweb.cgi">http://myhostname/ 13.969 - myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace 13.970 - yourself for instant failure. There's a high probability 13.971 - that trying to visit this URL will fail, and there are many 13.972 - possible reasons for this. In fact, you're likely to 13.973 - stumble over almost every one of the possible errors below, 13.974 - so please read carefully. The following are all of the 13.975 - problems I ran into on a system running Fedora 7, with a 13.976 - fresh installation of Apache, and a user account that I 13.977 - created specially to perform this exercise.</para> 13.978 - 13.979 - <para>Your web server may have per-user directories disabled. 13.980 - If you're using Apache, search your config file for a 13.981 - <literal>UserDir</literal> directive. If there's none 13.982 - present, per-user directories will be disabled. If one 13.983 - exists, but its value is <literal>disabled</literal>, then 13.984 - per-user directories will be disabled. Otherwise, the 13.985 - string after <literal>UserDir</literal> gives the name of 13.986 - the subdirectory that Apache will look in under your home 13.987 - directory, for example <filename 13.988 - class="directory">public_html</filename>.</para> 13.989 - 13.990 - <para>Your file access permissions may be too restrictive. 13.991 - The web server must be able to traverse your home directory 13.992 - and directories under your <filename 13.993 - class="directory">public_html</filename> directory, and 13.994 - read files under the latter too. Here's a quick recipe to 13.995 - help you to make your permissions more appropriate.</para> 13.996 - <programlisting>chmod 755 ~ 13.997 -find ~/public_html -type d -print0 | xargs -0r chmod 755 13.998 -find ~/public_html -type f -print0 | xargs -0r chmod 644</programlisting> 13.999 - 13.1000 - <para>The other possibility with permissions is that you might 13.1001 - get a completely empty window when you try to load the 13.1002 - script. In this case, it's likely that your access 13.1003 - permissions are <emphasis>too permissive</emphasis>. Apache's 13.1004 - <literal>suexec</literal> subsystem won't execute a script 13.1005 - that's group- or world-writable, for example.</para> 13.1006 - 13.1007 - <para>Your web server may be configured to disallow execution 13.1008 - of CGI programs in your per-user web directory. Here's 13.1009 - Apache's default per-user configuration from my Fedora 13.1010 - system.</para> 13.1011 - 13.1012 - &ch06-apache-config.lst; 13.1013 - 13.1014 - <para>If you find a similar-looking 13.1015 - <literal>Directory</literal> group in your Apache 13.1016 - configuration, the directive to look at inside it is 13.1017 - <literal>Options</literal>. Add <literal>ExecCGI</literal> 13.1018 - to the end of this list if it's missing, and restart the web 13.1019 - server.</para> 13.1020 - 13.1021 - <para>If you find that Apache serves you the text of the CGI 13.1022 - script instead of executing it, you may need to either 13.1023 - uncomment (if already present) or add a directive like 13.1024 - this.</para> 13.1025 - <programlisting>AddHandler cgi-script .cgi</programlisting> 13.1026 - 13.1027 - <para>The next possibility is that you might be served with a 13.1028 - colourful Python backtrace claiming that it can't import a 13.1029 - <literal>mercurial</literal>-related module. This is 13.1030 - actually progress! The server is now capable of executing 13.1031 - your CGI script. This error is only likely to occur if 13.1032 - you're running a private installation of Mercurial, instead 13.1033 - of a system-wide version. Remember that the web server runs 13.1034 - the CGI program without any of the environment variables 13.1035 - that you take for granted in an interactive session. If 13.1036 - this error happens to you, edit your copy of <filename 13.1037 - role="special">hgweb.cgi</filename> and follow the 13.1038 - directions inside it to correctly set your 13.1039 - <envar>PYTHONPATH</envar> environment variable.</para> 13.1040 - 13.1041 - <para>Finally, you are <emphasis>certain</emphasis> to by 13.1042 - served with another colourful Python backtrace: this one 13.1043 - will complain that it can't find <filename 13.1044 - class="directory">/path/to/repository</filename>. Edit 13.1045 - your <filename role="special">hgweb.cgi</filename> script 13.1046 - and replace the <filename 13.1047 - class="directory">/path/to/repository</filename> string 13.1048 - with the complete path to the repository you want to serve 13.1049 - up.</para> 13.1050 - 13.1051 - <para>At this point, when you try to reload the page, you 13.1052 - should be presented with a nice HTML view of your 13.1053 - repository's history. Whew!</para> 13.1054 - 13.1055 - </sect3> 13.1056 - <sect3> 13.1057 - <title>Configuring lighttpd</title> 13.1058 - 13.1059 - <para>To be exhaustive in my experiments, I tried configuring 13.1060 - the increasingly popular <literal>lighttpd</literal> web 13.1061 - server to serve the same repository as I described with 13.1062 - Apache above. I had already overcome all of the problems I 13.1063 - outlined with Apache, many of which are not server-specific. 13.1064 - As a result, I was fairly sure that my file and directory 13.1065 - permissions were good, and that my <filename 13.1066 - role="special">hgweb.cgi</filename> script was properly 13.1067 - edited.</para> 13.1068 - 13.1069 - <para>Once I had Apache running, getting 13.1070 - <literal>lighttpd</literal> to serve the repository was a 13.1071 - snap (in other words, even if you're trying to use 13.1072 - <literal>lighttpd</literal>, you should read the Apache 13.1073 - section). I first had to edit the 13.1074 - <literal>mod_access</literal> section of its config file to 13.1075 - enable <literal>mod_cgi</literal> and 13.1076 - <literal>mod_userdir</literal>, both of which were disabled 13.1077 - by default on my system. I then added a few lines to the 13.1078 - end of the config file, to configure these modules.</para> 13.1079 - <programlisting>userdir.path = "public_html" 13.1080 -cgi.assign = (".cgi" => "" )</programlisting> 13.1081 - <para>With this done, <literal>lighttpd</literal> ran 13.1082 - immediately for me. If I had configured 13.1083 - <literal>lighttpd</literal> before Apache, I'd almost 13.1084 - certainly have run into many of the same system-level 13.1085 - configuration problems as I did with Apache. However, I 13.1086 - found <literal>lighttpd</literal> to be noticeably easier to 13.1087 - configure than Apache, even though I've used Apache for over 13.1088 - a decade, and this was my first exposure to 13.1089 - <literal>lighttpd</literal>.</para> 13.1090 - 13.1091 - </sect3> 13.1092 - </sect2> 13.1093 - <sect2> 13.1094 - <title>Sharing multiple repositories with one CGI script</title> 13.1095 - 13.1096 - <para>The <filename role="special">hgweb.cgi</filename> script 13.1097 - only lets you publish a single repository, which is an 13.1098 - annoying restriction. If you want to publish more than one 13.1099 - without wracking yourself with multiple copies of the same 13.1100 - script, each with different names, a better choice is to use 13.1101 - the <filename role="special">hgwebdir.cgi</filename> 13.1102 - script.</para> 13.1103 - 13.1104 - <para>The procedure to configure <filename 13.1105 - role="special">hgwebdir.cgi</filename> is only a little more 13.1106 - involved than for <filename 13.1107 - role="special">hgweb.cgi</filename>. First, you must obtain 13.1108 - a copy of the script. If you don't have one handy, you can 13.1109 - download a copy from the master Mercurial repository at <ulink 13.1110 - url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>.</para> 13.1111 - 13.1112 - <para>You'll need to copy this script into your <filename 13.1113 - class="directory">public_html</filename> directory, and 13.1114 - ensure that it's executable.</para> 13.1115 - <programlisting>cp .../hgwebdir.cgi ~/public_html 13.1116 -chmod 755 ~/public_html ~/public_html/hgwebdir.cgi</programlisting> 13.1117 - <para>With basic configuration out of the way, try to visit 13.1118 - <ulink url="http://myhostname/ 13.1119 - myuser/hgwebdir.cgi">http://myhostname/ 13.1120 - myuser/hgwebdir.cgi</ulink> in your browser. It should 13.1121 - display an empty list of repositories. If you get a blank 13.1122 - window or error message, try walking through the list of 13.1123 - potential problems in section <xref 13.1124 - linkend="sec:collab:wtf"/>.</para> 13.1125 - 13.1126 - <para>The <filename role="special">hgwebdir.cgi</filename> 13.1127 - script relies on an external configuration file. By default, 13.1128 - it searches for a file named <filename 13.1129 - role="special">hgweb.config</filename> in the same directory 13.1130 - as itself. You'll need to create this file, and make it 13.1131 - world-readable. The format of the file is similar to a 13.1132 - Windows <quote>ini</quote> file, as understood by Python's 13.1133 - <literal>ConfigParser</literal> 13.1134 - <citation>web:configparser</citation> module.</para> 13.1135 - 13.1136 - <para>The easiest way to configure <filename 13.1137 - role="special">hgwebdir.cgi</filename> is with a section 13.1138 - named <literal>collections</literal>. This will automatically 13.1139 - publish <emphasis>every</emphasis> repository under the 13.1140 - directories you name. The section should look like 13.1141 - this:</para> 13.1142 - <programlisting>[collections] 13.1143 -/my/root = /my/root</programlisting> 13.1144 - <para>Mercurial interprets this by looking at the directory name 13.1145 - on the <emphasis>right</emphasis> hand side of the 13.1146 - <quote><literal>=</literal></quote> sign; finding repositories 13.1147 - in that directory hierarchy; and using the text on the 13.1148 - <emphasis>left</emphasis> to strip off matching text from the 13.1149 - names it will actually list in the web interface. The 13.1150 - remaining component of a path after this stripping has 13.1151 - occurred is called a <quote>virtual path</quote>.</para> 13.1152 - 13.1153 - <para>Given the example above, if we have a repository whose 13.1154 - local path is <filename 13.1155 - class="directory">/my/root/this/repo</filename>, the CGI 13.1156 - script will strip the leading <filename 13.1157 - class="directory">/my/root</filename> from the name, and 13.1158 - publish the repository with a virtual path of <filename 13.1159 - class="directory">this/repo</filename>. If the base URL for 13.1160 - our CGI script is <ulink url="http://myhostname/ 13.1161 - myuser/hgwebdir.cgi">http://myhostname/ 13.1162 - myuser/hgwebdir.cgi</ulink>, the complete URL for that 13.1163 - repository will be <ulink url="http://myhostname/ 13.1164 - myuser/hgwebdir.cgi/this/repo">http://myhostname/ 13.1165 - myuser/hgwebdir.cgi/this/repo</ulink>.</para> 13.1166 - 13.1167 - <para>If we replace <filename 13.1168 - class="directory">/my/root</filename> on the left hand side 13.1169 - of this example with <filename 13.1170 - class="directory">/my</filename>, then <filename 13.1171 - role="special">hgwebdir.cgi</filename> will only strip off 13.1172 - <filename class="directory">/my</filename> from the repository 13.1173 - name, and will give us a virtual path of <filename 13.1174 - class="directory">root/this/repo</filename> instead of 13.1175 - <filename class="directory">this/repo</filename>.</para> 13.1176 - 13.1177 - <para>The <filename role="special">hgwebdir.cgi</filename> 13.1178 - script will recursively search each directory listed in the 13.1179 - <literal>collections</literal> section of its configuration 13.1180 - file, but it will <literal>not</literal> recurse into the 13.1181 - repositories it finds.</para> 13.1182 - 13.1183 - <para>The <literal>collections</literal> mechanism makes it easy 13.1184 - to publish many repositories in a <quote>fire and 13.1185 - forget</quote> manner. You only need to set up the CGI 13.1186 - script and configuration file one time. Afterwards, you can 13.1187 - publish or unpublish a repository at any time by simply moving 13.1188 - it into, or out of, the directory hierarchy in which you've 13.1189 - configured <filename role="special">hgwebdir.cgi</filename> to 13.1190 - look.</para> 13.1191 - 13.1192 - <sect3> 13.1193 - <title>Explicitly specifying which repositories to 13.1194 - publish</title> 13.1195 - 13.1196 - <para>In addition to the <literal>collections</literal> 13.1197 - mechanism, the <filename 13.1198 - role="special">hgwebdir.cgi</filename> script allows you 13.1199 - to publish a specific list of repositories. To do so, 13.1200 - create a <literal>paths</literal> section, with contents of 13.1201 - the following form.</para> 13.1202 - <programlisting>[paths] 13.1203 -repo1 = /my/path/to/some/repo 13.1204 -repo2 = /some/path/to/another</programlisting> 13.1205 - <para>In this case, the virtual path (the component that will 13.1206 - appear in a URL) is on the left hand side of each 13.1207 - definition, while the path to the repository is on the 13.1208 - right. Notice that there does not need to be any 13.1209 - relationship between the virtual path you choose and the 13.1210 - location of a repository in your filesystem.</para> 13.1211 - 13.1212 - <para>If you wish, you can use both the 13.1213 - <literal>collections</literal> and <literal>paths</literal> 13.1214 - mechanisms simultaneously in a single configuration 13.1215 - file.</para> 13.1216 - 13.1217 - <note> 13.1218 - <para> If multiple repositories have the same virtual path, 13.1219 - <filename role="special">hgwebdir.cgi</filename> will not 13.1220 - report an error. Instead, it will behave 13.1221 - unpredictably.</para> 13.1222 - </note> 13.1223 - 13.1224 - </sect3> 13.1225 - </sect2> 13.1226 - <sect2> 13.1227 - <title>Downloading source archives</title> 13.1228 - 13.1229 - <para>Mercurial's web interface lets users download an archive 13.1230 - of any revision. This archive will contain a snapshot of the 13.1231 - working directory as of that revision, but it will not contain 13.1232 - a copy of the repository data.</para> 13.1233 - 13.1234 - <para>By default, this feature is not enabled. To enable it, 13.1235 - you'll need to add an <envar 13.1236 - role="rc-item-web">allow_archive</envar> item to the 13.1237 - <literal role="rc-web">web</literal> section of your <filename 13.1238 - role="special">~/.hgrc</filename>.</para> 13.1239 - 13.1240 - </sect2> 13.1241 - <sect2> 13.1242 - <title>Web configuration options</title> 13.1243 - 13.1244 - <para>Mercurial's web interfaces (the <command role="hg-cmd">hg 13.1245 - serve</command> command, and the <filename 13.1246 - role="special">hgweb.cgi</filename> and <filename 13.1247 - role="special">hgwebdir.cgi</filename> scripts) have a 13.1248 - number of configuration options that you can set. These 13.1249 - belong in a section named <literal 13.1250 - role="rc-web">web</literal>.</para> 13.1251 - <itemizedlist> 13.1252 - <listitem><para><envar 13.1253 - role="rc-item-web">allow_archive</envar>: Determines 13.1254 - which (if any) archive download mechanisms Mercurial 13.1255 - supports. If you enable this feature, users of the web 13.1256 - interface will be able to download an archive of whatever 13.1257 - revision of a repository they are viewing. To enable the 13.1258 - archive feature, this item must take the form of a 13.1259 - sequence of words drawn from the list below.</para> 13.1260 - <itemizedlist> 13.1261 - <listitem><para><literal>bz2</literal>: A 13.1262 - <command>tar</command> archive, compressed using 13.1263 - <literal>bzip2</literal> compression. This has the 13.1264 - best compression ratio, but uses the most CPU time on 13.1265 - the server.</para> 13.1266 - </listitem> 13.1267 - <listitem><para><literal>gz</literal>: A 13.1268 - <command>tar</command> archive, compressed using 13.1269 - <literal>gzip</literal> compression.</para> 13.1270 - </listitem> 13.1271 - <listitem><para><literal>zip</literal>: A 13.1272 - <command>zip</command> archive, compressed using LZW 13.1273 - compression. This format has the worst compression 13.1274 - ratio, but is widely used in the Windows world.</para> 13.1275 - </listitem> 13.1276 - </itemizedlist> 13.1277 - <para> If you provide an empty list, or don't have an 13.1278 - <envar role="rc-item-web">allow_archive</envar> entry at 13.1279 - all, this feature will be disabled. Here is an example of 13.1280 - how to enable all three supported formats.</para> 13.1281 - <programlisting>[web] 13.1282 -allow_archive = bz2 gz zip</programlisting> 13.1283 - </listitem> 13.1284 - <listitem><para><envar role="rc-item-web">allowpull</envar>: 13.1285 - Boolean. Determines whether the web interface allows 13.1286 - remote users to <command role="hg-cmd">hg pull</command> 13.1287 - and <command role="hg-cmd">hg clone</command> this 13.1288 - repository over HTTP. If set to <literal>no</literal> or 13.1289 - <literal>false</literal>, only the 13.1290 - <quote>human-oriented</quote> portion of the web interface 13.1291 - is available.</para> 13.1292 - </listitem> 13.1293 - <listitem><para><envar role="rc-item-web">contact</envar>: 13.1294 - String. A free-form (but preferably brief) string 13.1295 - identifying the person or group in charge of the 13.1296 - repository. This often contains the name and email 13.1297 - address of a person or mailing list. It often makes sense 13.1298 - to place this entry in a repository's own <filename 13.1299 - role="special">.hg/hgrc</filename> file, but it can make 13.1300 - sense to use in a global <filename 13.1301 - role="special">~/.hgrc</filename> if every repository 13.1302 - has a single maintainer.</para> 13.1303 - </listitem> 13.1304 - <listitem><para><envar role="rc-item-web">maxchanges</envar>: 13.1305 - Integer. The default maximum number of changesets to 13.1306 - display in a single page of output.</para> 13.1307 - </listitem> 13.1308 - <listitem><para><envar role="rc-item-web">maxfiles</envar>: 13.1309 - Integer. The default maximum number of modified files to 13.1310 - display in a single page of output.</para> 13.1311 - </listitem> 13.1312 - <listitem><para><envar role="rc-item-web">stripes</envar>: 13.1313 - Integer. If the web interface displays alternating 13.1314 - <quote>stripes</quote> to make it easier to visually align 13.1315 - rows when you are looking at a table, this number controls 13.1316 - the number of rows in each stripe.</para> 13.1317 - </listitem> 13.1318 - <listitem><para><envar role="rc-item-web">style</envar>: 13.1319 - Controls the template Mercurial uses to display the web 13.1320 - interface. Mercurial ships with two web templates, named 13.1321 - <literal>default</literal> and <literal>gitweb</literal> 13.1322 - (the latter is much more visually attractive). You can 13.1323 - also specify a custom template of your own; see chapter 13.1324 - <xref linkend="chap:template"/> for details. 13.1325 - Here, you can see how to enable the 13.1326 - <literal>gitweb</literal> style.</para> 13.1327 - <programlisting>[web] 13.1328 -style = gitweb</programlisting> 13.1329 - </listitem> 13.1330 - <listitem><para><envar role="rc-item-web">templates</envar>: 13.1331 - Path. The directory in which to search for template 13.1332 - files. By default, Mercurial searches in the directory in 13.1333 - which it was installed.</para> 13.1334 - </listitem></itemizedlist> 13.1335 - <para>If you are using <filename 13.1336 - role="special">hgwebdir.cgi</filename>, you can place a few 13.1337 - configuration items in a <literal role="rc-web">web</literal> 13.1338 - section of the <filename 13.1339 - role="special">hgweb.config</filename> file instead of a 13.1340 - <filename role="special">~/.hgrc</filename> file, for 13.1341 - convenience. These items are <envar 13.1342 - role="rc-item-web">motd</envar> and <envar 13.1343 - role="rc-item-web">style</envar>.</para> 13.1344 - 13.1345 - <sect3> 13.1346 - <title>Options specific to an individual repository</title> 13.1347 - 13.1348 - <para>A few <literal role="rc-web">web</literal> configuration 13.1349 - items ought to be placed in a repository's local <filename 13.1350 - role="special">.hg/hgrc</filename>, rather than a user's 13.1351 - or global <filename role="special">~/.hgrc</filename>.</para> 13.1352 - <itemizedlist> 13.1353 - <listitem><para><envar 13.1354 - role="rc-item-web">description</envar>: String. A 13.1355 - free-form (but preferably brief) string that describes 13.1356 - the contents or purpose of the repository.</para> 13.1357 - </listitem> 13.1358 - <listitem><para><envar role="rc-item-web">name</envar>: 13.1359 - String. The name to use for the repository in the web 13.1360 - interface. This overrides the default name, which is 13.1361 - the last component of the repository's path.</para> 13.1362 - </listitem></itemizedlist> 13.1363 - 13.1364 - </sect3> 13.1365 - <sect3> 13.1366 - <title>Options specific to the <command role="hg-cmd">hg 13.1367 - serve</command> command</title> 13.1368 - 13.1369 - <para>Some of the items in the <literal 13.1370 - role="rc-web">web</literal> section of a <filename 13.1371 - role="special">~/.hgrc</filename> file are only for use 13.1372 - with the <command role="hg-cmd">hg serve</command> 13.1373 - command.</para> 13.1374 - <itemizedlist> 13.1375 - <listitem><para><envar role="rc-item-web">accesslog</envar>: 13.1376 - Path. The name of a file into which to write an access 13.1377 - log. By default, the <command role="hg-cmd">hg 13.1378 - serve</command> command writes this information to 13.1379 - standard output, not to a file. Log entries are written 13.1380 - in the standard <quote>combined</quote> file format used 13.1381 - by almost all web servers.</para> 13.1382 - </listitem> 13.1383 - <listitem><para><envar role="rc-item-web">address</envar>: 13.1384 - String. The local address on which the server should 13.1385 - listen for incoming connections. By default, the server 13.1386 - listens on all addresses.</para> 13.1387 - </listitem> 13.1388 - <listitem><para><envar role="rc-item-web">errorlog</envar>: 13.1389 - Path. The name of a file into which to write an error 13.1390 - log. By default, the <command role="hg-cmd">hg 13.1391 - serve</command> command writes this information to 13.1392 - standard error, not to a file.</para> 13.1393 - </listitem> 13.1394 - <listitem><para><envar role="rc-item-web">ipv6</envar>: 13.1395 - Boolean. Whether to use the IPv6 protocol. By default, 13.1396 - IPv6 is not used.</para> 13.1397 - </listitem> 13.1398 - <listitem><para><envar role="rc-item-web">port</envar>: 13.1399 - Integer. The TCP port number on which the server should 13.1400 - listen. The default port number used is 8000.</para> 13.1401 - </listitem></itemizedlist> 13.1402 - 13.1403 - </sect3> 13.1404 - <sect3> 13.1405 - <title>Choosing the right <filename 13.1406 - role="special">~/.hgrc</filename> file to add <literal 13.1407 - role="rc-web">web</literal> items to</title> 13.1408 - 13.1409 - <para>It is important to remember that a web server like 13.1410 - Apache or <literal>lighttpd</literal> will run under a user 13.1411 - ID that is different to yours. CGI scripts run by your 13.1412 - server, such as <filename 13.1413 - role="special">hgweb.cgi</filename>, will usually also run 13.1414 - under that user ID.</para> 13.1415 - 13.1416 - <para>If you add <literal role="rc-web">web</literal> items to 13.1417 - your own personal <filename role="special">~/.hgrc</filename> file, CGI scripts won't read that 13.1418 - <filename role="special">~/.hgrc</filename> file. Those 13.1419 - settings will thus only affect the behaviour of the <command 13.1420 - role="hg-cmd">hg serve</command> command when you run it. 13.1421 - To cause CGI scripts to see your settings, either create a 13.1422 - <filename role="special">~/.hgrc</filename> file in the 13.1423 - home directory of the user ID that runs your web server, or 13.1424 - add those settings to a system-wide <filename 13.1425 - role="special">~/.hgrc</filename> file.</para> 13.1426 - 13.1427 - 13.1428 - </sect3> 13.1429 - </sect2> 13.1430 - </sect1> 13.1431 -</chapter> 13.1432 - 13.1433 -<!-- 13.1434 -local variables: 13.1435 -sgml-parent-document: ("00book.xml" "book" "chapter") 13.1436 -end: 13.1437 --->
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/en/ch06-filenames.xml Thu Mar 19 20:54:12 2009 -0700 14.3 @@ -0,0 +1,408 @@ 14.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 14.5 + 14.6 +<chapter id="chap:names"> 14.7 + <?dbhtml filename="file-names-and-pattern-matching.html"?> 14.8 + <title>File names and pattern matching</title> 14.9 + 14.10 + <para>Mercurial provides mechanisms that let you work with file 14.11 + names in a consistent and expressive way.</para> 14.12 + 14.13 + <sect1> 14.14 + <title>Simple file naming</title> 14.15 + 14.16 + <para>Mercurial uses a unified piece of machinery <quote>under the 14.17 + hood</quote> to handle file names. Every command behaves 14.18 + uniformly with respect to file names. The way in which commands 14.19 + work with file names is as follows.</para> 14.20 + 14.21 + <para>If you explicitly name real files on the command line, 14.22 + Mercurial works with exactly those files, as you would expect. 14.23 + &interaction.filenames.files;</para> 14.24 + 14.25 + <para>When you provide a directory name, Mercurial will interpret 14.26 + this as <quote>operate on every file in this directory and its 14.27 + subdirectories</quote>. Mercurial traverses the files and 14.28 + subdirectories in a directory in alphabetical order. When it 14.29 + encounters a subdirectory, it will traverse that subdirectory 14.30 + before continuing with the current directory.</para> 14.31 + 14.32 + &interaction.filenames.dirs; 14.33 + 14.34 + </sect1> 14.35 + <sect1> 14.36 + <title>Running commands without any file names</title> 14.37 + 14.38 + <para>Mercurial's commands that work with file names have useful 14.39 + default behaviours when you invoke them without providing any 14.40 + file names or patterns. What kind of behaviour you should 14.41 + expect depends on what the command does. Here are a few rules 14.42 + of thumb you can use to predict what a command is likely to do 14.43 + if you don't give it any names to work with.</para> 14.44 + <itemizedlist> 14.45 + <listitem><para>Most commands will operate on the entire working 14.46 + directory. This is what the <command role="hg-cmd">hg 14.47 + add</command> command does, for example.</para> 14.48 + </listitem> 14.49 + <listitem><para>If the command has effects that are difficult or 14.50 + impossible to reverse, it will force you to explicitly 14.51 + provide at least one name or pattern (see below). This 14.52 + protects you from accidentally deleting files by running 14.53 + <command role="hg-cmd">hg remove</command> with no 14.54 + arguments, for example.</para> 14.55 + </listitem></itemizedlist> 14.56 + 14.57 + <para>It's easy to work around these default behaviours if they 14.58 + don't suit you. If a command normally operates on the whole 14.59 + working directory, you can invoke it on just the current 14.60 + directory and its subdirectories by giving it the name 14.61 + <quote><filename class="directory">.</filename></quote>.</para> 14.62 + 14.63 + &interaction.filenames.wdir-subdir; 14.64 + 14.65 + <para>Along the same lines, some commands normally print file 14.66 + names relative to the root of the repository, even if you're 14.67 + invoking them from a subdirectory. Such a command will print 14.68 + file names relative to your subdirectory if you give it explicit 14.69 + names. Here, we're going to run <command role="hg-cmd">hg 14.70 + status</command> from a subdirectory, and get it to operate on 14.71 + the entire working directory while printing file names relative 14.72 + to our subdirectory, by passing it the output of the <command 14.73 + role="hg-cmd">hg root</command> command.</para> 14.74 + 14.75 + &interaction.filenames.wdir-relname; 14.76 + 14.77 + </sect1> 14.78 + <sect1> 14.79 + <title>Telling you what's going on</title> 14.80 + 14.81 + <para>The <command role="hg-cmd">hg add</command> example in the 14.82 + preceding section illustrates something else that's helpful 14.83 + about Mercurial commands. If a command operates on a file that 14.84 + you didn't name explicitly on the command line, it will usually 14.85 + print the name of the file, so that you will not be surprised 14.86 + what's going on.</para> 14.87 + 14.88 + <para>The principle here is of <emphasis>least 14.89 + surprise</emphasis>. If you've exactly named a file on the 14.90 + command line, there's no point in repeating it back at you. If 14.91 + Mercurial is acting on a file <emphasis>implicitly</emphasis>, 14.92 + because you provided no names, or a directory, or a pattern (see 14.93 + below), it's safest to tell you what it's doing.</para> 14.94 + 14.95 + <para>For commands that behave this way, you can silence them 14.96 + using the <option role="hg-opt-global">-q</option> option. You 14.97 + can also get them to print the name of every file, even those 14.98 + you've named explicitly, using the <option 14.99 + role="hg-opt-global">-v</option> option.</para> 14.100 + 14.101 + </sect1> 14.102 + <sect1> 14.103 + <title>Using patterns to identify files</title> 14.104 + 14.105 + <para>In addition to working with file and directory names, 14.106 + Mercurial lets you use <emphasis>patterns</emphasis> to identify 14.107 + files. Mercurial's pattern handling is expressive.</para> 14.108 + 14.109 + <para>On Unix-like systems (Linux, MacOS, etc.), the job of 14.110 + matching file names to patterns normally falls to the shell. On 14.111 + these systems, you must explicitly tell Mercurial that a name is 14.112 + a pattern. On Windows, the shell does not expand patterns, so 14.113 + Mercurial will automatically identify names that are patterns, 14.114 + and expand them for you.</para> 14.115 + 14.116 + <para>To provide a pattern in place of a regular name on the 14.117 + command line, the mechanism is simple:</para> 14.118 + <programlisting>syntax:patternbody</programlisting> 14.119 + <para>That is, a pattern is identified by a short text string that 14.120 + says what kind of pattern this is, followed by a colon, followed 14.121 + by the actual pattern.</para> 14.122 + 14.123 + <para>Mercurial supports two kinds of pattern syntax. The most 14.124 + frequently used is called <literal>glob</literal>; this is the 14.125 + same kind of pattern matching used by the Unix shell, and should 14.126 + be familiar to Windows command prompt users, too.</para> 14.127 + 14.128 + <para>When Mercurial does automatic pattern matching on Windows, 14.129 + it uses <literal>glob</literal> syntax. You can thus omit the 14.130 + <quote><literal>glob:</literal></quote> prefix on Windows, but 14.131 + it's safe to use it, too.</para> 14.132 + 14.133 + <para>The <literal>re</literal> syntax is more powerful; it lets 14.134 + you specify patterns using regular expressions, also known as 14.135 + regexps.</para> 14.136 + 14.137 + <para>By the way, in the examples that follow, notice that I'm 14.138 + careful to wrap all of my patterns in quote characters, so that 14.139 + they won't get expanded by the shell before Mercurial sees 14.140 + them.</para> 14.141 + 14.142 + <sect2> 14.143 + <title>Shell-style <literal>glob</literal> patterns</title> 14.144 + 14.145 + <para>This is an overview of the kinds of patterns you can use 14.146 + when you're matching on glob patterns.</para> 14.147 + 14.148 + <para>The <quote><literal>*</literal></quote> character matches 14.149 + any string, within a single directory.</para> 14.150 + 14.151 + &interaction.filenames.glob.star; 14.152 + 14.153 + <para>The <quote><literal>**</literal></quote> pattern matches 14.154 + any string, and crosses directory boundaries. It's not a 14.155 + standard Unix glob token, but it's accepted by several popular 14.156 + Unix shells, and is very useful.</para> 14.157 + 14.158 + &interaction.filenames.glob.starstar; 14.159 + 14.160 + <para>The <quote><literal>?</literal></quote> pattern matches 14.161 + any single character.</para> 14.162 + 14.163 + &interaction.filenames.glob.question; 14.164 + 14.165 + <para>The <quote><literal>[</literal></quote> character begins a 14.166 + <emphasis>character class</emphasis>. This matches any single 14.167 + character within the class. The class ends with a 14.168 + <quote><literal>]</literal></quote> character. A class may 14.169 + contain multiple <emphasis>range</emphasis>s of the form 14.170 + <quote><literal>a-f</literal></quote>, which is shorthand for 14.171 + <quote><literal>abcdef</literal></quote>.</para> 14.172 + 14.173 + &interaction.filenames.glob.range; 14.174 + 14.175 + <para>If the first character after the 14.176 + <quote><literal>[</literal></quote> in a character class is a 14.177 + <quote><literal>!</literal></quote>, it 14.178 + <emphasis>negates</emphasis> the class, making it match any 14.179 + single character not in the class.</para> 14.180 + 14.181 + <para>A <quote><literal>{</literal></quote> begins a group of 14.182 + subpatterns, where the whole group matches if any subpattern 14.183 + in the group matches. The <quote><literal>,</literal></quote> 14.184 + character separates subpatterns, and 14.185 + <quote><literal>}</literal></quote> ends the group.</para> 14.186 + 14.187 + &interaction.filenames.glob.group; 14.188 + 14.189 + <sect3> 14.190 + <title>Watch out!</title> 14.191 + 14.192 + <para>Don't forget that if you want to match a pattern in any 14.193 + directory, you should not be using the 14.194 + <quote><literal>*</literal></quote> match-any token, as this 14.195 + will only match within one directory. Instead, use the 14.196 + <quote><literal>**</literal></quote> token. This small 14.197 + example illustrates the difference between the two.</para> 14.198 + 14.199 + &interaction.filenames.glob.star-starstar; 14.200 + 14.201 + </sect3> 14.202 + </sect2> 14.203 + <sect2> 14.204 + <title>Regular expression matching with <literal>re</literal> 14.205 + patterns</title> 14.206 + 14.207 + <para>Mercurial accepts the same regular expression syntax as 14.208 + the Python programming language (it uses Python's regexp 14.209 + engine internally). This is based on the Perl language's 14.210 + regexp syntax, which is the most popular dialect in use (it's 14.211 + also used in Java, for example).</para> 14.212 + 14.213 + <para>I won't discuss Mercurial's regexp dialect in any detail 14.214 + here, as regexps are not often used. Perl-style regexps are 14.215 + in any case already exhaustively documented on a multitude of 14.216 + web sites, and in many books. Instead, I will focus here on a 14.217 + few things you should know if you find yourself needing to use 14.218 + regexps with Mercurial.</para> 14.219 + 14.220 + <para>A regexp is matched against an entire file name, relative 14.221 + to the root of the repository. In other words, even if you're 14.222 + already in subbdirectory <filename 14.223 + class="directory">foo</filename>, if you want to match files 14.224 + under this directory, your pattern must start with 14.225 + <quote><literal>foo/</literal></quote>.</para> 14.226 + 14.227 + <para>One thing to note, if you're familiar with Perl-style 14.228 + regexps, is that Mercurial's are <emphasis>rooted</emphasis>. 14.229 + That is, a regexp starts matching against the beginning of a 14.230 + string; it doesn't look for a match anywhere within the 14.231 + string. To match anywhere in a string, start your pattern 14.232 + with <quote><literal>.*</literal></quote>.</para> 14.233 + 14.234 + </sect2> 14.235 + </sect1> 14.236 + <sect1> 14.237 + <title>Filtering files</title> 14.238 + 14.239 + <para>Not only does Mercurial give you a variety of ways to 14.240 + specify files; it lets you further winnow those files using 14.241 + <emphasis>filters</emphasis>. Commands that work with file 14.242 + names accept two filtering options.</para> 14.243 + <itemizedlist> 14.244 + <listitem><para><option role="hg-opt-global">-I</option>, or 14.245 + <option role="hg-opt-global">--include</option>, lets you 14.246 + specify a pattern that file names must match in order to be 14.247 + processed.</para> 14.248 + </listitem> 14.249 + <listitem><para><option role="hg-opt-global">-X</option>, or 14.250 + <option role="hg-opt-global">--exclude</option>, gives you a 14.251 + way to <emphasis>avoid</emphasis> processing files, if they 14.252 + match this pattern.</para> 14.253 + </listitem></itemizedlist> 14.254 + <para>You can provide multiple <option 14.255 + role="hg-opt-global">-I</option> and <option 14.256 + role="hg-opt-global">-X</option> options on the command line, 14.257 + and intermix them as you please. Mercurial interprets the 14.258 + patterns you provide using glob syntax by default (but you can 14.259 + use regexps if you need to).</para> 14.260 + 14.261 + <para>You can read a <option role="hg-opt-global">-I</option> 14.262 + filter as <quote>process only the files that match this 14.263 + filter</quote>.</para> 14.264 + 14.265 + &interaction.filenames.filter.include; 14.266 + 14.267 + <para>The <option role="hg-opt-global">-X</option> filter is best 14.268 + read as <quote>process only the files that don't match this 14.269 + pattern</quote>.</para> 14.270 + 14.271 + &interaction.filenames.filter.exclude; 14.272 + 14.273 + </sect1> 14.274 + <sect1> 14.275 + <title>Ignoring unwanted files and directories</title> 14.276 + 14.277 + <para>XXX.</para> 14.278 + 14.279 + </sect1> 14.280 + <sect1 id="sec:names:case"> 14.281 + <title>Case sensitivity</title> 14.282 + 14.283 + <para>If you're working in a mixed development environment that 14.284 + contains both Linux (or other Unix) systems and Macs or Windows 14.285 + systems, you should keep in the back of your mind the knowledge 14.286 + that they treat the case (<quote>N</quote> versus 14.287 + <quote>n</quote>) of file names in incompatible ways. This is 14.288 + not very likely to affect you, and it's easy to deal with if it 14.289 + does, but it could surprise you if you don't know about 14.290 + it.</para> 14.291 + 14.292 + <para>Operating systems and filesystems differ in the way they 14.293 + handle the <emphasis>case</emphasis> of characters in file and 14.294 + directory names. There are three common ways to handle case in 14.295 + names.</para> 14.296 + <itemizedlist> 14.297 + <listitem><para>Completely case insensitive. Uppercase and 14.298 + lowercase versions of a letter are treated as identical, 14.299 + both when creating a file and during subsequent accesses. 14.300 + This is common on older DOS-based systems.</para> 14.301 + </listitem> 14.302 + <listitem><para>Case preserving, but insensitive. When a file 14.303 + or directory is created, the case of its name is stored, and 14.304 + can be retrieved and displayed by the operating system. 14.305 + When an existing file is being looked up, its case is 14.306 + ignored. This is the standard arrangement on Windows and 14.307 + MacOS. The names <filename>foo</filename> and 14.308 + <filename>FoO</filename> identify the same file. This 14.309 + treatment of uppercase and lowercase letters as 14.310 + interchangeable is also referred to as <emphasis>case 14.311 + folding</emphasis>.</para> 14.312 + </listitem> 14.313 + <listitem><para>Case sensitive. The case of a name is 14.314 + significant at all times. The names <filename>foo</filename> 14.315 + and {FoO} identify different files. This is the way Linux 14.316 + and Unix systems normally work.</para> 14.317 + </listitem></itemizedlist> 14.318 + 14.319 + <para>On Unix-like systems, it is possible to have any or all of 14.320 + the above ways of handling case in action at once. For example, 14.321 + if you use a USB thumb drive formatted with a FAT32 filesystem 14.322 + on a Linux system, Linux will handle names on that filesystem in 14.323 + a case preserving, but insensitive, way.</para> 14.324 + 14.325 + <sect2> 14.326 + <title>Safe, portable repository storage</title> 14.327 + 14.328 + <para>Mercurial's repository storage mechanism is <emphasis>case 14.329 + safe</emphasis>. It translates file names so that they can 14.330 + be safely stored on both case sensitive and case insensitive 14.331 + filesystems. This means that you can use normal file copying 14.332 + tools to transfer a Mercurial repository onto, for example, a 14.333 + USB thumb drive, and safely move that drive and repository 14.334 + back and forth between a Mac, a PC running Windows, and a 14.335 + Linux box.</para> 14.336 + 14.337 + </sect2> 14.338 + <sect2> 14.339 + <title>Detecting case conflicts</title> 14.340 + 14.341 + <para>When operating in the working directory, Mercurial honours 14.342 + the naming policy of the filesystem where the working 14.343 + directory is located. If the filesystem is case preserving, 14.344 + but insensitive, Mercurial will treat names that differ only 14.345 + in case as the same.</para> 14.346 + 14.347 + <para>An important aspect of this approach is that it is 14.348 + possible to commit a changeset on a case sensitive (typically 14.349 + Linux or Unix) filesystem that will cause trouble for users on 14.350 + case insensitive (usually Windows and MacOS) users. If a 14.351 + Linux user commits changes to two files, one named 14.352 + <filename>myfile.c</filename> and the other named 14.353 + <filename>MyFile.C</filename>, they will be stored correctly 14.354 + in the repository. And in the working directories of other 14.355 + Linux users, they will be correctly represented as separate 14.356 + files.</para> 14.357 + 14.358 + <para>If a Windows or Mac user pulls this change, they will not 14.359 + initially have a problem, because Mercurial's repository 14.360 + storage mechanism is case safe. However, once they try to 14.361 + <command role="hg-cmd">hg update</command> the working 14.362 + directory to that changeset, or <command role="hg-cmd">hg 14.363 + merge</command> with that changeset, Mercurial will spot the 14.364 + conflict between the two file names that the filesystem would 14.365 + treat as the same, and forbid the update or merge from 14.366 + occurring.</para> 14.367 + 14.368 + </sect2> 14.369 + <sect2> 14.370 + <title>Fixing a case conflict</title> 14.371 + 14.372 + <para>If you are using Windows or a Mac in a mixed environment 14.373 + where some of your collaborators are using Linux or Unix, and 14.374 + Mercurial reports a case folding conflict when you try to 14.375 + <command role="hg-cmd">hg update</command> or <command 14.376 + role="hg-cmd">hg merge</command>, the procedure to fix the 14.377 + problem is simple.</para> 14.378 + 14.379 + <para>Just find a nearby Linux or Unix box, clone the problem 14.380 + repository onto it, and use Mercurial's <command 14.381 + role="hg-cmd">hg rename</command> command to change the 14.382 + names of any offending files or directories so that they will 14.383 + no longer cause case folding conflicts. Commit this change, 14.384 + <command role="hg-cmd">hg pull</command> or <command 14.385 + role="hg-cmd">hg push</command> it across to your Windows or 14.386 + MacOS system, and <command role="hg-cmd">hg update</command> 14.387 + to the revision with the non-conflicting names.</para> 14.388 + 14.389 + <para>The changeset with case-conflicting names will remain in 14.390 + your project's history, and you still won't be able to 14.391 + <command role="hg-cmd">hg update</command> your working 14.392 + directory to that changeset on a Windows or MacOS system, but 14.393 + you can continue development unimpeded.</para> 14.394 + 14.395 + <note> 14.396 + <para> Prior to version 0.9.3, Mercurial did not use a case 14.397 + safe repository storage mechanism, and did not detect case 14.398 + folding conflicts. If you are using an older version of 14.399 + Mercurial on Windows or MacOS, I strongly recommend that you 14.400 + upgrade.</para> 14.401 + </note> 14.402 + 14.403 + </sect2> 14.404 + </sect1> 14.405 +</chapter> 14.406 + 14.407 +<!-- 14.408 +local variables: 14.409 +sgml-parent-document: ("00book.xml" "book" "chapter") 14.410 +end: 14.411 +-->
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/en/ch07-branch.xml Thu Mar 19 20:54:12 2009 -0700 15.3 @@ -0,0 +1,533 @@ 15.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 15.5 + 15.6 +<chapter id="chap:branch"> 15.7 + <?dbhtml filename="managing-releases-and-branchy-development.html"?> 15.8 + <title>Managing releases and branchy development</title> 15.9 + 15.10 + <para>Mercurial provides several mechanisms for you to manage a 15.11 + project that is making progress on multiple fronts at once. To 15.12 + understand these mechanisms, let's first take a brief look at a 15.13 + fairly normal software project structure.</para> 15.14 + 15.15 + <para>Many software projects issue periodic <quote>major</quote> 15.16 + releases that contain substantial new features. In parallel, they 15.17 + may issue <quote>minor</quote> releases. These are usually 15.18 + identical to the major releases off which they're based, but with 15.19 + a few bugs fixed.</para> 15.20 + 15.21 + <para>In this chapter, we'll start by talking about how to keep 15.22 + records of project milestones such as releases. We'll then 15.23 + continue on to talk about the flow of work between different 15.24 + phases of a project, and how Mercurial can help you to isolate and 15.25 + manage this work.</para> 15.26 + 15.27 + <sect1> 15.28 + <title>Giving a persistent name to a revision</title> 15.29 + 15.30 + <para>Once you decide that you'd like to call a particular 15.31 + revision a <quote>release</quote>, it's a good idea to record 15.32 + the identity of that revision. This will let you reproduce that 15.33 + release at a later date, for whatever purpose you might need at 15.34 + the time (reproducing a bug, porting to a new platform, etc). 15.35 + &interaction.tag.init;</para> 15.36 + 15.37 + <para>Mercurial lets you give a permanent name to any revision 15.38 + using the <command role="hg-cmd">hg tag</command> command. Not 15.39 + surprisingly, these names are called <quote>tags</quote>.</para> 15.40 + 15.41 + &interaction.tag.tag; 15.42 + 15.43 + <para>A tag is nothing more than a <quote>symbolic name</quote> 15.44 + for a revision. Tags exist purely for your convenience, so that 15.45 + you have a handy permanent way to refer to a revision; Mercurial 15.46 + doesn't interpret the tag names you use in any way. Neither 15.47 + does Mercurial place any restrictions on the name of a tag, 15.48 + beyond a few that are necessary to ensure that a tag can be 15.49 + parsed unambiguously. A tag name cannot contain any of the 15.50 + following characters:</para> 15.51 + <itemizedlist> 15.52 + <listitem><para>Colon (ASCII 58, 15.53 + <quote><literal>:</literal></quote>)</para> 15.54 + </listitem> 15.55 + <listitem><para>Carriage return (ASCII 13, 15.56 + <quote><literal>\r</literal></quote>)</para> 15.57 + </listitem> 15.58 + <listitem><para>Newline (ASCII 10, 15.59 + <quote><literal>\n</literal></quote>)</para> 15.60 + </listitem></itemizedlist> 15.61 + 15.62 + <para>You can use the <command role="hg-cmd">hg tags</command> 15.63 + command to display the tags present in your repository. In the 15.64 + output, each tagged revision is identified first by its name, 15.65 + then by revision number, and finally by the unique hash of the 15.66 + revision.</para> 15.67 + 15.68 + &interaction.tag.tags; 15.69 + 15.70 + <para>Notice that <literal>tip</literal> is listed in the output 15.71 + of <command role="hg-cmd">hg tags</command>. The 15.72 + <literal>tip</literal> tag is a special <quote>floating</quote> 15.73 + tag, which always identifies the newest revision in the 15.74 + repository.</para> 15.75 + 15.76 + <para>In the output of the <command role="hg-cmd">hg 15.77 + tags</command> command, tags are listed in reverse order, by 15.78 + revision number. This usually means that recent tags are listed 15.79 + before older tags. It also means that <literal>tip</literal> is 15.80 + always going to be the first tag listed in the output of 15.81 + <command role="hg-cmd">hg tags</command>.</para> 15.82 + 15.83 + <para>When you run <command role="hg-cmd">hg log</command>, if it 15.84 + displays a revision that has tags associated with it, it will 15.85 + print those tags.</para> 15.86 + 15.87 + &interaction.tag.log; 15.88 + 15.89 + <para>Any time you need to provide a revision ID to a Mercurial 15.90 + command, the command will accept a tag name in its place. 15.91 + Internally, Mercurial will translate your tag name into the 15.92 + corresponding revision ID, then use that.</para> 15.93 + 15.94 + &interaction.tag.log.v1.0; 15.95 + 15.96 + <para>There's no limit on the number of tags you can have in a 15.97 + repository, or on the number of tags that a single revision can 15.98 + have. As a practical matter, it's not a great idea to have 15.99 + <quote>too many</quote> (a number which will vary from project 15.100 + to project), simply because tags are supposed to help you to 15.101 + find revisions. If you have lots of tags, the ease of using 15.102 + them to identify revisions diminishes rapidly.</para> 15.103 + 15.104 + <para>For example, if your project has milestones as frequent as 15.105 + every few days, it's perfectly reasonable to tag each one of 15.106 + those. But if you have a continuous build system that makes 15.107 + sure every revision can be built cleanly, you'd be introducing a 15.108 + lot of noise if you were to tag every clean build. Instead, you 15.109 + could tag failed builds (on the assumption that they're rare!), 15.110 + or simply not use tags to track buildability.</para> 15.111 + 15.112 + <para>If you want to remove a tag that you no longer want, use 15.113 + <command role="hg-cmd">hg tag --remove</command>.</para> 15.114 + 15.115 + &interaction.tag.remove; 15.116 + 15.117 + <para>You can also modify a tag at any time, so that it identifies 15.118 + a different revision, by simply issuing a new <command 15.119 + role="hg-cmd">hg tag</command> command. You'll have to use the 15.120 + <option role="hg-opt-tag">-f</option> option to tell Mercurial 15.121 + that you <emphasis>really</emphasis> want to update the 15.122 + tag.</para> 15.123 + 15.124 + &interaction.tag.replace; 15.125 + 15.126 + <para>There will still be a permanent record of the previous 15.127 + identity of the tag, but Mercurial will no longer use it. 15.128 + There's thus no penalty to tagging the wrong revision; all you 15.129 + have to do is turn around and tag the correct revision once you 15.130 + discover your error.</para> 15.131 + 15.132 + <para>Mercurial stores tags in a normal revision-controlled file 15.133 + in your repository. If you've created any tags, you'll find 15.134 + them in a file named <filename 15.135 + role="special">.hgtags</filename>. When you run the <command 15.136 + role="hg-cmd">hg tag</command> command, Mercurial modifies 15.137 + this file, then automatically commits the change to it. This 15.138 + means that every time you run <command role="hg-cmd">hg 15.139 + tag</command>, you'll see a corresponding changeset in the 15.140 + output of <command role="hg-cmd">hg log</command>.</para> 15.141 + 15.142 + &interaction.tag.tip; 15.143 + 15.144 + <sect2> 15.145 + <title>Handling tag conflicts during a merge</title> 15.146 + 15.147 + <para>You won't often need to care about the <filename 15.148 + role="special">.hgtags</filename> file, but it sometimes 15.149 + makes its presence known during a merge. The format of the 15.150 + file is simple: it consists of a series of lines. Each line 15.151 + starts with a changeset hash, followed by a space, followed by 15.152 + the name of a tag.</para> 15.153 + 15.154 + <para>If you're resolving a conflict in the <filename 15.155 + role="special">.hgtags</filename> file during a merge, 15.156 + there's one twist to modifying the <filename 15.157 + role="special">.hgtags</filename> file: when Mercurial is 15.158 + parsing the tags in a repository, it 15.159 + <emphasis>never</emphasis> reads the working copy of the 15.160 + <filename role="special">.hgtags</filename> file. Instead, it 15.161 + reads the <emphasis>most recently committed</emphasis> 15.162 + revision of the file.</para> 15.163 + 15.164 + <para>An unfortunate consequence of this design is that you 15.165 + can't actually verify that your merged <filename 15.166 + role="special">.hgtags</filename> file is correct until 15.167 + <emphasis>after</emphasis> you've committed a change. So if 15.168 + you find yourself resolving a conflict on <filename 15.169 + role="special">.hgtags</filename> during a merge, be sure to 15.170 + run <command role="hg-cmd">hg tags</command> after you commit. 15.171 + If it finds an error in the <filename 15.172 + role="special">.hgtags</filename> file, it will report the 15.173 + location of the error, which you can then fix and commit. You 15.174 + should then run <command role="hg-cmd">hg tags</command> 15.175 + again, just to be sure that your fix is correct.</para> 15.176 + 15.177 + </sect2> 15.178 + <sect2> 15.179 + <title>Tags and cloning</title> 15.180 + 15.181 + <para>You may have noticed that the <command role="hg-cmd">hg 15.182 + clone</command> command has a <option 15.183 + role="hg-opt-clone">-r</option> option that lets you clone 15.184 + an exact copy of the repository as of a particular changeset. 15.185 + The new clone will not contain any project history that comes 15.186 + after the revision you specified. This has an interaction 15.187 + with tags that can surprise the unwary.</para> 15.188 + 15.189 + <para>Recall that a tag is stored as a revision to the <filename 15.190 + role="special">.hgtags</filename> file, so that when you 15.191 + create a tag, the changeset in which it's recorded necessarily 15.192 + refers to an older changeset. When you run <command 15.193 + role="hg-cmd">hg clone -r foo</command> to clone a 15.194 + repository as of tag <literal>foo</literal>, the new clone 15.195 + <emphasis>will not contain the history that created the 15.196 + tag</emphasis> that you used to clone the repository. The 15.197 + result is that you'll get exactly the right subset of the 15.198 + project's history in the new repository, but 15.199 + <emphasis>not</emphasis> the tag you might have 15.200 + expected.</para> 15.201 + 15.202 + </sect2> 15.203 + <sect2> 15.204 + <title>When permanent tags are too much</title> 15.205 + 15.206 + <para>Since Mercurial's tags are revision controlled and carried 15.207 + around with a project's history, everyone you work with will 15.208 + see the tags you create. But giving names to revisions has 15.209 + uses beyond simply noting that revision 15.210 + <literal>4237e45506ee</literal> is really 15.211 + <literal>v2.0.2</literal>. If you're trying to track down a 15.212 + subtle bug, you might want a tag to remind you of something 15.213 + like <quote>Anne saw the symptoms with this 15.214 + revision</quote>.</para> 15.215 + 15.216 + <para>For cases like this, what you might want to use are 15.217 + <emphasis>local</emphasis> tags. You can create a local tag 15.218 + with the <option role="hg-opt-tag">-l</option> option to the 15.219 + <command role="hg-cmd">hg tag</command> command. This will 15.220 + store the tag in a file called <filename 15.221 + role="special">.hg/localtags</filename>. Unlike <filename 15.222 + role="special">.hgtags</filename>, <filename 15.223 + role="special">.hg/localtags</filename> is not revision 15.224 + controlled. Any tags you create using <option 15.225 + role="hg-opt-tag">-l</option> remain strictly local to the 15.226 + repository you're currently working in.</para> 15.227 + 15.228 + </sect2> 15.229 + </sect1> 15.230 + <sect1> 15.231 + <title>The flow of changes&emdash;big picture vs. little</title> 15.232 + 15.233 + <para>To return to the outline I sketched at the beginning of a 15.234 + chapter, let's think about a project that has multiple 15.235 + concurrent pieces of work under development at once.</para> 15.236 + 15.237 + <para>There might be a push for a new <quote>main</quote> release; 15.238 + a new minor bugfix release to the last main release; and an 15.239 + unexpected <quote>hot fix</quote> to an old release that is now 15.240 + in maintenance mode.</para> 15.241 + 15.242 + <para>The usual way people refer to these different concurrent 15.243 + directions of development is as <quote>branches</quote>. 15.244 + However, we've already seen numerous times that Mercurial treats 15.245 + <emphasis>all of history</emphasis> as a series of branches and 15.246 + merges. Really, what we have here is two ideas that are 15.247 + peripherally related, but which happen to share a name.</para> 15.248 + <itemizedlist> 15.249 + <listitem><para><quote>Big picture</quote> branches represent 15.250 + the sweep of a project's evolution; people give them names, 15.251 + and talk about them in conversation.</para> 15.252 + </listitem> 15.253 + <listitem><para><quote>Little picture</quote> branches are 15.254 + artefacts of the day-to-day activity of developing and 15.255 + merging changes. They expose the narrative of how the code 15.256 + was developed.</para> 15.257 + </listitem></itemizedlist> 15.258 + 15.259 + </sect1> 15.260 + <sect1> 15.261 + <title>Managing big-picture branches in repositories</title> 15.262 + 15.263 + <para>The easiest way to isolate a <quote>big picture</quote> 15.264 + branch in Mercurial is in a dedicated repository. If you have 15.265 + an existing shared repository&emdash;let's call it 15.266 + <literal>myproject</literal>&emdash;that reaches a 15.267 + <quote>1.0</quote> milestone, you can start to prepare for 15.268 + future maintenance releases on top of version 1.0 by tagging the 15.269 + revision from which you prepared the 1.0 release.</para> 15.270 + 15.271 + &interaction.branch-repo.tag; 15.272 + 15.273 + <para>You can then clone a new shared 15.274 + <literal>myproject-1.0.1</literal> repository as of that 15.275 + tag.</para> 15.276 + 15.277 + &interaction.branch-repo.clone; 15.278 + 15.279 + <para>Afterwards, if someone needs to work on a bug fix that ought 15.280 + to go into an upcoming 1.0.1 minor release, they clone the 15.281 + <literal>myproject-1.0.1</literal> repository, make their 15.282 + changes, and push them back.</para> 15.283 + 15.284 + &interaction.branch-repo.bugfix; 15.285 + 15.286 + <para>Meanwhile, development for 15.287 + the next major release can continue, isolated and unabated, in 15.288 + the <literal>myproject</literal> repository.</para> 15.289 + 15.290 + &interaction.branch-repo.new; 15.291 + 15.292 + </sect1> 15.293 + <sect1> 15.294 + <title>Don't repeat yourself: merging across branches</title> 15.295 + 15.296 + <para>In many cases, if you have a bug to fix on a maintenance 15.297 + branch, the chances are good that the bug exists on your 15.298 + project's main branch (and possibly other maintenance branches, 15.299 + too). It's a rare developer who wants to fix the same bug 15.300 + multiple times, so let's look at a few ways that Mercurial can 15.301 + help you to manage these bugfixes without duplicating your 15.302 + work.</para> 15.303 + 15.304 + <para>In the simplest instance, all you need to do is pull changes 15.305 + from your maintenance branch into your local clone of the target 15.306 + branch.</para> 15.307 + 15.308 + &interaction.branch-repo.pull; 15.309 + 15.310 + <para>You'll then need to merge the heads of the two branches, and 15.311 + push back to the main branch.</para> 15.312 + 15.313 + &interaction.branch-repo.merge; 15.314 + 15.315 + </sect1> 15.316 + <sect1> 15.317 + <title>Naming branches within one repository</title> 15.318 + 15.319 + <para>In most instances, isolating branches in repositories is the 15.320 + right approach. Its simplicity makes it easy to understand; and 15.321 + so it's hard to make mistakes. There's a one-to-one 15.322 + relationship between branches you're working in and directories 15.323 + on your system. This lets you use normal (non-Mercurial-aware) 15.324 + tools to work on files within a branch/repository.</para> 15.325 + 15.326 + <para>If you're more in the <quote>power user</quote> category 15.327 + (<emphasis>and</emphasis> your collaborators are too), there is 15.328 + an alternative way of handling branches that you can consider. 15.329 + I've already mentioned the human-level distinction between 15.330 + <quote>small picture</quote> and <quote>big picture</quote> 15.331 + branches. While Mercurial works with multiple <quote>small 15.332 + picture</quote> branches in a repository all the time (for 15.333 + example after you pull changes in, but before you merge them), 15.334 + it can <emphasis>also</emphasis> work with multiple <quote>big 15.335 + picture</quote> branches.</para> 15.336 + 15.337 + <para>The key to working this way is that Mercurial lets you 15.338 + assign a persistent <emphasis>name</emphasis> to a branch. 15.339 + There always exists a branch named <literal>default</literal>. 15.340 + Even before you start naming branches yourself, you can find 15.341 + traces of the <literal>default</literal> branch if you look for 15.342 + them.</para> 15.343 + 15.344 + <para>As an example, when you run the <command role="hg-cmd">hg 15.345 + commit</command> command, and it pops up your editor so that 15.346 + you can enter a commit message, look for a line that contains 15.347 + the text <quote><literal>HG: branch default</literal></quote> at 15.348 + the bottom. This is telling you that your commit will occur on 15.349 + the branch named <literal>default</literal>.</para> 15.350 + 15.351 + <para>To start working with named branches, use the <command 15.352 + role="hg-cmd">hg branches</command> command. This command 15.353 + lists the named branches already present in your repository, 15.354 + telling you which changeset is the tip of each.</para> 15.355 + 15.356 + &interaction.branch-named.branches; 15.357 + 15.358 + <para>Since you haven't created any named branches yet, the only 15.359 + one that exists is <literal>default</literal>.</para> 15.360 + 15.361 + <para>To find out what the <quote>current</quote> branch is, run 15.362 + the <command role="hg-cmd">hg branch</command> command, giving 15.363 + it no arguments. This tells you what branch the parent of the 15.364 + current changeset is on.</para> 15.365 + 15.366 + &interaction.branch-named.branch; 15.367 + 15.368 + <para>To create a new branch, run the <command role="hg-cmd">hg 15.369 + branch</command> command again. This time, give it one 15.370 + argument: the name of the branch you want to create.</para> 15.371 + 15.372 + &interaction.branch-named.create; 15.373 + 15.374 + <para>After you've created a branch, you might wonder what effect 15.375 + the <command role="hg-cmd">hg branch</command> command has had. 15.376 + What do the <command role="hg-cmd">hg status</command> and 15.377 + <command role="hg-cmd">hg tip</command> commands report?</para> 15.378 + 15.379 + &interaction.branch-named.status; 15.380 + 15.381 + <para>Nothing has changed in the 15.382 + working directory, and there's been no new history created. As 15.383 + this suggests, running the <command role="hg-cmd">hg 15.384 + branch</command> command has no permanent effect; it only 15.385 + tells Mercurial what branch name to use the 15.386 + <emphasis>next</emphasis> time you commit a changeset.</para> 15.387 + 15.388 + <para>When you commit a change, Mercurial records the name of the 15.389 + branch on which you committed. Once you've switched from the 15.390 + <literal>default</literal> branch to another and committed, 15.391 + you'll see the name of the new branch show up in the output of 15.392 + <command role="hg-cmd">hg log</command>, <command 15.393 + role="hg-cmd">hg tip</command>, and other commands that 15.394 + display the same kind of output.</para> 15.395 + 15.396 + &interaction.branch-named.commit; 15.397 + 15.398 + <para>The <command role="hg-cmd">hg log</command>-like commands 15.399 + will print the branch name of every changeset that's not on the 15.400 + <literal>default</literal> branch. As a result, if you never 15.401 + use named branches, you'll never see this information.</para> 15.402 + 15.403 + <para>Once you've named a branch and committed a change with that 15.404 + name, every subsequent commit that descends from that change 15.405 + will inherit the same branch name. You can change the name of a 15.406 + branch at any time, using the <command role="hg-cmd">hg 15.407 + branch</command> command.</para> 15.408 + 15.409 + &interaction.branch-named.rebranch; 15.410 + 15.411 + <para>In practice, this is something you won't do very often, as 15.412 + branch names tend to have fairly long lifetimes. (This isn't a 15.413 + rule, just an observation.)</para> 15.414 + 15.415 + </sect1> 15.416 + <sect1> 15.417 + <title>Dealing with multiple named branches in a 15.418 + repository</title> 15.419 + 15.420 + <para>If you have more than one named branch in a repository, 15.421 + Mercurial will remember the branch that your working directory 15.422 + on when you start a command like <command role="hg-cmd">hg 15.423 + update</command> or <command role="hg-cmd">hg pull 15.424 + -u</command>. It will update the working directory to the tip 15.425 + of this branch, no matter what the <quote>repo-wide</quote> tip 15.426 + is. To update to a revision that's on a different named branch, 15.427 + you may need to use the <option role="hg-opt-update">-C</option> 15.428 + option to <command role="hg-cmd">hg update</command>.</para> 15.429 + 15.430 + <para>This behaviour is a little subtle, so let's see it in 15.431 + action. First, let's remind ourselves what branch we're 15.432 + currently on, and what branches are in our repository.</para> 15.433 + 15.434 + &interaction.branch-named.parents; 15.435 + 15.436 + <para>We're on the <literal>bar</literal> branch, but there also 15.437 + exists an older <command role="hg-cmd">hg foo</command> 15.438 + branch.</para> 15.439 + 15.440 + <para>We can <command role="hg-cmd">hg update</command> back and 15.441 + forth between the tips of the <literal>foo</literal> and 15.442 + <literal>bar</literal> branches without needing to use the 15.443 + <option role="hg-opt-update">-C</option> option, because this 15.444 + only involves going backwards and forwards linearly through our 15.445 + change history.</para> 15.446 + 15.447 + &interaction.branch-named.update-switchy; 15.448 + 15.449 + <para>If we go back to the <literal>foo</literal> branch and then 15.450 + run <command role="hg-cmd">hg update</command>, it will keep us 15.451 + on <literal>foo</literal>, not move us to the tip of 15.452 + <literal>bar</literal>.</para> 15.453 + 15.454 + &interaction.branch-named.update-nothing; 15.455 + 15.456 + <para>Committing a new change on the <literal>foo</literal> branch 15.457 + introduces a new head.</para> 15.458 + 15.459 + &interaction.branch-named.foo-commit; 15.460 + 15.461 + </sect1> 15.462 + <sect1> 15.463 + <title>Branch names and merging</title> 15.464 + 15.465 + <para>As you've probably noticed, merges in Mercurial are not 15.466 + symmetrical. Let's say our repository has two heads, 17 and 23. 15.467 + If I <command role="hg-cmd">hg update</command> to 17 and then 15.468 + <command role="hg-cmd">hg merge</command> with 23, Mercurial 15.469 + records 17 as the first parent of the merge, and 23 as the 15.470 + second. Whereas if I <command role="hg-cmd">hg update</command> 15.471 + to 23 and then <command role="hg-cmd">hg merge</command> with 15.472 + 17, it records 23 as the first parent, and 17 as the 15.473 + second.</para> 15.474 + 15.475 + <para>This affects Mercurial's choice of branch name when you 15.476 + merge. After a merge, Mercurial will retain the branch name of 15.477 + the first parent when you commit the result of the merge. If 15.478 + your first parent's branch name is <literal>foo</literal>, and 15.479 + you merge with <literal>bar</literal>, the branch name will 15.480 + still be <literal>foo</literal> after you merge.</para> 15.481 + 15.482 + <para>It's not unusual for a repository to contain multiple heads, 15.483 + each with the same branch name. Let's say I'm working on the 15.484 + <literal>foo</literal> branch, and so are you. We commit 15.485 + different changes; I pull your changes; I now have two heads, 15.486 + each claiming to be on the <literal>foo</literal> branch. The 15.487 + result of a merge will be a single head on the 15.488 + <literal>foo</literal> branch, as you might hope.</para> 15.489 + 15.490 + <para>But if I'm working on the <literal>bar</literal> branch, and 15.491 + I merge work from the <literal>foo</literal> branch, the result 15.492 + will remain on the <literal>bar</literal> branch.</para> 15.493 + 15.494 + &interaction.branch-named.merge; 15.495 + 15.496 + <para>To give a more concrete example, if I'm working on the 15.497 + <literal>bleeding-edge</literal> branch, and I want to bring in 15.498 + the latest fixes from the <literal>stable</literal> branch, 15.499 + Mercurial will choose the <quote>right</quote> 15.500 + (<literal>bleeding-edge</literal>) branch name when I pull and 15.501 + merge from <literal>stable</literal>.</para> 15.502 + 15.503 + </sect1> 15.504 + <sect1> 15.505 + <title>Branch naming is generally useful</title> 15.506 + 15.507 + <para>You shouldn't think of named branches as applicable only to 15.508 + situations where you have multiple long-lived branches 15.509 + cohabiting in a single repository. They're very useful even in 15.510 + the one-branch-per-repository case.</para> 15.511 + 15.512 + <para>In the simplest case, giving a name to each branch gives you 15.513 + a permanent record of which branch a changeset originated on. 15.514 + This gives you more context when you're trying to follow the 15.515 + history of a long-lived branchy project.</para> 15.516 + 15.517 + <para>If you're working with shared repositories, you can set up a 15.518 + <literal role="hook">pretxnchangegroup</literal> hook on each 15.519 + that will block incoming changes that have the 15.520 + <quote>wrong</quote> branch name. This provides a simple, but 15.521 + effective, defence against people accidentally pushing changes 15.522 + from a <quote>bleeding edge</quote> branch to a 15.523 + <quote>stable</quote> branch. Such a hook might look like this 15.524 + inside the shared repo's <filename role="special"> 15.525 + /.hgrc</filename>.</para> 15.526 + <programlisting>[hooks] 15.527 +pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting> 15.528 + 15.529 + </sect1> 15.530 +</chapter> 15.531 + 15.532 +<!-- 15.533 +local variables: 15.534 +sgml-parent-document: ("00book.xml" "book" "chapter") 15.535 +end: 15.536 +-->
16.1 --- a/en/ch07-filenames.xml Wed Mar 18 00:08:22 2009 -0700 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,408 +0,0 @@ 16.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 16.5 - 16.6 -<chapter id="chap:names"> 16.7 - <?dbhtml filename="file-names-and-pattern-matching.html"?> 16.8 - <title>File names and pattern matching</title> 16.9 - 16.10 - <para>Mercurial provides mechanisms that let you work with file 16.11 - names in a consistent and expressive way.</para> 16.12 - 16.13 - <sect1> 16.14 - <title>Simple file naming</title> 16.15 - 16.16 - <para>Mercurial uses a unified piece of machinery <quote>under the 16.17 - hood</quote> to handle file names. Every command behaves 16.18 - uniformly with respect to file names. The way in which commands 16.19 - work with file names is as follows.</para> 16.20 - 16.21 - <para>If you explicitly name real files on the command line, 16.22 - Mercurial works with exactly those files, as you would expect. 16.23 - &interaction.filenames.files;</para> 16.24 - 16.25 - <para>When you provide a directory name, Mercurial will interpret 16.26 - this as <quote>operate on every file in this directory and its 16.27 - subdirectories</quote>. Mercurial traverses the files and 16.28 - subdirectories in a directory in alphabetical order. When it 16.29 - encounters a subdirectory, it will traverse that subdirectory 16.30 - before continuing with the current directory.</para> 16.31 - 16.32 - &interaction.filenames.dirs; 16.33 - 16.34 - </sect1> 16.35 - <sect1> 16.36 - <title>Running commands without any file names</title> 16.37 - 16.38 - <para>Mercurial's commands that work with file names have useful 16.39 - default behaviours when you invoke them without providing any 16.40 - file names or patterns. What kind of behaviour you should 16.41 - expect depends on what the command does. Here are a few rules 16.42 - of thumb you can use to predict what a command is likely to do 16.43 - if you don't give it any names to work with.</para> 16.44 - <itemizedlist> 16.45 - <listitem><para>Most commands will operate on the entire working 16.46 - directory. This is what the <command role="hg-cmd">hg 16.47 - add</command> command does, for example.</para> 16.48 - </listitem> 16.49 - <listitem><para>If the command has effects that are difficult or 16.50 - impossible to reverse, it will force you to explicitly 16.51 - provide at least one name or pattern (see below). This 16.52 - protects you from accidentally deleting files by running 16.53 - <command role="hg-cmd">hg remove</command> with no 16.54 - arguments, for example.</para> 16.55 - </listitem></itemizedlist> 16.56 - 16.57 - <para>It's easy to work around these default behaviours if they 16.58 - don't suit you. If a command normally operates on the whole 16.59 - working directory, you can invoke it on just the current 16.60 - directory and its subdirectories by giving it the name 16.61 - <quote><filename class="directory">.</filename></quote>.</para> 16.62 - 16.63 - &interaction.filenames.wdir-subdir; 16.64 - 16.65 - <para>Along the same lines, some commands normally print file 16.66 - names relative to the root of the repository, even if you're 16.67 - invoking them from a subdirectory. Such a command will print 16.68 - file names relative to your subdirectory if you give it explicit 16.69 - names. Here, we're going to run <command role="hg-cmd">hg 16.70 - status</command> from a subdirectory, and get it to operate on 16.71 - the entire working directory while printing file names relative 16.72 - to our subdirectory, by passing it the output of the <command 16.73 - role="hg-cmd">hg root</command> command.</para> 16.74 - 16.75 - &interaction.filenames.wdir-relname; 16.76 - 16.77 - </sect1> 16.78 - <sect1> 16.79 - <title>Telling you what's going on</title> 16.80 - 16.81 - <para>The <command role="hg-cmd">hg add</command> example in the 16.82 - preceding section illustrates something else that's helpful 16.83 - about Mercurial commands. If a command operates on a file that 16.84 - you didn't name explicitly on the command line, it will usually 16.85 - print the name of the file, so that you will not be surprised 16.86 - what's going on.</para> 16.87 - 16.88 - <para>The principle here is of <emphasis>least 16.89 - surprise</emphasis>. If you've exactly named a file on the 16.90 - command line, there's no point in repeating it back at you. If 16.91 - Mercurial is acting on a file <emphasis>implicitly</emphasis>, 16.92 - because you provided no names, or a directory, or a pattern (see 16.93 - below), it's safest to tell you what it's doing.</para> 16.94 - 16.95 - <para>For commands that behave this way, you can silence them 16.96 - using the <option role="hg-opt-global">-q</option> option. You 16.97 - can also get them to print the name of every file, even those 16.98 - you've named explicitly, using the <option 16.99 - role="hg-opt-global">-v</option> option.</para> 16.100 - 16.101 - </sect1> 16.102 - <sect1> 16.103 - <title>Using patterns to identify files</title> 16.104 - 16.105 - <para>In addition to working with file and directory names, 16.106 - Mercurial lets you use <emphasis>patterns</emphasis> to identify 16.107 - files. Mercurial's pattern handling is expressive.</para> 16.108 - 16.109 - <para>On Unix-like systems (Linux, MacOS, etc.), the job of 16.110 - matching file names to patterns normally falls to the shell. On 16.111 - these systems, you must explicitly tell Mercurial that a name is 16.112 - a pattern. On Windows, the shell does not expand patterns, so 16.113 - Mercurial will automatically identify names that are patterns, 16.114 - and expand them for you.</para> 16.115 - 16.116 - <para>To provide a pattern in place of a regular name on the 16.117 - command line, the mechanism is simple:</para> 16.118 - <programlisting>syntax:patternbody</programlisting> 16.119 - <para>That is, a pattern is identified by a short text string that 16.120 - says what kind of pattern this is, followed by a colon, followed 16.121 - by the actual pattern.</para> 16.122 - 16.123 - <para>Mercurial supports two kinds of pattern syntax. The most 16.124 - frequently used is called <literal>glob</literal>; this is the 16.125 - same kind of pattern matching used by the Unix shell, and should 16.126 - be familiar to Windows command prompt users, too.</para> 16.127 - 16.128 - <para>When Mercurial does automatic pattern matching on Windows, 16.129 - it uses <literal>glob</literal> syntax. You can thus omit the 16.130 - <quote><literal>glob:</literal></quote> prefix on Windows, but 16.131 - it's safe to use it, too.</para> 16.132 - 16.133 - <para>The <literal>re</literal> syntax is more powerful; it lets 16.134 - you specify patterns using regular expressions, also known as 16.135 - regexps.</para> 16.136 - 16.137 - <para>By the way, in the examples that follow, notice that I'm 16.138 - careful to wrap all of my patterns in quote characters, so that 16.139 - they won't get expanded by the shell before Mercurial sees 16.140 - them.</para> 16.141 - 16.142 - <sect2> 16.143 - <title>Shell-style <literal>glob</literal> patterns</title> 16.144 - 16.145 - <para>This is an overview of the kinds of patterns you can use 16.146 - when you're matching on glob patterns.</para> 16.147 - 16.148 - <para>The <quote><literal>*</literal></quote> character matches 16.149 - any string, within a single directory.</para> 16.150 - 16.151 - &interaction.filenames.glob.star; 16.152 - 16.153 - <para>The <quote><literal>**</literal></quote> pattern matches 16.154 - any string, and crosses directory boundaries. It's not a 16.155 - standard Unix glob token, but it's accepted by several popular 16.156 - Unix shells, and is very useful.</para> 16.157 - 16.158 - &interaction.filenames.glob.starstar; 16.159 - 16.160 - <para>The <quote><literal>?</literal></quote> pattern matches 16.161 - any single character.</para> 16.162 - 16.163 - &interaction.filenames.glob.question; 16.164 - 16.165 - <para>The <quote><literal>[</literal></quote> character begins a 16.166 - <emphasis>character class</emphasis>. This matches any single 16.167 - character within the class. The class ends with a 16.168 - <quote><literal>]</literal></quote> character. A class may 16.169 - contain multiple <emphasis>range</emphasis>s of the form 16.170 - <quote><literal>a-f</literal></quote>, which is shorthand for 16.171 - <quote><literal>abcdef</literal></quote>.</para> 16.172 - 16.173 - &interaction.filenames.glob.range; 16.174 - 16.175 - <para>If the first character after the 16.176 - <quote><literal>[</literal></quote> in a character class is a 16.177 - <quote><literal>!</literal></quote>, it 16.178 - <emphasis>negates</emphasis> the class, making it match any 16.179 - single character not in the class.</para> 16.180 - 16.181 - <para>A <quote><literal>{</literal></quote> begins a group of 16.182 - subpatterns, where the whole group matches if any subpattern 16.183 - in the group matches. The <quote><literal>,</literal></quote> 16.184 - character separates subpatterns, and 16.185 - <quote><literal>}</literal></quote> ends the group.</para> 16.186 - 16.187 - &interaction.filenames.glob.group; 16.188 - 16.189 - <sect3> 16.190 - <title>Watch out!</title> 16.191 - 16.192 - <para>Don't forget that if you want to match a pattern in any 16.193 - directory, you should not be using the 16.194 - <quote><literal>*</literal></quote> match-any token, as this 16.195 - will only match within one directory. Instead, use the 16.196 - <quote><literal>**</literal></quote> token. This small 16.197 - example illustrates the difference between the two.</para> 16.198 - 16.199 - &interaction.filenames.glob.star-starstar; 16.200 - 16.201 - </sect3> 16.202 - </sect2> 16.203 - <sect2> 16.204 - <title>Regular expression matching with <literal>re</literal> 16.205 - patterns</title> 16.206 - 16.207 - <para>Mercurial accepts the same regular expression syntax as 16.208 - the Python programming language (it uses Python's regexp 16.209 - engine internally). This is based on the Perl language's 16.210 - regexp syntax, which is the most popular dialect in use (it's 16.211 - also used in Java, for example).</para> 16.212 - 16.213 - <para>I won't discuss Mercurial's regexp dialect in any detail 16.214 - here, as regexps are not often used. Perl-style regexps are 16.215 - in any case already exhaustively documented on a multitude of 16.216 - web sites, and in many books. Instead, I will focus here on a 16.217 - few things you should know if you find yourself needing to use 16.218 - regexps with Mercurial.</para> 16.219 - 16.220 - <para>A regexp is matched against an entire file name, relative 16.221 - to the root of the repository. In other words, even if you're 16.222 - already in subbdirectory <filename 16.223 - class="directory">foo</filename>, if you want to match files 16.224 - under this directory, your pattern must start with 16.225 - <quote><literal>foo/</literal></quote>.</para> 16.226 - 16.227 - <para>One thing to note, if you're familiar with Perl-style 16.228 - regexps, is that Mercurial's are <emphasis>rooted</emphasis>. 16.229 - That is, a regexp starts matching against the beginning of a 16.230 - string; it doesn't look for a match anywhere within the 16.231 - string. To match anywhere in a string, start your pattern 16.232 - with <quote><literal>.*</literal></quote>.</para> 16.233 - 16.234 - </sect2> 16.235 - </sect1> 16.236 - <sect1> 16.237 - <title>Filtering files</title> 16.238 - 16.239 - <para>Not only does Mercurial give you a variety of ways to 16.240 - specify files; it lets you further winnow those files using 16.241 - <emphasis>filters</emphasis>. Commands that work with file 16.242 - names accept two filtering options.</para> 16.243 - <itemizedlist> 16.244 - <listitem><para><option role="hg-opt-global">-I</option>, or 16.245 - <option role="hg-opt-global">--include</option>, lets you 16.246 - specify a pattern that file names must match in order to be 16.247 - processed.</para> 16.248 - </listitem> 16.249 - <listitem><para><option role="hg-opt-global">-X</option>, or 16.250 - <option role="hg-opt-global">--exclude</option>, gives you a 16.251 - way to <emphasis>avoid</emphasis> processing files, if they 16.252 - match this pattern.</para> 16.253 - </listitem></itemizedlist> 16.254 - <para>You can provide multiple <option 16.255 - role="hg-opt-global">-I</option> and <option 16.256 - role="hg-opt-global">-X</option> options on the command line, 16.257 - and intermix them as you please. Mercurial interprets the 16.258 - patterns you provide using glob syntax by default (but you can 16.259 - use regexps if you need to).</para> 16.260 - 16.261 - <para>You can read a <option role="hg-opt-global">-I</option> 16.262 - filter as <quote>process only the files that match this 16.263 - filter</quote>.</para> 16.264 - 16.265 - &interaction.filenames.filter.include; 16.266 - 16.267 - <para>The <option role="hg-opt-global">-X</option> filter is best 16.268 - read as <quote>process only the files that don't match this 16.269 - pattern</quote>.</para> 16.270 - 16.271 - &interaction.filenames.filter.exclude; 16.272 - 16.273 - </sect1> 16.274 - <sect1> 16.275 - <title>Ignoring unwanted files and directories</title> 16.276 - 16.277 - <para>XXX.</para> 16.278 - 16.279 - </sect1> 16.280 - <sect1 id="sec:names:case"> 16.281 - <title>Case sensitivity</title> 16.282 - 16.283 - <para>If you're working in a mixed development environment that 16.284 - contains both Linux (or other Unix) systems and Macs or Windows 16.285 - systems, you should keep in the back of your mind the knowledge 16.286 - that they treat the case (<quote>N</quote> versus 16.287 - <quote>n</quote>) of file names in incompatible ways. This is 16.288 - not very likely to affect you, and it's easy to deal with if it 16.289 - does, but it could surprise you if you don't know about 16.290 - it.</para> 16.291 - 16.292 - <para>Operating systems and filesystems differ in the way they 16.293 - handle the <emphasis>case</emphasis> of characters in file and 16.294 - directory names. There are three common ways to handle case in 16.295 - names.</para> 16.296 - <itemizedlist> 16.297 - <listitem><para>Completely case insensitive. Uppercase and 16.298 - lowercase versions of a letter are treated as identical, 16.299 - both when creating a file and during subsequent accesses. 16.300 - This is common on older DOS-based systems.</para> 16.301 - </listitem> 16.302 - <listitem><para>Case preserving, but insensitive. When a file 16.303 - or directory is created, the case of its name is stored, and 16.304 - can be retrieved and displayed by the operating system. 16.305 - When an existing file is being looked up, its case is 16.306 - ignored. This is the standard arrangement on Windows and 16.307 - MacOS. The names <filename>foo</filename> and 16.308 - <filename>FoO</filename> identify the same file. This 16.309 - treatment of uppercase and lowercase letters as 16.310 - interchangeable is also referred to as <emphasis>case 16.311 - folding</emphasis>.</para> 16.312 - </listitem> 16.313 - <listitem><para>Case sensitive. The case of a name is 16.314 - significant at all times. The names <filename>foo</filename> 16.315 - and {FoO} identify different files. This is the way Linux 16.316 - and Unix systems normally work.</para> 16.317 - </listitem></itemizedlist> 16.318 - 16.319 - <para>On Unix-like systems, it is possible to have any or all of 16.320 - the above ways of handling case in action at once. For example, 16.321 - if you use a USB thumb drive formatted with a FAT32 filesystem 16.322 - on a Linux system, Linux will handle names on that filesystem in 16.323 - a case preserving, but insensitive, way.</para> 16.324 - 16.325 - <sect2> 16.326 - <title>Safe, portable repository storage</title> 16.327 - 16.328 - <para>Mercurial's repository storage mechanism is <emphasis>case 16.329 - safe</emphasis>. It translates file names so that they can 16.330 - be safely stored on both case sensitive and case insensitive 16.331 - filesystems. This means that you can use normal file copying 16.332 - tools to transfer a Mercurial repository onto, for example, a 16.333 - USB thumb drive, and safely move that drive and repository 16.334 - back and forth between a Mac, a PC running Windows, and a 16.335 - Linux box.</para> 16.336 - 16.337 - </sect2> 16.338 - <sect2> 16.339 - <title>Detecting case conflicts</title> 16.340 - 16.341 - <para>When operating in the working directory, Mercurial honours 16.342 - the naming policy of the filesystem where the working 16.343 - directory is located. If the filesystem is case preserving, 16.344 - but insensitive, Mercurial will treat names that differ only 16.345 - in case as the same.</para> 16.346 - 16.347 - <para>An important aspect of this approach is that it is 16.348 - possible to commit a changeset on a case sensitive (typically 16.349 - Linux or Unix) filesystem that will cause trouble for users on 16.350 - case insensitive (usually Windows and MacOS) users. If a 16.351 - Linux user commits changes to two files, one named 16.352 - <filename>myfile.c</filename> and the other named 16.353 - <filename>MyFile.C</filename>, they will be stored correctly 16.354 - in the repository. And in the working directories of other 16.355 - Linux users, they will be correctly represented as separate 16.356 - files.</para> 16.357 - 16.358 - <para>If a Windows or Mac user pulls this change, they will not 16.359 - initially have a problem, because Mercurial's repository 16.360 - storage mechanism is case safe. However, once they try to 16.361 - <command role="hg-cmd">hg update</command> the working 16.362 - directory to that changeset, or <command role="hg-cmd">hg 16.363 - merge</command> with that changeset, Mercurial will spot the 16.364 - conflict between the two file names that the filesystem would 16.365 - treat as the same, and forbid the update or merge from 16.366 - occurring.</para> 16.367 - 16.368 - </sect2> 16.369 - <sect2> 16.370 - <title>Fixing a case conflict</title> 16.371 - 16.372 - <para>If you are using Windows or a Mac in a mixed environment 16.373 - where some of your collaborators are using Linux or Unix, and 16.374 - Mercurial reports a case folding conflict when you try to 16.375 - <command role="hg-cmd">hg update</command> or <command 16.376 - role="hg-cmd">hg merge</command>, the procedure to fix the 16.377 - problem is simple.</para> 16.378 - 16.379 - <para>Just find a nearby Linux or Unix box, clone the problem 16.380 - repository onto it, and use Mercurial's <command 16.381 - role="hg-cmd">hg rename</command> command to change the 16.382 - names of any offending files or directories so that they will 16.383 - no longer cause case folding conflicts. Commit this change, 16.384 - <command role="hg-cmd">hg pull</command> or <command 16.385 - role="hg-cmd">hg push</command> it across to your Windows or 16.386 - MacOS system, and <command role="hg-cmd">hg update</command> 16.387 - to the revision with the non-conflicting names.</para> 16.388 - 16.389 - <para>The changeset with case-conflicting names will remain in 16.390 - your project's history, and you still won't be able to 16.391 - <command role="hg-cmd">hg update</command> your working 16.392 - directory to that changeset on a Windows or MacOS system, but 16.393 - you can continue development unimpeded.</para> 16.394 - 16.395 - <note> 16.396 - <para> Prior to version 0.9.3, Mercurial did not use a case 16.397 - safe repository storage mechanism, and did not detect case 16.398 - folding conflicts. If you are using an older version of 16.399 - Mercurial on Windows or MacOS, I strongly recommend that you 16.400 - upgrade.</para> 16.401 - </note> 16.402 - 16.403 - </sect2> 16.404 - </sect1> 16.405 -</chapter> 16.406 - 16.407 -<!-- 16.408 -local variables: 16.409 -sgml-parent-document: ("00book.xml" "book" "chapter") 16.410 -end: 16.411 --->
17.1 --- a/en/ch08-branch.xml Wed Mar 18 00:08:22 2009 -0700 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,533 +0,0 @@ 17.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 17.5 - 17.6 -<chapter id="chap:branch"> 17.7 - <?dbhtml filename="managing-releases-and-branchy-development.html"?> 17.8 - <title>Managing releases and branchy development</title> 17.9 - 17.10 - <para>Mercurial provides several mechanisms for you to manage a 17.11 - project that is making progress on multiple fronts at once. To 17.12 - understand these mechanisms, let's first take a brief look at a 17.13 - fairly normal software project structure.</para> 17.14 - 17.15 - <para>Many software projects issue periodic <quote>major</quote> 17.16 - releases that contain substantial new features. In parallel, they 17.17 - may issue <quote>minor</quote> releases. These are usually 17.18 - identical to the major releases off which they're based, but with 17.19 - a few bugs fixed.</para> 17.20 - 17.21 - <para>In this chapter, we'll start by talking about how to keep 17.22 - records of project milestones such as releases. We'll then 17.23 - continue on to talk about the flow of work between different 17.24 - phases of a project, and how Mercurial can help you to isolate and 17.25 - manage this work.</para> 17.26 - 17.27 - <sect1> 17.28 - <title>Giving a persistent name to a revision</title> 17.29 - 17.30 - <para>Once you decide that you'd like to call a particular 17.31 - revision a <quote>release</quote>, it's a good idea to record 17.32 - the identity of that revision. This will let you reproduce that 17.33 - release at a later date, for whatever purpose you might need at 17.34 - the time (reproducing a bug, porting to a new platform, etc). 17.35 - &interaction.tag.init;</para> 17.36 - 17.37 - <para>Mercurial lets you give a permanent name to any revision 17.38 - using the <command role="hg-cmd">hg tag</command> command. Not 17.39 - surprisingly, these names are called <quote>tags</quote>.</para> 17.40 - 17.41 - &interaction.tag.tag; 17.42 - 17.43 - <para>A tag is nothing more than a <quote>symbolic name</quote> 17.44 - for a revision. Tags exist purely for your convenience, so that 17.45 - you have a handy permanent way to refer to a revision; Mercurial 17.46 - doesn't interpret the tag names you use in any way. Neither 17.47 - does Mercurial place any restrictions on the name of a tag, 17.48 - beyond a few that are necessary to ensure that a tag can be 17.49 - parsed unambiguously. A tag name cannot contain any of the 17.50 - following characters:</para> 17.51 - <itemizedlist> 17.52 - <listitem><para>Colon (ASCII 58, 17.53 - <quote><literal>:</literal></quote>)</para> 17.54 - </listitem> 17.55 - <listitem><para>Carriage return (ASCII 13, 17.56 - <quote><literal>\r</literal></quote>)</para> 17.57 - </listitem> 17.58 - <listitem><para>Newline (ASCII 10, 17.59 - <quote><literal>\n</literal></quote>)</para> 17.60 - </listitem></itemizedlist> 17.61 - 17.62 - <para>You can use the <command role="hg-cmd">hg tags</command> 17.63 - command to display the tags present in your repository. In the 17.64 - output, each tagged revision is identified first by its name, 17.65 - then by revision number, and finally by the unique hash of the 17.66 - revision.</para> 17.67 - 17.68 - &interaction.tag.tags; 17.69 - 17.70 - <para>Notice that <literal>tip</literal> is listed in the output 17.71 - of <command role="hg-cmd">hg tags</command>. The 17.72 - <literal>tip</literal> tag is a special <quote>floating</quote> 17.73 - tag, which always identifies the newest revision in the 17.74 - repository.</para> 17.75 - 17.76 - <para>In the output of the <command role="hg-cmd">hg 17.77 - tags</command> command, tags are listed in reverse order, by 17.78 - revision number. This usually means that recent tags are listed 17.79 - before older tags. It also means that <literal>tip</literal> is 17.80 - always going to be the first tag listed in the output of 17.81 - <command role="hg-cmd">hg tags</command>.</para> 17.82 - 17.83 - <para>When you run <command role="hg-cmd">hg log</command>, if it 17.84 - displays a revision that has tags associated with it, it will 17.85 - print those tags.</para> 17.86 - 17.87 - &interaction.tag.log; 17.88 - 17.89 - <para>Any time you need to provide a revision ID to a Mercurial 17.90 - command, the command will accept a tag name in its place. 17.91 - Internally, Mercurial will translate your tag name into the 17.92 - corresponding revision ID, then use that.</para> 17.93 - 17.94 - &interaction.tag.log.v1.0; 17.95 - 17.96 - <para>There's no limit on the number of tags you can have in a 17.97 - repository, or on the number of tags that a single revision can 17.98 - have. As a practical matter, it's not a great idea to have 17.99 - <quote>too many</quote> (a number which will vary from project 17.100 - to project), simply because tags are supposed to help you to 17.101 - find revisions. If you have lots of tags, the ease of using 17.102 - them to identify revisions diminishes rapidly.</para> 17.103 - 17.104 - <para>For example, if your project has milestones as frequent as 17.105 - every few days, it's perfectly reasonable to tag each one of 17.106 - those. But if you have a continuous build system that makes 17.107 - sure every revision can be built cleanly, you'd be introducing a 17.108 - lot of noise if you were to tag every clean build. Instead, you 17.109 - could tag failed builds (on the assumption that they're rare!), 17.110 - or simply not use tags to track buildability.</para> 17.111 - 17.112 - <para>If you want to remove a tag that you no longer want, use 17.113 - <command role="hg-cmd">hg tag --remove</command>.</para> 17.114 - 17.115 - &interaction.tag.remove; 17.116 - 17.117 - <para>You can also modify a tag at any time, so that it identifies 17.118 - a different revision, by simply issuing a new <command 17.119 - role="hg-cmd">hg tag</command> command. You'll have to use the 17.120 - <option role="hg-opt-tag">-f</option> option to tell Mercurial 17.121 - that you <emphasis>really</emphasis> want to update the 17.122 - tag.</para> 17.123 - 17.124 - &interaction.tag.replace; 17.125 - 17.126 - <para>There will still be a permanent record of the previous 17.127 - identity of the tag, but Mercurial will no longer use it. 17.128 - There's thus no penalty to tagging the wrong revision; all you 17.129 - have to do is turn around and tag the correct revision once you 17.130 - discover your error.</para> 17.131 - 17.132 - <para>Mercurial stores tags in a normal revision-controlled file 17.133 - in your repository. If you've created any tags, you'll find 17.134 - them in a file named <filename 17.135 - role="special">.hgtags</filename>. When you run the <command 17.136 - role="hg-cmd">hg tag</command> command, Mercurial modifies 17.137 - this file, then automatically commits the change to it. This 17.138 - means that every time you run <command role="hg-cmd">hg 17.139 - tag</command>, you'll see a corresponding changeset in the 17.140 - output of <command role="hg-cmd">hg log</command>.</para> 17.141 - 17.142 - &interaction.tag.tip; 17.143 - 17.144 - <sect2> 17.145 - <title>Handling tag conflicts during a merge</title> 17.146 - 17.147 - <para>You won't often need to care about the <filename 17.148 - role="special">.hgtags</filename> file, but it sometimes 17.149 - makes its presence known during a merge. The format of the 17.150 - file is simple: it consists of a series of lines. Each line 17.151 - starts with a changeset hash, followed by a space, followed by 17.152 - the name of a tag.</para> 17.153 - 17.154 - <para>If you're resolving a conflict in the <filename 17.155 - role="special">.hgtags</filename> file during a merge, 17.156 - there's one twist to modifying the <filename 17.157 - role="special">.hgtags</filename> file: when Mercurial is 17.158 - parsing the tags in a repository, it 17.159 - <emphasis>never</emphasis> reads the working copy of the 17.160 - <filename role="special">.hgtags</filename> file. Instead, it 17.161 - reads the <emphasis>most recently committed</emphasis> 17.162 - revision of the file.</para> 17.163 - 17.164 - <para>An unfortunate consequence of this design is that you 17.165 - can't actually verify that your merged <filename 17.166 - role="special">.hgtags</filename> file is correct until 17.167 - <emphasis>after</emphasis> you've committed a change. So if 17.168 - you find yourself resolving a conflict on <filename 17.169 - role="special">.hgtags</filename> during a merge, be sure to 17.170 - run <command role="hg-cmd">hg tags</command> after you commit. 17.171 - If it finds an error in the <filename 17.172 - role="special">.hgtags</filename> file, it will report the 17.173 - location of the error, which you can then fix and commit. You 17.174 - should then run <command role="hg-cmd">hg tags</command> 17.175 - again, just to be sure that your fix is correct.</para> 17.176 - 17.177 - </sect2> 17.178 - <sect2> 17.179 - <title>Tags and cloning</title> 17.180 - 17.181 - <para>You may have noticed that the <command role="hg-cmd">hg 17.182 - clone</command> command has a <option 17.183 - role="hg-opt-clone">-r</option> option that lets you clone 17.184 - an exact copy of the repository as of a particular changeset. 17.185 - The new clone will not contain any project history that comes 17.186 - after the revision you specified. This has an interaction 17.187 - with tags that can surprise the unwary.</para> 17.188 - 17.189 - <para>Recall that a tag is stored as a revision to the <filename 17.190 - role="special">.hgtags</filename> file, so that when you 17.191 - create a tag, the changeset in which it's recorded necessarily 17.192 - refers to an older changeset. When you run <command 17.193 - role="hg-cmd">hg clone -r foo</command> to clone a 17.194 - repository as of tag <literal>foo</literal>, the new clone 17.195 - <emphasis>will not contain the history that created the 17.196 - tag</emphasis> that you used to clone the repository. The 17.197 - result is that you'll get exactly the right subset of the 17.198 - project's history in the new repository, but 17.199 - <emphasis>not</emphasis> the tag you might have 17.200 - expected.</para> 17.201 - 17.202 - </sect2> 17.203 - <sect2> 17.204 - <title>When permanent tags are too much</title> 17.205 - 17.206 - <para>Since Mercurial's tags are revision controlled and carried 17.207 - around with a project's history, everyone you work with will 17.208 - see the tags you create. But giving names to revisions has 17.209 - uses beyond simply noting that revision 17.210 - <literal>4237e45506ee</literal> is really 17.211 - <literal>v2.0.2</literal>. If you're trying to track down a 17.212 - subtle bug, you might want a tag to remind you of something 17.213 - like <quote>Anne saw the symptoms with this 17.214 - revision</quote>.</para> 17.215 - 17.216 - <para>For cases like this, what you might want to use are 17.217 - <emphasis>local</emphasis> tags. You can create a local tag 17.218 - with the <option role="hg-opt-tag">-l</option> option to the 17.219 - <command role="hg-cmd">hg tag</command> command. This will 17.220 - store the tag in a file called <filename 17.221 - role="special">.hg/localtags</filename>. Unlike <filename 17.222 - role="special">.hgtags</filename>, <filename 17.223 - role="special">.hg/localtags</filename> is not revision 17.224 - controlled. Any tags you create using <option 17.225 - role="hg-opt-tag">-l</option> remain strictly local to the 17.226 - repository you're currently working in.</para> 17.227 - 17.228 - </sect2> 17.229 - </sect1> 17.230 - <sect1> 17.231 - <title>The flow of changes&emdash;big picture vs. little</title> 17.232 - 17.233 - <para>To return to the outline I sketched at the beginning of a 17.234 - chapter, let's think about a project that has multiple 17.235 - concurrent pieces of work under development at once.</para> 17.236 - 17.237 - <para>There might be a push for a new <quote>main</quote> release; 17.238 - a new minor bugfix release to the last main release; and an 17.239 - unexpected <quote>hot fix</quote> to an old release that is now 17.240 - in maintenance mode.</para> 17.241 - 17.242 - <para>The usual way people refer to these different concurrent 17.243 - directions of development is as <quote>branches</quote>. 17.244 - However, we've already seen numerous times that Mercurial treats 17.245 - <emphasis>all of history</emphasis> as a series of branches and 17.246 - merges. Really, what we have here is two ideas that are 17.247 - peripherally related, but which happen to share a name.</para> 17.248 - <itemizedlist> 17.249 - <listitem><para><quote>Big picture</quote> branches represent 17.250 - the sweep of a project's evolution; people give them names, 17.251 - and talk about them in conversation.</para> 17.252 - </listitem> 17.253 - <listitem><para><quote>Little picture</quote> branches are 17.254 - artefacts of the day-to-day activity of developing and 17.255 - merging changes. They expose the narrative of how the code 17.256 - was developed.</para> 17.257 - </listitem></itemizedlist> 17.258 - 17.259 - </sect1> 17.260 - <sect1> 17.261 - <title>Managing big-picture branches in repositories</title> 17.262 - 17.263 - <para>The easiest way to isolate a <quote>big picture</quote> 17.264 - branch in Mercurial is in a dedicated repository. If you have 17.265 - an existing shared repository&emdash;let's call it 17.266 - <literal>myproject</literal>&emdash;that reaches a 17.267 - <quote>1.0</quote> milestone, you can start to prepare for 17.268 - future maintenance releases on top of version 1.0 by tagging the 17.269 - revision from which you prepared the 1.0 release.</para> 17.270 - 17.271 - &interaction.branch-repo.tag; 17.272 - 17.273 - <para>You can then clone a new shared 17.274 - <literal>myproject-1.0.1</literal> repository as of that 17.275 - tag.</para> 17.276 - 17.277 - &interaction.branch-repo.clone; 17.278 - 17.279 - <para>Afterwards, if someone needs to work on a bug fix that ought 17.280 - to go into an upcoming 1.0.1 minor release, they clone the 17.281 - <literal>myproject-1.0.1</literal> repository, make their 17.282 - changes, and push them back.</para> 17.283 - 17.284 - &interaction.branch-repo.bugfix; 17.285 - 17.286 - <para>Meanwhile, development for 17.287 - the next major release can continue, isolated and unabated, in 17.288 - the <literal>myproject</literal> repository.</para> 17.289 - 17.290 - &interaction.branch-repo.new; 17.291 - 17.292 - </sect1> 17.293 - <sect1> 17.294 - <title>Don't repeat yourself: merging across branches</title> 17.295 - 17.296 - <para>In many cases, if you have a bug to fix on a maintenance 17.297 - branch, the chances are good that the bug exists on your 17.298 - project's main branch (and possibly other maintenance branches, 17.299 - too). It's a rare developer who wants to fix the same bug 17.300 - multiple times, so let's look at a few ways that Mercurial can 17.301 - help you to manage these bugfixes without duplicating your 17.302 - work.</para> 17.303 - 17.304 - <para>In the simplest instance, all you need to do is pull changes 17.305 - from your maintenance branch into your local clone of the target 17.306 - branch.</para> 17.307 - 17.308 - &interaction.branch-repo.pull; 17.309 - 17.310 - <para>You'll then need to merge the heads of the two branches, and 17.311 - push back to the main branch.</para> 17.312 - 17.313 - &interaction.branch-repo.merge; 17.314 - 17.315 - </sect1> 17.316 - <sect1> 17.317 - <title>Naming branches within one repository</title> 17.318 - 17.319 - <para>In most instances, isolating branches in repositories is the 17.320 - right approach. Its simplicity makes it easy to understand; and 17.321 - so it's hard to make mistakes. There's a one-to-one 17.322 - relationship between branches you're working in and directories 17.323 - on your system. This lets you use normal (non-Mercurial-aware) 17.324 - tools to work on files within a branch/repository.</para> 17.325 - 17.326 - <para>If you're more in the <quote>power user</quote> category 17.327 - (<emphasis>and</emphasis> your collaborators are too), there is 17.328 - an alternative way of handling branches that you can consider. 17.329 - I've already mentioned the human-level distinction between 17.330 - <quote>small picture</quote> and <quote>big picture</quote> 17.331 - branches. While Mercurial works with multiple <quote>small 17.332 - picture</quote> branches in a repository all the time (for 17.333 - example after you pull changes in, but before you merge them), 17.334 - it can <emphasis>also</emphasis> work with multiple <quote>big 17.335 - picture</quote> branches.</para> 17.336 - 17.337 - <para>The key to working this way is that Mercurial lets you 17.338 - assign a persistent <emphasis>name</emphasis> to a branch. 17.339 - There always exists a branch named <literal>default</literal>. 17.340 - Even before you start naming branches yourself, you can find 17.341 - traces of the <literal>default</literal> branch if you look for 17.342 - them.</para> 17.343 - 17.344 - <para>As an example, when you run the <command role="hg-cmd">hg 17.345 - commit</command> command, and it pops up your editor so that 17.346 - you can enter a commit message, look for a line that contains 17.347 - the text <quote><literal>HG: branch default</literal></quote> at 17.348 - the bottom. This is telling you that your commit will occur on 17.349 - the branch named <literal>default</literal>.</para> 17.350 - 17.351 - <para>To start working with named branches, use the <command 17.352 - role="hg-cmd">hg branches</command> command. This command 17.353 - lists the named branches already present in your repository, 17.354 - telling you which changeset is the tip of each.</para> 17.355 - 17.356 - &interaction.branch-named.branches; 17.357 - 17.358 - <para>Since you haven't created any named branches yet, the only 17.359 - one that exists is <literal>default</literal>.</para> 17.360 - 17.361 - <para>To find out what the <quote>current</quote> branch is, run 17.362 - the <command role="hg-cmd">hg branch</command> command, giving 17.363 - it no arguments. This tells you what branch the parent of the 17.364 - current changeset is on.</para> 17.365 - 17.366 - &interaction.branch-named.branch; 17.367 - 17.368 - <para>To create a new branch, run the <command role="hg-cmd">hg 17.369 - branch</command> command again. This time, give it one 17.370 - argument: the name of the branch you want to create.</para> 17.371 - 17.372 - &interaction.branch-named.create; 17.373 - 17.374 - <para>After you've created a branch, you might wonder what effect 17.375 - the <command role="hg-cmd">hg branch</command> command has had. 17.376 - What do the <command role="hg-cmd">hg status</command> and 17.377 - <command role="hg-cmd">hg tip</command> commands report?</para> 17.378 - 17.379 - &interaction.branch-named.status; 17.380 - 17.381 - <para>Nothing has changed in the 17.382 - working directory, and there's been no new history created. As 17.383 - this suggests, running the <command role="hg-cmd">hg 17.384 - branch</command> command has no permanent effect; it only 17.385 - tells Mercurial what branch name to use the 17.386 - <emphasis>next</emphasis> time you commit a changeset.</para> 17.387 - 17.388 - <para>When you commit a change, Mercurial records the name of the 17.389 - branch on which you committed. Once you've switched from the 17.390 - <literal>default</literal> branch to another and committed, 17.391 - you'll see the name of the new branch show up in the output of 17.392 - <command role="hg-cmd">hg log</command>, <command 17.393 - role="hg-cmd">hg tip</command>, and other commands that 17.394 - display the same kind of output.</para> 17.395 - 17.396 - &interaction.branch-named.commit; 17.397 - 17.398 - <para>The <command role="hg-cmd">hg log</command>-like commands 17.399 - will print the branch name of every changeset that's not on the 17.400 - <literal>default</literal> branch. As a result, if you never 17.401 - use named branches, you'll never see this information.</para> 17.402 - 17.403 - <para>Once you've named a branch and committed a change with that 17.404 - name, every subsequent commit that descends from that change 17.405 - will inherit the same branch name. You can change the name of a 17.406 - branch at any time, using the <command role="hg-cmd">hg 17.407 - branch</command> command.</para> 17.408 - 17.409 - &interaction.branch-named.rebranch; 17.410 - 17.411 - <para>In practice, this is something you won't do very often, as 17.412 - branch names tend to have fairly long lifetimes. (This isn't a 17.413 - rule, just an observation.)</para> 17.414 - 17.415 - </sect1> 17.416 - <sect1> 17.417 - <title>Dealing with multiple named branches in a 17.418 - repository</title> 17.419 - 17.420 - <para>If you have more than one named branch in a repository, 17.421 - Mercurial will remember the branch that your working directory 17.422 - on when you start a command like <command role="hg-cmd">hg 17.423 - update</command> or <command role="hg-cmd">hg pull 17.424 - -u</command>. It will update the working directory to the tip 17.425 - of this branch, no matter what the <quote>repo-wide</quote> tip 17.426 - is. To update to a revision that's on a different named branch, 17.427 - you may need to use the <option role="hg-opt-update">-C</option> 17.428 - option to <command role="hg-cmd">hg update</command>.</para> 17.429 - 17.430 - <para>This behaviour is a little subtle, so let's see it in 17.431 - action. First, let's remind ourselves what branch we're 17.432 - currently on, and what branches are in our repository.</para> 17.433 - 17.434 - &interaction.branch-named.parents; 17.435 - 17.436 - <para>We're on the <literal>bar</literal> branch, but there also 17.437 - exists an older <command role="hg-cmd">hg foo</command> 17.438 - branch.</para> 17.439 - 17.440 - <para>We can <command role="hg-cmd">hg update</command> back and 17.441 - forth between the tips of the <literal>foo</literal> and 17.442 - <literal>bar</literal> branches without needing to use the 17.443 - <option role="hg-opt-update">-C</option> option, because this 17.444 - only involves going backwards and forwards linearly through our 17.445 - change history.</para> 17.446 - 17.447 - &interaction.branch-named.update-switchy; 17.448 - 17.449 - <para>If we go back to the <literal>foo</literal> branch and then 17.450 - run <command role="hg-cmd">hg update</command>, it will keep us 17.451 - on <literal>foo</literal>, not move us to the tip of 17.452 - <literal>bar</literal>.</para> 17.453 - 17.454 - &interaction.branch-named.update-nothing; 17.455 - 17.456 - <para>Committing a new change on the <literal>foo</literal> branch 17.457 - introduces a new head.</para> 17.458 - 17.459 - &interaction.branch-named.foo-commit; 17.460 - 17.461 - </sect1> 17.462 - <sect1> 17.463 - <title>Branch names and merging</title> 17.464 - 17.465 - <para>As you've probably noticed, merges in Mercurial are not 17.466 - symmetrical. Let's say our repository has two heads, 17 and 23. 17.467 - If I <command role="hg-cmd">hg update</command> to 17 and then 17.468 - <command role="hg-cmd">hg merge</command> with 23, Mercurial 17.469 - records 17 as the first parent of the merge, and 23 as the 17.470 - second. Whereas if I <command role="hg-cmd">hg update</command> 17.471 - to 23 and then <command role="hg-cmd">hg merge</command> with 17.472 - 17, it records 23 as the first parent, and 17 as the 17.473 - second.</para> 17.474 - 17.475 - <para>This affects Mercurial's choice of branch name when you 17.476 - merge. After a merge, Mercurial will retain the branch name of 17.477 - the first parent when you commit the result of the merge. If 17.478 - your first parent's branch name is <literal>foo</literal>, and 17.479 - you merge with <literal>bar</literal>, the branch name will 17.480 - still be <literal>foo</literal> after you merge.</para> 17.481 - 17.482 - <para>It's not unusual for a repository to contain multiple heads, 17.483 - each with the same branch name. Let's say I'm working on the 17.484 - <literal>foo</literal> branch, and so are you. We commit 17.485 - different changes; I pull your changes; I now have two heads, 17.486 - each claiming to be on the <literal>foo</literal> branch. The 17.487 - result of a merge will be a single head on the 17.488 - <literal>foo</literal> branch, as you might hope.</para> 17.489 - 17.490 - <para>But if I'm working on the <literal>bar</literal> branch, and 17.491 - I merge work from the <literal>foo</literal> branch, the result 17.492 - will remain on the <literal>bar</literal> branch.</para> 17.493 - 17.494 - &interaction.branch-named.merge; 17.495 - 17.496 - <para>To give a more concrete example, if I'm working on the 17.497 - <literal>bleeding-edge</literal> branch, and I want to bring in 17.498 - the latest fixes from the <literal>stable</literal> branch, 17.499 - Mercurial will choose the <quote>right</quote> 17.500 - (<literal>bleeding-edge</literal>) branch name when I pull and 17.501 - merge from <literal>stable</literal>.</para> 17.502 - 17.503 - </sect1> 17.504 - <sect1> 17.505 - <title>Branch naming is generally useful</title> 17.506 - 17.507 - <para>You shouldn't think of named branches as applicable only to 17.508 - situations where you have multiple long-lived branches 17.509 - cohabiting in a single repository. They're very useful even in 17.510 - the one-branch-per-repository case.</para> 17.511 - 17.512 - <para>In the simplest case, giving a name to each branch gives you 17.513 - a permanent record of which branch a changeset originated on. 17.514 - This gives you more context when you're trying to follow the 17.515 - history of a long-lived branchy project.</para> 17.516 - 17.517 - <para>If you're working with shared repositories, you can set up a 17.518 - <literal role="hook">pretxnchangegroup</literal> hook on each 17.519 - that will block incoming changes that have the 17.520 - <quote>wrong</quote> branch name. This provides a simple, but 17.521 - effective, defence against people accidentally pushing changes 17.522 - from a <quote>bleeding edge</quote> branch to a 17.523 - <quote>stable</quote> branch. Such a hook might look like this 17.524 - inside the shared repo's <filename role="special"> 17.525 - /.hgrc</filename>.</para> 17.526 - <programlisting>[hooks] 17.527 -pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch</programlisting> 17.528 - 17.529 - </sect1> 17.530 -</chapter> 17.531 - 17.532 -<!-- 17.533 -local variables: 17.534 -sgml-parent-document: ("00book.xml" "book" "chapter") 17.535 -end: 17.536 --->
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/en/ch08-undo.xml Thu Mar 19 20:54:12 2009 -0700 18.3 @@ -0,0 +1,1072 @@ 18.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 18.5 + 18.6 +<chapter id="chap:undo"> 18.7 + <?dbhtml filename="finding-and-fixing-mistakes.html"?> 18.8 + <title>Finding and fixing mistakes</title> 18.9 + 18.10 + <para>To err might be human, but to really handle the consequences 18.11 + well takes a top-notch revision control system. In this chapter, 18.12 + we'll discuss some of the techniques you can use when you find 18.13 + that a problem has crept into your project. Mercurial has some 18.14 + highly capable features that will help you to isolate the sources 18.15 + of problems, and to handle them appropriately.</para> 18.16 + 18.17 + <sect1> 18.18 + <title>Erasing local history</title> 18.19 + 18.20 + <sect2> 18.21 + <title>The accidental commit</title> 18.22 + 18.23 + <para>I have the occasional but persistent problem of typing 18.24 + rather more quickly than I can think, which sometimes results 18.25 + in me committing a changeset that is either incomplete or 18.26 + plain wrong. In my case, the usual kind of incomplete 18.27 + changeset is one in which I've created a new source file, but 18.28 + forgotten to <command role="hg-cmd">hg add</command> it. A 18.29 + <quote>plain wrong</quote> changeset is not as common, but no 18.30 + less annoying.</para> 18.31 + 18.32 + </sect2> 18.33 + <sect2 id="sec:undo:rollback"> 18.34 + <title>Rolling back a transaction</title> 18.35 + 18.36 + <para>In section <xref linkend="sec:concepts:txn"/>, I mentioned 18.37 + that Mercurial treats each modification of a repository as a 18.38 + <emphasis>transaction</emphasis>. Every time you commit a 18.39 + changeset or pull changes from another repository, Mercurial 18.40 + remembers what you did. You can undo, or <emphasis>roll 18.41 + back</emphasis>, exactly one of these actions using the 18.42 + <command role="hg-cmd">hg rollback</command> command. (See 18.43 + section <xref linkend="sec:undo:rollback-after-push"/> for an 18.44 + important caveat about the use of this command.)</para> 18.45 + 18.46 + <para>Here's a mistake that I often find myself making: 18.47 + committing a change in which I've created a new file, but 18.48 + forgotten to <command role="hg-cmd">hg add</command> 18.49 + it.</para> 18.50 + 18.51 + &interaction.rollback.commit; 18.52 + 18.53 + <para>Looking at the output of <command role="hg-cmd">hg 18.54 + status</command> after the commit immediately confirms the 18.55 + error.</para> 18.56 + 18.57 + &interaction.rollback.status; 18.58 + 18.59 + <para>The commit captured the changes to the file 18.60 + <filename>a</filename>, but not the new file 18.61 + <filename>b</filename>. If I were to push this changeset to a 18.62 + repository that I shared with a colleague, the chances are 18.63 + high that something in <filename>a</filename> would refer to 18.64 + <filename>b</filename>, which would not be present in their 18.65 + repository when they pulled my changes. I would thus become 18.66 + the object of some indignation.</para> 18.67 + 18.68 + <para>However, luck is with me&emdash;I've caught my error 18.69 + before I pushed the changeset. I use the <command 18.70 + role="hg-cmd">hg rollback</command> command, and Mercurial 18.71 + makes that last changeset vanish.</para> 18.72 + 18.73 + &interaction.rollback.rollback; 18.74 + 18.75 + <para>Notice that the changeset is no longer present in the 18.76 + repository's history, and the working directory once again 18.77 + thinks that the file <filename>a</filename> is modified. The 18.78 + commit and rollback have left the working directory exactly as 18.79 + it was prior to the commit; the changeset has been completely 18.80 + erased. I can now safely <command role="hg-cmd">hg 18.81 + add</command> the file <filename>b</filename>, and rerun my 18.82 + commit.</para> 18.83 + 18.84 + &interaction.rollback.add; 18.85 + 18.86 + </sect2> 18.87 + <sect2> 18.88 + <title>The erroneous pull</title> 18.89 + 18.90 + <para>It's common practice with Mercurial to maintain separate 18.91 + development branches of a project in different repositories. 18.92 + Your development team might have one shared repository for 18.93 + your project's <quote>0.9</quote> release, and another, 18.94 + containing different changes, for the <quote>1.0</quote> 18.95 + release.</para> 18.96 + 18.97 + <para>Given this, you can imagine that the consequences could be 18.98 + messy if you had a local <quote>0.9</quote> repository, and 18.99 + accidentally pulled changes from the shared <quote>1.0</quote> 18.100 + repository into it. At worst, you could be paying 18.101 + insufficient attention, and push those changes into the shared 18.102 + <quote>0.9</quote> tree, confusing your entire team (but don't 18.103 + worry, we'll return to this horror scenario later). However, 18.104 + it's more likely that you'll notice immediately, because 18.105 + Mercurial will display the URL it's pulling from, or you will 18.106 + see it pull a suspiciously large number of changes into the 18.107 + repository.</para> 18.108 + 18.109 + <para>The <command role="hg-cmd">hg rollback</command> command 18.110 + will work nicely to expunge all of the changesets that you 18.111 + just pulled. Mercurial groups all changes from one <command 18.112 + role="hg-cmd">hg pull</command> into a single transaction, 18.113 + so one <command role="hg-cmd">hg rollback</command> is all you 18.114 + need to undo this mistake.</para> 18.115 + 18.116 + </sect2> 18.117 + <sect2 id="sec:undo:rollback-after-push"> 18.118 + <title>Rolling back is useless once you've pushed</title> 18.119 + 18.120 + <para>The value of the <command role="hg-cmd">hg 18.121 + rollback</command> command drops to zero once you've pushed 18.122 + your changes to another repository. Rolling back a change 18.123 + makes it disappear entirely, but <emphasis>only</emphasis> in 18.124 + the repository in which you perform the <command 18.125 + role="hg-cmd">hg rollback</command>. Because a rollback 18.126 + eliminates history, there's no way for the disappearance of a 18.127 + change to propagate between repositories.</para> 18.128 + 18.129 + <para>If you've pushed a change to another 18.130 + repository&emdash;particularly if it's a shared 18.131 + repository&emdash;it has essentially <quote>escaped into the 18.132 + wild,</quote> and you'll have to recover from your mistake 18.133 + in a different way. What will happen if you push a changeset 18.134 + somewhere, then roll it back, then pull from the repository 18.135 + you pushed to, is that the changeset will reappear in your 18.136 + repository.</para> 18.137 + 18.138 + <para>(If you absolutely know for sure that the change you want 18.139 + to roll back is the most recent change in the repository that 18.140 + you pushed to, <emphasis>and</emphasis> you know that nobody 18.141 + else could have pulled it from that repository, you can roll 18.142 + back the changeset there, too, but you really should really 18.143 + not rely on this working reliably. If you do this, sooner or 18.144 + later a change really will make it into a repository that you 18.145 + don't directly control (or have forgotten about), and come 18.146 + back to bite you.)</para> 18.147 + 18.148 + </sect2> 18.149 + <sect2> 18.150 + <title>You can only roll back once</title> 18.151 + 18.152 + <para>Mercurial stores exactly one transaction in its 18.153 + transaction log; that transaction is the most recent one that 18.154 + occurred in the repository. This means that you can only roll 18.155 + back one transaction. If you expect to be able to roll back 18.156 + one transaction, then its predecessor, this is not the 18.157 + behaviour you will get.</para> 18.158 + 18.159 + &interaction.rollback.twice; 18.160 + 18.161 + <para>Once you've rolled back one transaction in a repository, 18.162 + you can't roll back again in that repository until you perform 18.163 + another commit or pull.</para> 18.164 + 18.165 + </sect2> 18.166 + </sect1> 18.167 + <sect1> 18.168 + <title>Reverting the mistaken change</title> 18.169 + 18.170 + <para>If you make a modification to a file, and decide that you 18.171 + really didn't want to change the file at all, and you haven't 18.172 + yet committed your changes, the <command role="hg-cmd">hg 18.173 + revert</command> command is the one you'll need. It looks at 18.174 + the changeset that's the parent of the working directory, and 18.175 + restores the contents of the file to their state as of that 18.176 + changeset. (That's a long-winded way of saying that, in the 18.177 + normal case, it undoes your modifications.)</para> 18.178 + 18.179 + <para>Let's illustrate how the <command role="hg-cmd">hg 18.180 + revert</command> command works with yet another small example. 18.181 + We'll begin by modifying a file that Mercurial is already 18.182 + tracking.</para> 18.183 + 18.184 + &interaction.daily.revert.modify; 18.185 + 18.186 + <para>If we don't 18.187 + want that change, we can simply <command role="hg-cmd">hg 18.188 + revert</command> the file.</para> 18.189 + 18.190 + &interaction.daily.revert.unmodify; 18.191 + 18.192 + <para>The <command role="hg-cmd">hg revert</command> command 18.193 + provides us with an extra degree of safety by saving our 18.194 + modified file with a <filename>.orig</filename> 18.195 + extension.</para> 18.196 + 18.197 + &interaction.daily.revert.status; 18.198 + 18.199 + <para>Here is a summary of the cases that the <command 18.200 + role="hg-cmd">hg revert</command> command can deal with. We 18.201 + will describe each of these in more detail in the section that 18.202 + follows.</para> 18.203 + <itemizedlist> 18.204 + <listitem><para>If you modify a file, it will restore the file 18.205 + to its unmodified state.</para> 18.206 + </listitem> 18.207 + <listitem><para>If you <command role="hg-cmd">hg add</command> a 18.208 + file, it will undo the <quote>added</quote> state of the 18.209 + file, but leave the file itself untouched.</para> 18.210 + </listitem> 18.211 + <listitem><para>If you delete a file without telling Mercurial, 18.212 + it will restore the file to its unmodified contents.</para> 18.213 + </listitem> 18.214 + <listitem><para>If you use the <command role="hg-cmd">hg 18.215 + remove</command> command to remove a file, it will undo 18.216 + the <quote>removed</quote> state of the file, and restore 18.217 + the file to its unmodified contents.</para> 18.218 + </listitem></itemizedlist> 18.219 + 18.220 + <sect2 id="sec:undo:mgmt"> 18.221 + <title>File management errors</title> 18.222 + 18.223 + <para>The <command role="hg-cmd">hg revert</command> command is 18.224 + useful for more than just modified files. It lets you reverse 18.225 + the results of all of Mercurial's file management 18.226 + commands&emdash;<command role="hg-cmd">hg add</command>, 18.227 + <command role="hg-cmd">hg remove</command>, and so on.</para> 18.228 + 18.229 + <para>If you <command role="hg-cmd">hg add</command> a file, 18.230 + then decide that in fact you don't want Mercurial to track it, 18.231 + use <command role="hg-cmd">hg revert</command> to undo the 18.232 + add. Don't worry; Mercurial will not modify the file in any 18.233 + way. It will just <quote>unmark</quote> the file.</para> 18.234 + 18.235 + &interaction.daily.revert.add; 18.236 + 18.237 + <para>Similarly, if you ask Mercurial to <command 18.238 + role="hg-cmd">hg remove</command> a file, you can use 18.239 + <command role="hg-cmd">hg revert</command> to restore it to 18.240 + the contents it had as of the parent of the working directory. 18.241 + &interaction.daily.revert.remove; This works just as 18.242 + well for a file that you deleted by hand, without telling 18.243 + Mercurial (recall that in Mercurial terminology, this kind of 18.244 + file is called <quote>missing</quote>).</para> 18.245 + 18.246 + &interaction.daily.revert.missing; 18.247 + 18.248 + <para>If you revert a <command role="hg-cmd">hg copy</command>, 18.249 + the copied-to file remains in your working directory 18.250 + afterwards, untracked. Since a copy doesn't affect the 18.251 + copied-from file in any way, Mercurial doesn't do anything 18.252 + with the copied-from file.</para> 18.253 + 18.254 + &interaction.daily.revert.copy; 18.255 + 18.256 + <sect3> 18.257 + <title>A slightly special case: reverting a rename</title> 18.258 + 18.259 + <para>If you <command role="hg-cmd">hg rename</command> a 18.260 + file, there is one small detail that you should remember. 18.261 + When you <command role="hg-cmd">hg revert</command> a 18.262 + rename, it's not enough to provide the name of the 18.263 + renamed-to file, as you can see here.</para> 18.264 + 18.265 + &interaction.daily.revert.rename; 18.266 + 18.267 + <para>As you can see from the output of <command 18.268 + role="hg-cmd">hg status</command>, the renamed-to file is 18.269 + no longer identified as added, but the 18.270 + renamed-<emphasis>from</emphasis> file is still removed! 18.271 + This is counter-intuitive (at least to me), but at least 18.272 + it's easy to deal with.</para> 18.273 + 18.274 + &interaction.daily.revert.rename-orig; 18.275 + 18.276 + <para>So remember, to revert a <command role="hg-cmd">hg 18.277 + rename</command>, you must provide 18.278 + <emphasis>both</emphasis> the source and destination 18.279 + names.</para> 18.280 + 18.281 + <para>% TODO: the output doesn't look like it will be 18.282 + removed!</para> 18.283 + 18.284 + <para>(By the way, if you rename a file, then modify the 18.285 + renamed-to file, then revert both components of the rename, 18.286 + when Mercurial restores the file that was removed as part of 18.287 + the rename, it will be unmodified. If you need the 18.288 + modifications in the renamed-to file to show up in the 18.289 + renamed-from file, don't forget to copy them over.)</para> 18.290 + 18.291 + <para>These fiddly aspects of reverting a rename arguably 18.292 + constitute a small bug in Mercurial.</para> 18.293 + 18.294 + </sect3> 18.295 + </sect2> 18.296 + </sect1> 18.297 + <sect1> 18.298 + <title>Dealing with committed changes</title> 18.299 + 18.300 + <para>Consider a case where you have committed a change $a$, and 18.301 + another change $b$ on top of it; you then realise that change 18.302 + $a$ was incorrect. Mercurial lets you <quote>back out</quote> 18.303 + an entire changeset automatically, and building blocks that let 18.304 + you reverse part of a changeset by hand.</para> 18.305 + 18.306 + <para>Before you read this section, here's something to keep in 18.307 + mind: the <command role="hg-cmd">hg backout</command> command 18.308 + undoes changes by <emphasis>adding</emphasis> history, not by 18.309 + modifying or erasing it. It's the right tool to use if you're 18.310 + fixing bugs, but not if you're trying to undo some change that 18.311 + has catastrophic consequences. To deal with those, see section 18.312 + <xref linkend="sec:undo:aaaiiieee"/>.</para> 18.313 + 18.314 + <sect2> 18.315 + <title>Backing out a changeset</title> 18.316 + 18.317 + <para>The <command role="hg-cmd">hg backout</command> command 18.318 + lets you <quote>undo</quote> the effects of an entire 18.319 + changeset in an automated fashion. Because Mercurial's 18.320 + history is immutable, this command <emphasis>does 18.321 + not</emphasis> get rid of the changeset you want to undo. 18.322 + Instead, it creates a new changeset that 18.323 + <emphasis>reverses</emphasis> the effect of the to-be-undone 18.324 + changeset.</para> 18.325 + 18.326 + <para>The operation of the <command role="hg-cmd">hg 18.327 + backout</command> command is a little intricate, so let's 18.328 + illustrate it with some examples. First, we'll create a 18.329 + repository with some simple changes.</para> 18.330 + 18.331 + &interaction.backout.init; 18.332 + 18.333 + <para>The <command role="hg-cmd">hg backout</command> command 18.334 + takes a single changeset ID as its argument; this is the 18.335 + changeset to back out. Normally, <command role="hg-cmd">hg 18.336 + backout</command> will drop you into a text editor to write 18.337 + a commit message, so you can record why you're backing the 18.338 + change out. In this example, we provide a commit message on 18.339 + the command line using the <option 18.340 + role="hg-opt-backout">-m</option> option.</para> 18.341 + 18.342 + </sect2> 18.343 + <sect2> 18.344 + <title>Backing out the tip changeset</title> 18.345 + 18.346 + <para>We're going to start by backing out the last changeset we 18.347 + committed.</para> 18.348 + 18.349 + &interaction.backout.simple; 18.350 + 18.351 + <para>You can see that the second line from 18.352 + <filename>myfile</filename> is no longer present. Taking a 18.353 + look at the output of <command role="hg-cmd">hg log</command> 18.354 + gives us an idea of what the <command role="hg-cmd">hg 18.355 + backout</command> command has done. 18.356 + &interaction.backout.simple.log; Notice that the new changeset 18.357 + that <command role="hg-cmd">hg backout</command> has created 18.358 + is a child of the changeset we backed out. It's easier to see 18.359 + this in figure <xref 18.360 + linkend="fig:undo:backout"/>, which presents a graphical 18.361 + view of the change history. As you can see, the history is 18.362 + nice and linear.</para> 18.363 + 18.364 + <informalfigure id="fig:undo:backout"> 18.365 + <mediaobject><imageobject><imagedata 18.366 + fileref="undo-simple"/></imageobject><textobject><phrase>XXX 18.367 + add text</phrase></textobject><caption><para>Backing out 18.368 + a change using the <command role="hg-cmd">hg 18.369 + backout</command> 18.370 + command</para></caption></mediaobject> 18.371 + 18.372 + </informalfigure> 18.373 + 18.374 + </sect2> 18.375 + <sect2> 18.376 + <title>Backing out a non-tip change</title> 18.377 + 18.378 + <para>If you want to back out a change other than the last one 18.379 + you committed, pass the <option 18.380 + role="hg-opt-backout">--merge</option> option to the 18.381 + <command role="hg-cmd">hg backout</command> command.</para> 18.382 + 18.383 + &interaction.backout.non-tip.clone; 18.384 + 18.385 + <para>This makes backing out any changeset a 18.386 + <quote>one-shot</quote> operation that's usually simple and 18.387 + fast.</para> 18.388 + 18.389 + &interaction.backout.non-tip.backout; 18.390 + 18.391 + <para>If you take a look at the contents of 18.392 + <filename>myfile</filename> after the backout finishes, you'll 18.393 + see that the first and third changes are present, but not the 18.394 + second.</para> 18.395 + 18.396 + &interaction.backout.non-tip.cat; 18.397 + 18.398 + <para>As the graphical history in figure <xref 18.399 + linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial 18.400 + actually commits <emphasis>two</emphasis> changes in this kind 18.401 + of situation (the box-shaped nodes are the ones that Mercurial 18.402 + commits automatically). Before Mercurial begins the backout 18.403 + process, it first remembers what the current parent of the 18.404 + working directory is. It then backs out the target changeset, 18.405 + and commits that as a changeset. Finally, it merges back to 18.406 + the previous parent of the working directory, and commits the 18.407 + result of the merge.</para> 18.408 + 18.409 + <para>% TODO: to me it looks like mercurial doesn't commit the 18.410 + second merge automatically!</para> 18.411 + 18.412 + <informalfigure id="fig:undo:backout-non-tip"> 18.413 + <mediaobject><imageobject><imagedata 18.414 + fileref="undo-non-tip"/></imageobject><textobject><phrase>XXX 18.415 + add text</phrase></textobject><caption><para>Automated 18.416 + backout of a non-tip change using the <command 18.417 + role="hg-cmd">hg backout</command> 18.418 + command</para></caption></mediaobject> 18.419 + </informalfigure> 18.420 + 18.421 + <para>The result is that you end up <quote>back where you 18.422 + were</quote>, only with some extra history that undoes the 18.423 + effect of the changeset you wanted to back out.</para> 18.424 + 18.425 + <sect3> 18.426 + <title>Always use the <option 18.427 + role="hg-opt-backout">--merge</option> option</title> 18.428 + 18.429 + <para>In fact, since the <option 18.430 + role="hg-opt-backout">--merge</option> option will do the 18.431 + <quote>right thing</quote> whether or not the changeset 18.432 + you're backing out is the tip (i.e. it won't try to merge if 18.433 + it's backing out the tip, since there's no need), you should 18.434 + <emphasis>always</emphasis> use this option when you run the 18.435 + <command role="hg-cmd">hg backout</command> command.</para> 18.436 + 18.437 + </sect3> 18.438 + </sect2> 18.439 + <sect2> 18.440 + <title>Gaining more control of the backout process</title> 18.441 + 18.442 + <para>While I've recommended that you always use the <option 18.443 + role="hg-opt-backout">--merge</option> option when backing 18.444 + out a change, the <command role="hg-cmd">hg backout</command> 18.445 + command lets you decide how to merge a backout changeset. 18.446 + Taking control of the backout process by hand is something you 18.447 + will rarely need to do, but it can be useful to understand 18.448 + what the <command role="hg-cmd">hg backout</command> command 18.449 + is doing for you automatically. To illustrate this, let's 18.450 + clone our first repository, but omit the backout change that 18.451 + it contains.</para> 18.452 + 18.453 + &interaction.backout.manual.clone; 18.454 + 18.455 + <para>As with our 18.456 + earlier example, We'll commit a third changeset, then back out 18.457 + its parent, and see what happens.</para> 18.458 + 18.459 + &interaction.backout.manual.backout; 18.460 + 18.461 + <para>Our new changeset is again a descendant of the changeset 18.462 + we backout out; it's thus a new head, <emphasis>not</emphasis> 18.463 + a descendant of the changeset that was the tip. The <command 18.464 + role="hg-cmd">hg backout</command> command was quite 18.465 + explicit in telling us this.</para> 18.466 + 18.467 + &interaction.backout.manual.log; 18.468 + 18.469 + <para>Again, it's easier to see what has happened by looking at 18.470 + a graph of the revision history, in figure <xref 18.471 + linkend="fig:undo:backout-manual"/>. This makes it clear 18.472 + that when we use <command role="hg-cmd">hg backout</command> 18.473 + to back out a change other than the tip, Mercurial adds a new 18.474 + head to the repository (the change it committed is 18.475 + box-shaped).</para> 18.476 + 18.477 + <informalfigure id="fig:undo:backout-manual"> 18.478 + <mediaobject><imageobject><imagedata 18.479 + fileref="undo-manual"/></imageobject><textobject><phrase>XXX 18.480 + add text</phrase></textobject><caption><para>Backing out 18.481 + a change using the <command role="hg-cmd">hg 18.482 + backout</command> 18.483 + command</para></caption></mediaobject> 18.484 + 18.485 + </informalfigure> 18.486 + 18.487 + <para>After the <command role="hg-cmd">hg backout</command> 18.488 + command has completed, it leaves the new 18.489 + <quote>backout</quote> changeset as the parent of the working 18.490 + directory.</para> 18.491 + 18.492 + &interaction.backout.manual.parents; 18.493 + 18.494 + <para>Now we have two isolated sets of changes.</para> 18.495 + 18.496 + &interaction.backout.manual.heads; 18.497 + 18.498 + <para>Let's think about what we expect to see as the contents of 18.499 + <filename>myfile</filename> now. The first change should be 18.500 + present, because we've never backed it out. The second change 18.501 + should be missing, as that's the change we backed out. Since 18.502 + the history graph shows the third change as a separate head, 18.503 + we <emphasis>don't</emphasis> expect to see the third change 18.504 + present in <filename>myfile</filename>.</para> 18.505 + 18.506 + &interaction.backout.manual.cat; 18.507 + 18.508 + <para>To get the third change back into the file, we just do a 18.509 + normal merge of our two heads.</para> 18.510 + 18.511 + &interaction.backout.manual.merge; 18.512 + 18.513 + <para>Afterwards, the graphical history of our repository looks 18.514 + like figure 18.515 + <xref linkend="fig:undo:backout-manual-merge"/>.</para> 18.516 + 18.517 + <informalfigure id="fig:undo:backout-manual-merge"> 18.518 + <mediaobject><imageobject><imagedata 18.519 + fileref="undo-manual-merge"/></imageobject><textobject><phrase>XXX 18.520 + add text</phrase></textobject><caption><para>Manually 18.521 + merging a backout change</para></caption></mediaobject> 18.522 + 18.523 + </informalfigure> 18.524 + 18.525 + </sect2> 18.526 + <sect2> 18.527 + <title>Why <command role="hg-cmd">hg backout</command> works as 18.528 + it does</title> 18.529 + 18.530 + <para>Here's a brief description of how the <command 18.531 + role="hg-cmd">hg backout</command> command works.</para> 18.532 + <orderedlist> 18.533 + <listitem><para>It ensures that the working directory is 18.534 + <quote>clean</quote>, i.e. that the output of <command 18.535 + role="hg-cmd">hg status</command> would be empty.</para> 18.536 + </listitem> 18.537 + <listitem><para>It remembers the current parent of the working 18.538 + directory. Let's call this changeset 18.539 + <literal>orig</literal></para> 18.540 + </listitem> 18.541 + <listitem><para>It does the equivalent of a <command 18.542 + role="hg-cmd">hg update</command> to sync the working 18.543 + directory to the changeset you want to back out. Let's 18.544 + call this changeset <literal>backout</literal></para> 18.545 + </listitem> 18.546 + <listitem><para>It finds the parent of that changeset. Let's 18.547 + call that changeset <literal>parent</literal>.</para> 18.548 + </listitem> 18.549 + <listitem><para>For each file that the 18.550 + <literal>backout</literal> changeset affected, it does the 18.551 + equivalent of a <command role="hg-cmd">hg revert -r 18.552 + parent</command> on that file, to restore it to the 18.553 + contents it had before that changeset was 18.554 + committed.</para> 18.555 + </listitem> 18.556 + <listitem><para>It commits the result as a new changeset. 18.557 + This changeset has <literal>backout</literal> as its 18.558 + parent.</para> 18.559 + </listitem> 18.560 + <listitem><para>If you specify <option 18.561 + role="hg-opt-backout">--merge</option> on the command 18.562 + line, it merges with <literal>orig</literal>, and commits 18.563 + the result of the merge.</para> 18.564 + </listitem></orderedlist> 18.565 + 18.566 + <para>An alternative way to implement the <command 18.567 + role="hg-cmd">hg backout</command> command would be to 18.568 + <command role="hg-cmd">hg export</command> the 18.569 + to-be-backed-out changeset as a diff, then use the <option 18.570 + role="cmd-opt-patch">--reverse</option> option to the 18.571 + <command>patch</command> command to reverse the effect of the 18.572 + change without fiddling with the working directory. This 18.573 + sounds much simpler, but it would not work nearly as 18.574 + well.</para> 18.575 + 18.576 + <para>The reason that <command role="hg-cmd">hg 18.577 + backout</command> does an update, a commit, a merge, and 18.578 + another commit is to give the merge machinery the best chance 18.579 + to do a good job when dealing with all the changes 18.580 + <emphasis>between</emphasis> the change you're backing out and 18.581 + the current tip.</para> 18.582 + 18.583 + <para>If you're backing out a changeset that's 100 revisions 18.584 + back in your project's history, the chances that the 18.585 + <command>patch</command> command will be able to apply a 18.586 + reverse diff cleanly are not good, because intervening changes 18.587 + are likely to have <quote>broken the context</quote> that 18.588 + <command>patch</command> uses to determine whether it can 18.589 + apply a patch (if this sounds like gibberish, see <xref 18.590 + linkend="sec:mq:patch"/> for a 18.591 + discussion of the <command>patch</command> command). Also, 18.592 + Mercurial's merge machinery will handle files and directories 18.593 + being renamed, permission changes, and modifications to binary 18.594 + files, none of which <command>patch</command> can deal 18.595 + with.</para> 18.596 + 18.597 + </sect2> 18.598 + </sect1> 18.599 + <sect1 id="sec:undo:aaaiiieee"> 18.600 + <title>Changes that should never have been</title> 18.601 + 18.602 + <para>Most of the time, the <command role="hg-cmd">hg 18.603 + backout</command> command is exactly what you need if you want 18.604 + to undo the effects of a change. It leaves a permanent record 18.605 + of exactly what you did, both when committing the original 18.606 + changeset and when you cleaned up after it.</para> 18.607 + 18.608 + <para>On rare occasions, though, you may find that you've 18.609 + committed a change that really should not be present in the 18.610 + repository at all. For example, it would be very unusual, and 18.611 + usually considered a mistake, to commit a software project's 18.612 + object files as well as its source files. Object files have 18.613 + almost no intrinsic value, and they're <emphasis>big</emphasis>, 18.614 + so they increase the size of the repository and the amount of 18.615 + time it takes to clone or pull changes.</para> 18.616 + 18.617 + <para>Before I discuss the options that you have if you commit a 18.618 + <quote>brown paper bag</quote> change (the kind that's so bad 18.619 + that you want to pull a brown paper bag over your head), let me 18.620 + first discuss some approaches that probably won't work.</para> 18.621 + 18.622 + <para>Since Mercurial treats history as accumulative&emdash;every 18.623 + change builds on top of all changes that preceded it&emdash;you 18.624 + generally can't just make disastrous changes disappear. The one 18.625 + exception is when you've just committed a change, and it hasn't 18.626 + been pushed or pulled into another repository. That's when you 18.627 + can safely use the <command role="hg-cmd">hg rollback</command> 18.628 + command, as I detailed in section <xref 18.629 + linkend="sec:undo:rollback"/>.</para> 18.630 + 18.631 + <para>After you've pushed a bad change to another repository, you 18.632 + <emphasis>could</emphasis> still use <command role="hg-cmd">hg 18.633 + rollback</command> to make your local copy of the change 18.634 + disappear, but it won't have the consequences you want. The 18.635 + change will still be present in the remote repository, so it 18.636 + will reappear in your local repository the next time you 18.637 + pull.</para> 18.638 + 18.639 + <para>If a situation like this arises, and you know which 18.640 + repositories your bad change has propagated into, you can 18.641 + <emphasis>try</emphasis> to get rid of the changeefrom 18.642 + <emphasis>every</emphasis> one of those repositories. This is, 18.643 + of course, not a satisfactory solution: if you miss even a 18.644 + single repository while you're expunging, the change is still 18.645 + <quote>in the wild</quote>, and could propagate further.</para> 18.646 + 18.647 + <para>If you've committed one or more changes 18.648 + <emphasis>after</emphasis> the change that you'd like to see 18.649 + disappear, your options are further reduced. Mercurial doesn't 18.650 + provide a way to <quote>punch a hole</quote> in history, leaving 18.651 + changesets intact.</para> 18.652 + 18.653 + <para>XXX This needs filling out. The 18.654 + <literal>hg-replay</literal> script in the 18.655 + <literal>examples</literal> directory works, but doesn't handle 18.656 + merge changesets. Kind of an important omission.</para> 18.657 + 18.658 + <sect2> 18.659 + <title>Protect yourself from <quote>escaped</quote> 18.660 + changes</title> 18.661 + 18.662 + <para>If you've committed some changes to your local repository 18.663 + and they've been pushed or pulled somewhere else, this isn't 18.664 + necessarily a disaster. You can protect yourself ahead of 18.665 + time against some classes of bad changeset. This is 18.666 + particularly easy if your team usually pulls changes from a 18.667 + central repository.</para> 18.668 + 18.669 + <para>By configuring some hooks on that repository to validate 18.670 + incoming changesets (see chapter <xref linkend="chap:hook"/>), 18.671 + you can 18.672 + automatically prevent some kinds of bad changeset from being 18.673 + pushed to the central repository at all. With such a 18.674 + configuration in place, some kinds of bad changeset will 18.675 + naturally tend to <quote>die out</quote> because they can't 18.676 + propagate into the central repository. Better yet, this 18.677 + happens without any need for explicit intervention.</para> 18.678 + 18.679 + <para>For instance, an incoming change hook that verifies that a 18.680 + changeset will actually compile can prevent people from 18.681 + inadvertantly <quote>breaking the build</quote>.</para> 18.682 + 18.683 + </sect2> 18.684 + </sect1> 18.685 + <sect1 id="sec:undo:bisect"> 18.686 + <title>Finding the source of a bug</title> 18.687 + 18.688 + <para>While it's all very well to be able to back out a changeset 18.689 + that introduced a bug, this requires that you know which 18.690 + changeset to back out. Mercurial provides an invaluable 18.691 + command, called <command role="hg-cmd">hg bisect</command>, that 18.692 + helps you to automate this process and accomplish it very 18.693 + efficiently.</para> 18.694 + 18.695 + <para>The idea behind the <command role="hg-cmd">hg 18.696 + bisect</command> command is that a changeset has introduced 18.697 + some change of behaviour that you can identify with a simple 18.698 + binary test. You don't know which piece of code introduced the 18.699 + change, but you know how to test for the presence of the bug. 18.700 + The <command role="hg-cmd">hg bisect</command> command uses your 18.701 + test to direct its search for the changeset that introduced the 18.702 + code that caused the bug.</para> 18.703 + 18.704 + <para>Here are a few scenarios to help you understand how you 18.705 + might apply this command.</para> 18.706 + <itemizedlist> 18.707 + <listitem><para>The most recent version of your software has a 18.708 + bug that you remember wasn't present a few weeks ago, but 18.709 + you don't know when it was introduced. Here, your binary 18.710 + test checks for the presence of that bug.</para> 18.711 + </listitem> 18.712 + <listitem><para>You fixed a bug in a rush, and now it's time to 18.713 + close the entry in your team's bug database. The bug 18.714 + database requires a changeset ID when you close an entry, 18.715 + but you don't remember which changeset you fixed the bug in. 18.716 + Once again, your binary test checks for the presence of the 18.717 + bug.</para> 18.718 + </listitem> 18.719 + <listitem><para>Your software works correctly, but runs 15% 18.720 + slower than the last time you measured it. You want to know 18.721 + which changeset introduced the performance regression. In 18.722 + this case, your binary test measures the performance of your 18.723 + software, to see whether it's <quote>fast</quote> or 18.724 + <quote>slow</quote>.</para> 18.725 + </listitem> 18.726 + <listitem><para>The sizes of the components of your project that 18.727 + you ship exploded recently, and you suspect that something 18.728 + changed in the way you build your project.</para> 18.729 + </listitem></itemizedlist> 18.730 + 18.731 + <para>From these examples, it should be clear that the <command 18.732 + role="hg-cmd">hg bisect</command> command is not useful only 18.733 + for finding the sources of bugs. You can use it to find any 18.734 + <quote>emergent property</quote> of a repository (anything that 18.735 + you can't find from a simple text search of the files in the 18.736 + tree) for which you can write a binary test.</para> 18.737 + 18.738 + <para>We'll introduce a little bit of terminology here, just to 18.739 + make it clear which parts of the search process are your 18.740 + responsibility, and which are Mercurial's. A 18.741 + <emphasis>test</emphasis> is something that 18.742 + <emphasis>you</emphasis> run when <command role="hg-cmd">hg 18.743 + bisect</command> chooses a changeset. A 18.744 + <emphasis>probe</emphasis> is what <command role="hg-cmd">hg 18.745 + bisect</command> runs to tell whether a revision is good. 18.746 + Finally, we'll use the word <quote>bisect</quote>, as both a 18.747 + noun and a verb, to stand in for the phrase <quote>search using 18.748 + the <command role="hg-cmd">hg bisect</command> 18.749 + command</quote>.</para> 18.750 + 18.751 + <para>One simple way to automate the searching process would be 18.752 + simply to probe every changeset. However, this scales poorly. 18.753 + If it took ten minutes to test a single changeset, and you had 18.754 + 10,000 changesets in your repository, the exhaustive approach 18.755 + would take on average 35 <emphasis>days</emphasis> to find the 18.756 + changeset that introduced a bug. Even if you knew that the bug 18.757 + was introduced by one of the last 500 changesets, and limited 18.758 + your search to those, you'd still be looking at over 40 hours to 18.759 + find the changeset that introduced your bug.</para> 18.760 + 18.761 + <para>What the <command role="hg-cmd">hg bisect</command> command 18.762 + does is use its knowledge of the <quote>shape</quote> of your 18.763 + project's revision history to perform a search in time 18.764 + proportional to the <emphasis>logarithm</emphasis> of the number 18.765 + of changesets to check (the kind of search it performs is called 18.766 + a dichotomic search). With this approach, searching through 18.767 + 10,000 changesets will take less than three hours, even at ten 18.768 + minutes per test (the search will require about 14 tests). 18.769 + Limit your search to the last hundred changesets, and it will 18.770 + take only about an hour (roughly seven tests).</para> 18.771 + 18.772 + <para>The <command role="hg-cmd">hg bisect</command> command is 18.773 + aware of the <quote>branchy</quote> nature of a Mercurial 18.774 + project's revision history, so it has no problems dealing with 18.775 + branches, merges, or multiple heads in a repository. It can 18.776 + prune entire branches of history with a single probe, which is 18.777 + how it operates so efficiently.</para> 18.778 + 18.779 + <sect2> 18.780 + <title>Using the <command role="hg-cmd">hg bisect</command> 18.781 + command</title> 18.782 + 18.783 + <para>Here's an example of <command role="hg-cmd">hg 18.784 + bisect</command> in action.</para> 18.785 + 18.786 + <note> 18.787 + <para> In versions 0.9.5 and earlier of Mercurial, <command 18.788 + role="hg-cmd">hg bisect</command> was not a core command: 18.789 + it was distributed with Mercurial as an extension. This 18.790 + section describes the built-in command, not the old 18.791 + extension.</para> 18.792 + </note> 18.793 + 18.794 + <para>Now let's create a repository, so that we can try out the 18.795 + <command role="hg-cmd">hg bisect</command> command in 18.796 + isolation.</para> 18.797 + 18.798 + &interaction.bisect.init; 18.799 + 18.800 + <para>We'll simulate a project that has a bug in it in a 18.801 + simple-minded way: create trivial changes in a loop, and 18.802 + nominate one specific change that will have the 18.803 + <quote>bug</quote>. This loop creates 35 changesets, each 18.804 + adding a single file to the repository. We'll represent our 18.805 + <quote>bug</quote> with a file that contains the text <quote>i 18.806 + have a gub</quote>.</para> 18.807 + 18.808 + &interaction.bisect.commits; 18.809 + 18.810 + <para>The next thing that we'd like to do is figure out how to 18.811 + use the <command role="hg-cmd">hg bisect</command> command. 18.812 + We can use Mercurial's normal built-in help mechanism for 18.813 + this.</para> 18.814 + 18.815 + &interaction.bisect.help; 18.816 + 18.817 + <para>The <command role="hg-cmd">hg bisect</command> command 18.818 + works in steps. Each step proceeds as follows.</para> 18.819 + <orderedlist> 18.820 + <listitem><para>You run your binary test.</para> 18.821 + <itemizedlist> 18.822 + <listitem><para>If the test succeeded, you tell <command 18.823 + role="hg-cmd">hg bisect</command> by running the 18.824 + <command role="hg-cmd">hg bisect good</command> 18.825 + command.</para> 18.826 + </listitem> 18.827 + <listitem><para>If it failed, run the <command 18.828 + role="hg-cmd">hg bisect bad</command> 18.829 + command.</para></listitem></itemizedlist> 18.830 + </listitem> 18.831 + <listitem><para>The command uses your information to decide 18.832 + which changeset to test next.</para> 18.833 + </listitem> 18.834 + <listitem><para>It updates the working directory to that 18.835 + changeset, and the process begins again.</para> 18.836 + </listitem></orderedlist> 18.837 + <para>The process ends when <command role="hg-cmd">hg 18.838 + bisect</command> identifies a unique changeset that marks 18.839 + the point where your test transitioned from 18.840 + <quote>succeeding</quote> to <quote>failing</quote>.</para> 18.841 + 18.842 + <para>To start the search, we must run the <command 18.843 + role="hg-cmd">hg bisect --reset</command> command.</para> 18.844 + 18.845 + &interaction.bisect.search.init; 18.846 + 18.847 + <para>In our case, the binary test we use is simple: we check to 18.848 + see if any file in the repository contains the string <quote>i 18.849 + have a gub</quote>. If it does, this changeset contains the 18.850 + change that <quote>caused the bug</quote>. By convention, a 18.851 + changeset that has the property we're searching for is 18.852 + <quote>bad</quote>, while one that doesn't is 18.853 + <quote>good</quote>.</para> 18.854 + 18.855 + <para>Most of the time, the revision to which the working 18.856 + directory is synced (usually the tip) already exhibits the 18.857 + problem introduced by the buggy change, so we'll mark it as 18.858 + <quote>bad</quote>.</para> 18.859 + 18.860 + &interaction.bisect.search.bad-init; 18.861 + 18.862 + <para>Our next task is to nominate a changeset that we know 18.863 + <emphasis>doesn't</emphasis> have the bug; the <command 18.864 + role="hg-cmd">hg bisect</command> command will 18.865 + <quote>bracket</quote> its search between the first pair of 18.866 + good and bad changesets. In our case, we know that revision 18.867 + 10 didn't have the bug. (I'll have more words about choosing 18.868 + the first <quote>good</quote> changeset later.)</para> 18.869 + 18.870 + &interaction.bisect.search.good-init; 18.871 + 18.872 + <para>Notice that this command printed some output.</para> 18.873 + <itemizedlist> 18.874 + <listitem><para>It told us how many changesets it must 18.875 + consider before it can identify the one that introduced 18.876 + the bug, and how many tests that will require.</para> 18.877 + </listitem> 18.878 + <listitem><para>It updated the working directory to the next 18.879 + changeset to test, and told us which changeset it's 18.880 + testing.</para> 18.881 + </listitem></itemizedlist> 18.882 + 18.883 + <para>We now run our test in the working directory. We use the 18.884 + <command>grep</command> command to see if our 18.885 + <quote>bad</quote> file is present in the working directory. 18.886 + If it is, this revision is bad; if not, this revision is good. 18.887 + &interaction.bisect.search.step1;</para> 18.888 + 18.889 + <para>This test looks like a perfect candidate for automation, 18.890 + so let's turn it into a shell function.</para> 18.891 + &interaction.bisect.search.mytest; 18.892 + 18.893 + <para>We can now run an entire test step with a single command, 18.894 + <literal>mytest</literal>.</para> 18.895 + 18.896 + &interaction.bisect.search.step2; 18.897 + 18.898 + <para>A few more invocations of our canned test step command, 18.899 + and we're done.</para> 18.900 + 18.901 + &interaction.bisect.search.rest; 18.902 + 18.903 + <para>Even though we had 40 changesets to search through, the 18.904 + <command role="hg-cmd">hg bisect</command> command let us find 18.905 + the changeset that introduced our <quote>bug</quote> with only 18.906 + five tests. Because the number of tests that the <command 18.907 + role="hg-cmd">hg bisect</command> command performs grows 18.908 + logarithmically with the number of changesets to search, the 18.909 + advantage that it has over the <quote>brute force</quote> 18.910 + search approach increases with every changeset you add.</para> 18.911 + 18.912 + </sect2> 18.913 + <sect2> 18.914 + <title>Cleaning up after your search</title> 18.915 + 18.916 + <para>When you're finished using the <command role="hg-cmd">hg 18.917 + bisect</command> command in a repository, you can use the 18.918 + <command role="hg-cmd">hg bisect reset</command> command to 18.919 + drop the information it was using to drive your search. The 18.920 + command doesn't use much space, so it doesn't matter if you 18.921 + forget to run this command. However, <command 18.922 + role="hg-cmd">hg bisect</command> won't let you start a new 18.923 + search in that repository until you do a <command 18.924 + role="hg-cmd">hg bisect reset</command>.</para> 18.925 + 18.926 + &interaction.bisect.search.reset; 18.927 + 18.928 + </sect2> 18.929 + </sect1> 18.930 + <sect1> 18.931 + <title>Tips for finding bugs effectively</title> 18.932 + 18.933 + <sect2> 18.934 + <title>Give consistent input</title> 18.935 + 18.936 + <para>The <command role="hg-cmd">hg bisect</command> command 18.937 + requires that you correctly report the result of every test 18.938 + you perform. If you tell it that a test failed when it really 18.939 + succeeded, it <emphasis>might</emphasis> be able to detect the 18.940 + inconsistency. If it can identify an inconsistency in your 18.941 + reports, it will tell you that a particular changeset is both 18.942 + good and bad. However, it can't do this perfectly; it's about 18.943 + as likely to report the wrong changeset as the source of the 18.944 + bug.</para> 18.945 + 18.946 + </sect2> 18.947 + <sect2> 18.948 + <title>Automate as much as possible</title> 18.949 + 18.950 + <para>When I started using the <command role="hg-cmd">hg 18.951 + bisect</command> command, I tried a few times to run my 18.952 + tests by hand, on the command line. This is an approach that 18.953 + I, at least, am not suited to. After a few tries, I found 18.954 + that I was making enough mistakes that I was having to restart 18.955 + my searches several times before finally getting correct 18.956 + results.</para> 18.957 + 18.958 + <para>My initial problems with driving the <command 18.959 + role="hg-cmd">hg bisect</command> command by hand occurred 18.960 + even with simple searches on small repositories; if the 18.961 + problem you're looking for is more subtle, or the number of 18.962 + tests that <command role="hg-cmd">hg bisect</command> must 18.963 + perform increases, the likelihood of operator error ruining 18.964 + the search is much higher. Once I started automating my 18.965 + tests, I had much better results.</para> 18.966 + 18.967 + <para>The key to automated testing is twofold:</para> 18.968 + <itemizedlist> 18.969 + <listitem><para>always test for the same symptom, and</para> 18.970 + </listitem> 18.971 + <listitem><para>always feed consistent input to the <command 18.972 + role="hg-cmd">hg bisect</command> command.</para> 18.973 + </listitem></itemizedlist> 18.974 + <para>In my tutorial example above, the <command>grep</command> 18.975 + command tests for the symptom, and the <literal>if</literal> 18.976 + statement takes the result of this check and ensures that we 18.977 + always feed the same input to the <command role="hg-cmd">hg 18.978 + bisect</command> command. The <literal>mytest</literal> 18.979 + function marries these together in a reproducible way, so that 18.980 + every test is uniform and consistent.</para> 18.981 + 18.982 + </sect2> 18.983 + <sect2> 18.984 + <title>Check your results</title> 18.985 + 18.986 + <para>Because the output of a <command role="hg-cmd">hg 18.987 + bisect</command> search is only as good as the input you 18.988 + give it, don't take the changeset it reports as the absolute 18.989 + truth. A simple way to cross-check its report is to manually 18.990 + run your test at each of the following changesets:</para> 18.991 + <itemizedlist> 18.992 + <listitem><para>The changeset that it reports as the first bad 18.993 + revision. Your test should still report this as 18.994 + bad.</para> 18.995 + </listitem> 18.996 + <listitem><para>The parent of that changeset (either parent, 18.997 + if it's a merge). Your test should report this changeset 18.998 + as good.</para> 18.999 + </listitem> 18.1000 + <listitem><para>A child of that changeset. Your test should 18.1001 + report this changeset as bad.</para> 18.1002 + </listitem></itemizedlist> 18.1003 + 18.1004 + </sect2> 18.1005 + <sect2> 18.1006 + <title>Beware interference between bugs</title> 18.1007 + 18.1008 + <para>It's possible that your search for one bug could be 18.1009 + disrupted by the presence of another. For example, let's say 18.1010 + your software crashes at revision 100, and worked correctly at 18.1011 + revision 50. Unknown to you, someone else introduced a 18.1012 + different crashing bug at revision 60, and fixed it at 18.1013 + revision 80. This could distort your results in one of 18.1014 + several ways.</para> 18.1015 + 18.1016 + <para>It is possible that this other bug completely 18.1017 + <quote>masks</quote> yours, which is to say that it occurs 18.1018 + before your bug has a chance to manifest itself. If you can't 18.1019 + avoid that other bug (for example, it prevents your project 18.1020 + from building), and so can't tell whether your bug is present 18.1021 + in a particular changeset, the <command role="hg-cmd">hg 18.1022 + bisect</command> command cannot help you directly. Instead, 18.1023 + you can mark a changeset as untested by running <command 18.1024 + role="hg-cmd">hg bisect --skip</command>.</para> 18.1025 + 18.1026 + <para>A different problem could arise if your test for a bug's 18.1027 + presence is not specific enough. If you check for <quote>my 18.1028 + program crashes</quote>, then both your crashing bug and an 18.1029 + unrelated crashing bug that masks it will look like the same 18.1030 + thing, and mislead <command role="hg-cmd">hg 18.1031 + bisect</command>.</para> 18.1032 + 18.1033 + <para>Another useful situation in which to use <command 18.1034 + role="hg-cmd">hg bisect --skip</command> is if you can't 18.1035 + test a revision because your project was in a broken and hence 18.1036 + untestable state at that revision, perhaps because someone 18.1037 + checked in a change that prevented the project from 18.1038 + building.</para> 18.1039 + 18.1040 + </sect2> 18.1041 + <sect2> 18.1042 + <title>Bracket your search lazily</title> 18.1043 + 18.1044 + <para>Choosing the first <quote>good</quote> and 18.1045 + <quote>bad</quote> changesets that will mark the end points of 18.1046 + your search is often easy, but it bears a little discussion 18.1047 + nevertheless. From the perspective of <command 18.1048 + role="hg-cmd">hg bisect</command>, the <quote>newest</quote> 18.1049 + changeset is conventionally <quote>bad</quote>, and the older 18.1050 + changeset is <quote>good</quote>.</para> 18.1051 + 18.1052 + <para>If you're having trouble remembering when a suitable 18.1053 + <quote>good</quote> change was, so that you can tell <command 18.1054 + role="hg-cmd">hg bisect</command>, you could do worse than 18.1055 + testing changesets at random. Just remember to eliminate 18.1056 + contenders that can't possibly exhibit the bug (perhaps 18.1057 + because the feature with the bug isn't present yet) and those 18.1058 + where another problem masks the bug (as I discussed 18.1059 + above).</para> 18.1060 + 18.1061 + <para>Even if you end up <quote>early</quote> by thousands of 18.1062 + changesets or months of history, you will only add a handful 18.1063 + of tests to the total number that <command role="hg-cmd">hg 18.1064 + bisect</command> must perform, thanks to its logarithmic 18.1065 + behaviour.</para> 18.1066 + 18.1067 + </sect2> 18.1068 + </sect1> 18.1069 +</chapter> 18.1070 + 18.1071 +<!-- 18.1072 +local variables: 18.1073 +sgml-parent-document: ("00book.xml" "book" "chapter") 18.1074 +end: 18.1075 +-->
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/en/ch09-hook.xml Thu Mar 19 20:54:12 2009 -0700 19.3 @@ -0,0 +1,2037 @@ 19.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 19.5 + 19.6 +<chapter id="chap:hook"> 19.7 + <?dbhtml filename="handling-repository-events-with-hooks.html"?> 19.8 + <title>Handling repository events with hooks</title> 19.9 + 19.10 + <para>Mercurial offers a powerful mechanism to let you perform 19.11 + automated actions in response to events that occur in a 19.12 + repository. In some cases, you can even control Mercurial's 19.13 + response to those events.</para> 19.14 + 19.15 + <para>The name Mercurial uses for one of these actions is a 19.16 + <emphasis>hook</emphasis>. Hooks are called 19.17 + <quote>triggers</quote> in some revision control systems, but the 19.18 + two names refer to the same idea.</para> 19.19 + 19.20 + <sect1> 19.21 + <title>An overview of hooks in Mercurial</title> 19.22 + 19.23 + <para>Here is a brief list of the hooks that Mercurial supports. 19.24 + We will revisit each of these hooks in more detail later, in 19.25 + section <xref linkend="sec:hook:ref"/>.</para> 19.26 + 19.27 + <itemizedlist> 19.28 + <listitem><para><literal role="hook">changegroup</literal>: This 19.29 + is run after a group of changesets has been brought into the 19.30 + repository from elsewhere.</para> 19.31 + </listitem> 19.32 + <listitem><para><literal role="hook">commit</literal>: This is 19.33 + run after a new changeset has been created in the local 19.34 + repository.</para> 19.35 + </listitem> 19.36 + <listitem><para><literal role="hook">incoming</literal>: This is 19.37 + run once for each new changeset that is brought into the 19.38 + repository from elsewhere. Notice the difference from 19.39 + <literal role="hook">changegroup</literal>, which is run 19.40 + once per <emphasis>group</emphasis> of changesets brought 19.41 + in.</para> 19.42 + </listitem> 19.43 + <listitem><para><literal role="hook">outgoing</literal>: This is 19.44 + run after a group of changesets has been transmitted from 19.45 + this repository.</para> 19.46 + </listitem> 19.47 + <listitem><para><literal role="hook">prechangegroup</literal>: 19.48 + This is run before starting to bring a group of changesets 19.49 + into the repository. 19.50 + </para> 19.51 + </listitem> 19.52 + <listitem><para><literal role="hook">precommit</literal>: 19.53 + Controlling. This is run before starting a commit. 19.54 + </para> 19.55 + </listitem> 19.56 + <listitem><para><literal role="hook">preoutgoing</literal>: 19.57 + Controlling. This is run before starting to transmit a group 19.58 + of changesets from this repository. 19.59 + </para> 19.60 + </listitem> 19.61 + <listitem><para><literal role="hook">pretag</literal>: 19.62 + Controlling. This is run before creating a tag. 19.63 + </para> 19.64 + </listitem> 19.65 + <listitem><para><literal 19.66 + role="hook">pretxnchangegroup</literal>: Controlling. This 19.67 + is run after a group of changesets has been brought into the 19.68 + local repository from another, but before the transaction 19.69 + completes that will make the changes permanent in the 19.70 + repository. 19.71 + </para> 19.72 + </listitem> 19.73 + <listitem><para><literal role="hook">pretxncommit</literal>: 19.74 + Controlling. This is run after a new changeset has been 19.75 + created in the local repository, but before the transaction 19.76 + completes that will make it permanent. 19.77 + </para> 19.78 + </listitem> 19.79 + <listitem><para><literal role="hook">preupdate</literal>: 19.80 + Controlling. This is run before starting an update or merge 19.81 + of the working directory. 19.82 + </para> 19.83 + </listitem> 19.84 + <listitem><para><literal role="hook">tag</literal>: This is run 19.85 + after a tag is created. 19.86 + </para> 19.87 + </listitem> 19.88 + <listitem><para><literal role="hook">update</literal>: This is 19.89 + run after an update or merge of the working directory has 19.90 + finished. 19.91 + </para> 19.92 + </listitem></itemizedlist> 19.93 + <para>Each of the hooks whose description begins with the word 19.94 + <quote>Controlling</quote> has the ability to determine whether 19.95 + an activity can proceed. If the hook succeeds, the activity may 19.96 + proceed; if it fails, the activity is either not permitted or 19.97 + undone, depending on the hook. 19.98 + </para> 19.99 + 19.100 + </sect1> 19.101 + <sect1> 19.102 + <title>Hooks and security</title> 19.103 + 19.104 + <sect2> 19.105 + <title>Hooks are run with your privileges</title> 19.106 + 19.107 + <para>When you run a Mercurial command in a repository, and the 19.108 + command causes a hook to run, that hook runs on 19.109 + <emphasis>your</emphasis> system, under 19.110 + <emphasis>your</emphasis> user account, with 19.111 + <emphasis>your</emphasis> privilege level. Since hooks are 19.112 + arbitrary pieces of executable code, you should treat them 19.113 + with an appropriate level of suspicion. Do not install a hook 19.114 + unless you are confident that you know who created it and what 19.115 + it does. 19.116 + </para> 19.117 + 19.118 + <para>In some cases, you may be exposed to hooks that you did 19.119 + not install yourself. If you work with Mercurial on an 19.120 + unfamiliar system, Mercurial will run hooks defined in that 19.121 + system's global <filename role="special">~/.hgrc</filename> 19.122 + file. 19.123 + </para> 19.124 + 19.125 + <para>If you are working with a repository owned by another 19.126 + user, Mercurial can run hooks defined in that user's 19.127 + repository, but it will still run them as <quote>you</quote>. 19.128 + For example, if you <command role="hg-cmd">hg pull</command> 19.129 + from that repository, and its <filename 19.130 + role="special">.hg/hgrc</filename> defines a local <literal 19.131 + role="hook">outgoing</literal> hook, that hook will run 19.132 + under your user account, even though you don't own that 19.133 + repository. 19.134 + </para> 19.135 + 19.136 + <note> 19.137 + <para> This only applies if you are pulling from a repository 19.138 + on a local or network filesystem. If you're pulling over 19.139 + http or ssh, any <literal role="hook">outgoing</literal> 19.140 + hook will run under whatever account is executing the server 19.141 + process, on the server. 19.142 + </para> 19.143 + </note> 19.144 + 19.145 + <para>XXX To see what hooks are defined in a repository, use the 19.146 + <command role="hg-cmd">hg config hooks</command> command. If 19.147 + you are working in one repository, but talking to another that 19.148 + you do not own (e.g. using <command role="hg-cmd">hg 19.149 + pull</command> or <command role="hg-cmd">hg 19.150 + incoming</command>), remember that it is the other 19.151 + repository's hooks you should be checking, not your own. 19.152 + </para> 19.153 + 19.154 + </sect2> 19.155 + <sect2> 19.156 + <title>Hooks do not propagate</title> 19.157 + 19.158 + <para>In Mercurial, hooks are not revision controlled, and do 19.159 + not propagate when you clone, or pull from, a repository. The 19.160 + reason for this is simple: a hook is a completely arbitrary 19.161 + piece of executable code. It runs under your user identity, 19.162 + with your privilege level, on your machine. 19.163 + </para> 19.164 + 19.165 + <para>It would be extremely reckless for any distributed 19.166 + revision control system to implement revision-controlled 19.167 + hooks, as this would offer an easily exploitable way to 19.168 + subvert the accounts of users of the revision control system. 19.169 + </para> 19.170 + 19.171 + <para>Since Mercurial does not propagate hooks, if you are 19.172 + collaborating with other people on a common project, you 19.173 + should not assume that they are using the same Mercurial hooks 19.174 + as you are, or that theirs are correctly configured. You 19.175 + should document the hooks you expect people to use. 19.176 + </para> 19.177 + 19.178 + <para>In a corporate intranet, this is somewhat easier to 19.179 + control, as you can for example provide a 19.180 + <quote>standard</quote> installation of Mercurial on an NFS 19.181 + filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will 19.182 + see. However, this too has its limits; see below. 19.183 + </para> 19.184 + 19.185 + </sect2> 19.186 + <sect2> 19.187 + <title>Hooks can be overridden</title> 19.188 + 19.189 + <para>Mercurial allows you to override a hook definition by 19.190 + redefining the hook. You can disable it by setting its value 19.191 + to the empty string, or change its behaviour as you wish. 19.192 + </para> 19.193 + 19.194 + <para>If you deploy a system- or site-wide <filename 19.195 + role="special">~/.hgrc</filename> file that defines some 19.196 + hooks, you should thus understand that your users can disable 19.197 + or override those hooks. 19.198 + </para> 19.199 + 19.200 + </sect2> 19.201 + <sect2> 19.202 + <title>Ensuring that critical hooks are run</title> 19.203 + 19.204 + <para>Sometimes you may want to enforce a policy that you do not 19.205 + want others to be able to work around. For example, you may 19.206 + have a requirement that every changeset must pass a rigorous 19.207 + set of tests. Defining this requirement via a hook in a 19.208 + site-wide <filename role="special">~/.hgrc</filename> won't 19.209 + work for remote users on laptops, and of course local users 19.210 + can subvert it at will by overriding the hook. 19.211 + </para> 19.212 + 19.213 + <para>Instead, you can set up your policies for use of Mercurial 19.214 + so that people are expected to propagate changes through a 19.215 + well-known <quote>canonical</quote> server that you have 19.216 + locked down and configured appropriately. 19.217 + </para> 19.218 + 19.219 + <para>One way to do this is via a combination of social 19.220 + engineering and technology. Set up a restricted-access 19.221 + account; users can push changes over the network to 19.222 + repositories managed by this account, but they cannot log into 19.223 + the account and run normal shell commands. In this scenario, 19.224 + a user can commit a changeset that contains any old garbage 19.225 + they want. 19.226 + </para> 19.227 + 19.228 + <para>When someone pushes a changeset to the server that 19.229 + everyone pulls from, the server will test the changeset before 19.230 + it accepts it as permanent, and reject it if it fails to pass 19.231 + the test suite. If people only pull changes from this 19.232 + filtering server, it will serve to ensure that all changes 19.233 + that people pull have been automatically vetted. 19.234 + </para> 19.235 + 19.236 + </sect2> 19.237 + </sect1> 19.238 + <sect1> 19.239 + <title>Care with <literal>pretxn</literal> hooks in a 19.240 + shared-access repository</title> 19.241 + 19.242 + <para>If you want to use hooks to do some automated work in a 19.243 + repository that a number of people have shared access to, you 19.244 + need to be careful in how you do this. 19.245 + </para> 19.246 + 19.247 + <para>Mercurial only locks a repository when it is writing to the 19.248 + repository, and only the parts of Mercurial that write to the 19.249 + repository pay attention to locks. Write locks are necessary to 19.250 + prevent multiple simultaneous writers from scribbling on each 19.251 + other's work, corrupting the repository. 19.252 + </para> 19.253 + 19.254 + <para>Because Mercurial is careful with the order in which it 19.255 + reads and writes data, it does not need to acquire a lock when 19.256 + it wants to read data from the repository. The parts of 19.257 + Mercurial that read from the repository never pay attention to 19.258 + locks. This lockless reading scheme greatly increases 19.259 + performance and concurrency. 19.260 + </para> 19.261 + 19.262 + <para>With great performance comes a trade-off, though, one which 19.263 + has the potential to cause you trouble unless you're aware of 19.264 + it. To describe this requires a little detail about how 19.265 + Mercurial adds changesets to a repository and reads those 19.266 + changes. 19.267 + </para> 19.268 + 19.269 + <para>When Mercurial <emphasis>writes</emphasis> metadata, it 19.270 + writes it straight into the destination file. It writes file 19.271 + data first, then manifest data (which contains pointers to the 19.272 + new file data), then changelog data (which contains pointers to 19.273 + the new manifest data). Before the first write to each file, it 19.274 + stores a record of where the end of the file was in its 19.275 + transaction log. If the transaction must be rolled back, 19.276 + Mercurial simply truncates each file back to the size it was 19.277 + before the transaction began. 19.278 + </para> 19.279 + 19.280 + <para>When Mercurial <emphasis>reads</emphasis> metadata, it reads 19.281 + the changelog first, then everything else. Since a reader will 19.282 + only access parts of the manifest or file metadata that it can 19.283 + see in the changelog, it can never see partially written data. 19.284 + </para> 19.285 + 19.286 + <para>Some controlling hooks (<literal 19.287 + role="hook">pretxncommit</literal> and <literal 19.288 + role="hook">pretxnchangegroup</literal>) run when a 19.289 + transaction is almost complete. All of the metadata has been 19.290 + written, but Mercurial can still roll the transaction back and 19.291 + cause the newly-written data to disappear. 19.292 + </para> 19.293 + 19.294 + <para>If one of these hooks runs for long, it opens a window of 19.295 + time during which a reader can see the metadata for changesets 19.296 + that are not yet permanent, and should not be thought of as 19.297 + <quote>really there</quote>. The longer the hook runs, the 19.298 + longer that window is open. 19.299 + </para> 19.300 + 19.301 + <sect2> 19.302 + <title>The problem illustrated</title> 19.303 + 19.304 + <para>In principle, a good use for the <literal 19.305 + role="hook">pretxnchangegroup</literal> hook would be to 19.306 + automatically build and test incoming changes before they are 19.307 + accepted into a central repository. This could let you 19.308 + guarantee that nobody can push changes to this repository that 19.309 + <quote>break the build</quote>. But if a client can pull 19.310 + changes while they're being tested, the usefulness of the test 19.311 + is zero; an unsuspecting someone can pull untested changes, 19.312 + potentially breaking their build. 19.313 + </para> 19.314 + 19.315 + <para>The safest technological answer to this challenge is to 19.316 + set up such a <quote>gatekeeper</quote> repository as 19.317 + <emphasis>unidirectional</emphasis>. Let it take changes 19.318 + pushed in from the outside, but do not allow anyone to pull 19.319 + changes from it (use the <literal 19.320 + role="hook">preoutgoing</literal> hook to lock it down). 19.321 + Configure a <literal role="hook">changegroup</literal> hook so 19.322 + that if a build or test succeeds, the hook will push the new 19.323 + changes out to another repository that people 19.324 + <emphasis>can</emphasis> pull from. 19.325 + </para> 19.326 + 19.327 + <para>In practice, putting a centralised bottleneck like this in 19.328 + place is not often a good idea, and transaction visibility has 19.329 + nothing to do with the problem. As the size of a 19.330 + project&emdash;and the time it takes to build and 19.331 + test&emdash;grows, you rapidly run into a wall with this 19.332 + <quote>try before you buy</quote> approach, where you have 19.333 + more changesets to test than time in which to deal with them. 19.334 + The inevitable result is frustration on the part of all 19.335 + involved. 19.336 + </para> 19.337 + 19.338 + <para>An approach that scales better is to get people to build 19.339 + and test before they push, then run automated builds and tests 19.340 + centrally <emphasis>after</emphasis> a push, to be sure all is 19.341 + well. The advantage of this approach is that it does not 19.342 + impose a limit on the rate at which the repository can accept 19.343 + changes. 19.344 + </para> 19.345 + 19.346 + </sect2> 19.347 + </sect1> 19.348 + <sect1 id="sec:hook:simple"> 19.349 + <title>A short tutorial on using hooks</title> 19.350 + 19.351 + <para>It is easy to write a Mercurial hook. Let's start with a 19.352 + hook that runs when you finish a <command role="hg-cmd">hg 19.353 + commit</command>, and simply prints the hash of the changeset 19.354 + you just created. The hook is called <literal 19.355 + role="hook">commit</literal>. 19.356 + </para> 19.357 + 19.358 + <para>All hooks follow the pattern in this example.</para> 19.359 + 19.360 +&interaction.hook.simple.init; 19.361 + 19.362 + <para>You add an entry to the <literal 19.363 + role="rc-hooks">hooks</literal> section of your <filename 19.364 + role="special">~/.hgrc</filename>. On the left is the name of 19.365 + the event to trigger on; on the right is the action to take. As 19.366 + you can see, you can run an arbitrary shell command in a hook. 19.367 + Mercurial passes extra information to the hook using environment 19.368 + variables (look for <envar>HG_NODE</envar> in the example). 19.369 + </para> 19.370 + 19.371 + <sect2> 19.372 + <title>Performing multiple actions per event</title> 19.373 + 19.374 + <para>Quite often, you will want to define more than one hook 19.375 + for a particular kind of event, as shown below.</para> 19.376 + 19.377 +&interaction.hook.simple.ext; 19.378 + 19.379 + <para>Mercurial lets you do this by adding an 19.380 + <emphasis>extension</emphasis> to the end of a hook's name. 19.381 + You extend a hook's name by giving the name of the hook, 19.382 + followed by a full stop (the 19.383 + <quote><literal>.</literal></quote> character), followed by 19.384 + some more text of your choosing. For example, Mercurial will 19.385 + run both <literal>commit.foo</literal> and 19.386 + <literal>commit.bar</literal> when the 19.387 + <literal>commit</literal> event occurs. 19.388 + </para> 19.389 + 19.390 + <para>To give a well-defined order of execution when there are 19.391 + multiple hooks defined for an event, Mercurial sorts hooks by 19.392 + extension, and executes the hook commands in this sorted 19.393 + order. In the above example, it will execute 19.394 + <literal>commit.bar</literal> before 19.395 + <literal>commit.foo</literal>, and <literal>commit</literal> 19.396 + before both. 19.397 + </para> 19.398 + 19.399 + <para>It is a good idea to use a somewhat descriptive extension 19.400 + when you define a new hook. This will help you to remember 19.401 + what the hook was for. If the hook fails, you'll get an error 19.402 + message that contains the hook name and extension, so using a 19.403 + descriptive extension could give you an immediate hint as to 19.404 + why the hook failed (see section <xref 19.405 + linkend="sec:hook:perm"/> for an example). 19.406 + </para> 19.407 + 19.408 + </sect2> 19.409 + <sect2 id="sec:hook:perm"> 19.410 + <title>Controlling whether an activity can proceed</title> 19.411 + 19.412 + <para>In our earlier examples, we used the <literal 19.413 + role="hook">commit</literal> hook, which is run after a 19.414 + commit has completed. This is one of several Mercurial hooks 19.415 + that run after an activity finishes. Such hooks have no way 19.416 + of influencing the activity itself. 19.417 + </para> 19.418 + 19.419 + <para>Mercurial defines a number of events that occur before an 19.420 + activity starts; or after it starts, but before it finishes. 19.421 + Hooks that trigger on these events have the added ability to 19.422 + choose whether the activity can continue, or will abort. 19.423 + </para> 19.424 + 19.425 + <para>The <literal role="hook">pretxncommit</literal> hook runs 19.426 + after a commit has all but completed. In other words, the 19.427 + metadata representing the changeset has been written out to 19.428 + disk, but the transaction has not yet been allowed to 19.429 + complete. The <literal role="hook">pretxncommit</literal> 19.430 + hook has the ability to decide whether the transaction can 19.431 + complete, or must be rolled back. 19.432 + </para> 19.433 + 19.434 + <para>If the <literal role="hook">pretxncommit</literal> hook 19.435 + exits with a status code of zero, the transaction is allowed 19.436 + to complete; the commit finishes; and the <literal 19.437 + role="hook">commit</literal> hook is run. If the <literal 19.438 + role="hook">pretxncommit</literal> hook exits with a 19.439 + non-zero status code, the transaction is rolled back; the 19.440 + metadata representing the changeset is erased; and the 19.441 + <literal role="hook">commit</literal> hook is not run. 19.442 + </para> 19.443 + 19.444 +&interaction.hook.simple.pretxncommit; 19.445 + 19.446 + <para>The hook in the example above checks that a commit comment 19.447 + contains a bug ID. If it does, the commit can complete. If 19.448 + not, the commit is rolled back. 19.449 + </para> 19.450 + 19.451 + </sect2> 19.452 + </sect1> 19.453 + <sect1> 19.454 + <title>Writing your own hooks</title> 19.455 + 19.456 + <para>When you are writing a hook, you might find it useful to run 19.457 + Mercurial either with the <option 19.458 + role="hg-opt-global">-v</option> option, or the <envar 19.459 + role="rc-item-ui">verbose</envar> config item set to 19.460 + <quote>true</quote>. When you do so, Mercurial will print a 19.461 + message before it calls each hook. 19.462 + </para> 19.463 + 19.464 + <sect2 id="sec:hook:lang"> 19.465 + <title>Choosing how your hook should run</title> 19.466 + 19.467 + <para>You can write a hook either as a normal 19.468 + program&emdash;typically a shell script&emdash;or as a Python 19.469 + function that is executed within the Mercurial process. 19.470 + </para> 19.471 + 19.472 + <para>Writing a hook as an external program has the advantage 19.473 + that it requires no knowledge of Mercurial's internals. You 19.474 + can call normal Mercurial commands to get any added 19.475 + information you need. The trade-off is that external hooks 19.476 + are slower than in-process hooks. 19.477 + </para> 19.478 + 19.479 + <para>An in-process Python hook has complete access to the 19.480 + Mercurial API, and does not <quote>shell out</quote> to 19.481 + another process, so it is inherently faster than an external 19.482 + hook. It is also easier to obtain much of the information 19.483 + that a hook requires by using the Mercurial API than by 19.484 + running Mercurial commands. 19.485 + </para> 19.486 + 19.487 + <para>If you are comfortable with Python, or require high 19.488 + performance, writing your hooks in Python may be a good 19.489 + choice. However, when you have a straightforward hook to 19.490 + write and you don't need to care about performance (probably 19.491 + the majority of hooks), a shell script is perfectly fine. 19.492 + </para> 19.493 + 19.494 + </sect2> 19.495 + <sect2 id="sec:hook:param"> 19.496 + <title>Hook parameters</title> 19.497 + 19.498 + <para>Mercurial calls each hook with a set of well-defined 19.499 + parameters. In Python, a parameter is passed as a keyword 19.500 + argument to your hook function. For an external program, a 19.501 + parameter is passed as an environment variable. 19.502 + </para> 19.503 + 19.504 + <para>Whether your hook is written in Python or as a shell 19.505 + script, the hook-specific parameter names and values will be 19.506 + the same. A boolean parameter will be represented as a 19.507 + boolean value in Python, but as the number 1 (for 19.508 + <quote>true</quote>) or 0 (for <quote>false</quote>) as an 19.509 + environment variable for an external hook. If a hook 19.510 + parameter is named <literal>foo</literal>, the keyword 19.511 + argument for a Python hook will also be named 19.512 + <literal>foo</literal>, while the environment variable for an 19.513 + external hook will be named <literal>HG_FOO</literal>. 19.514 + </para> 19.515 + 19.516 + </sect2> 19.517 + <sect2> 19.518 + <title>Hook return values and activity control</title> 19.519 + 19.520 + <para>A hook that executes successfully must exit with a status 19.521 + of zero if external, or return boolean <quote>false</quote> if 19.522 + in-process. Failure is indicated with a non-zero exit status 19.523 + from an external hook, or an in-process hook returning boolean 19.524 + <quote>true</quote>. If an in-process hook raises an 19.525 + exception, the hook is considered to have failed. 19.526 + </para> 19.527 + 19.528 + <para>For a hook that controls whether an activity can proceed, 19.529 + zero/false means <quote>allow</quote>, while 19.530 + non-zero/true/exception means <quote>deny</quote>. 19.531 + </para> 19.532 + 19.533 + </sect2> 19.534 + <sect2> 19.535 + <title>Writing an external hook</title> 19.536 + 19.537 + <para>When you define an external hook in your <filename 19.538 + role="special">~/.hgrc</filename> and the hook is run, its 19.539 + value is passed to your shell, which interprets it. This 19.540 + means that you can use normal shell constructs in the body of 19.541 + the hook. 19.542 + </para> 19.543 + 19.544 + <para>An executable hook is always run with its current 19.545 + directory set to a repository's root directory. 19.546 + </para> 19.547 + 19.548 + <para>Each hook parameter is passed in as an environment 19.549 + variable; the name is upper-cased, and prefixed with the 19.550 + string <quote><literal>HG_</literal></quote>. 19.551 + </para> 19.552 + 19.553 + <para>With the exception of hook parameters, Mercurial does not 19.554 + set or modify any environment variables when running a hook. 19.555 + This is useful to remember if you are writing a site-wide hook 19.556 + that may be run by a number of different users with differing 19.557 + environment variables set. In multi-user situations, you 19.558 + should not rely on environment variables being set to the 19.559 + values you have in your environment when testing the hook. 19.560 + </para> 19.561 + 19.562 + </sect2> 19.563 + <sect2> 19.564 + <title>Telling Mercurial to use an in-process hook</title> 19.565 + 19.566 + <para>The <filename role="special">~/.hgrc</filename> syntax 19.567 + for defining an in-process hook is slightly different than for 19.568 + an executable hook. The value of the hook must start with the 19.569 + text <quote><literal>python:</literal></quote>, and continue 19.570 + with the fully-qualified name of a callable object to use as 19.571 + the hook's value. 19.572 + </para> 19.573 + 19.574 + <para>The module in which a hook lives is automatically imported 19.575 + when a hook is run. So long as you have the module name and 19.576 + <envar>PYTHONPATH</envar> right, it should <quote>just 19.577 + work</quote>. 19.578 + </para> 19.579 + 19.580 + <para>The following <filename role="special">~/.hgrc</filename> 19.581 + example snippet illustrates the syntax and meaning of the 19.582 + notions we just described. 19.583 + </para> 19.584 + <programlisting>[hooks] 19.585 +commit.example = python:mymodule.submodule.myhook</programlisting> 19.586 + <para>When Mercurial runs the <literal>commit.example</literal> 19.587 + hook, it imports <literal>mymodule.submodule</literal>, looks 19.588 + for the callable object named <literal>myhook</literal>, and 19.589 + calls it. 19.590 + </para> 19.591 + 19.592 + </sect2> 19.593 + <sect2> 19.594 + <title>Writing an in-process hook</title> 19.595 + 19.596 + <para>The simplest in-process hook does nothing, but illustrates 19.597 + the basic shape of the hook API: 19.598 + </para> 19.599 + <programlisting>def myhook(ui, repo, **kwargs): 19.600 + pass</programlisting> 19.601 + <para>The first argument to a Python hook is always a <literal 19.602 + role="py-mod-mercurial.ui">ui</literal> object. The second 19.603 + is a repository object; at the moment, it is always an 19.604 + instance of <literal 19.605 + role="py-mod-mercurial.localrepo">localrepository</literal>. 19.606 + Following these two arguments are other keyword arguments. 19.607 + Which ones are passed in depends on the hook being called, but 19.608 + a hook can ignore arguments it doesn't care about by dropping 19.609 + them into a keyword argument dict, as with 19.610 + <literal>**kwargs</literal> above. 19.611 + </para> 19.612 + 19.613 + </sect2> 19.614 + </sect1> 19.615 + <sect1> 19.616 + <title>Some hook examples</title> 19.617 + 19.618 + <sect2> 19.619 + <title>Writing meaningful commit messages</title> 19.620 + 19.621 + <para>It's hard to imagine a useful commit message being very 19.622 + short. The simple <literal role="hook">pretxncommit</literal> 19.623 + hook of the example below will prevent you from committing a 19.624 + changeset with a message that is less than ten bytes long. 19.625 + </para> 19.626 + 19.627 +&interaction.hook.msglen.go; 19.628 + 19.629 + </sect2> 19.630 + <sect2> 19.631 + <title>Checking for trailing whitespace</title> 19.632 + 19.633 + <para>An interesting use of a commit-related hook is to help you 19.634 + to write cleaner code. A simple example of <quote>cleaner 19.635 + code</quote> is the dictum that a change should not add any 19.636 + new lines of text that contain <quote>trailing 19.637 + whitespace</quote>. Trailing whitespace is a series of 19.638 + space and tab characters at the end of a line of text. In 19.639 + most cases, trailing whitespace is unnecessary, invisible 19.640 + noise, but it is occasionally problematic, and people often 19.641 + prefer to get rid of it. 19.642 + </para> 19.643 + 19.644 + <para>You can use either the <literal 19.645 + role="hook">precommit</literal> or <literal 19.646 + role="hook">pretxncommit</literal> hook to tell whether you 19.647 + have a trailing whitespace problem. If you use the <literal 19.648 + role="hook">precommit</literal> hook, the hook will not know 19.649 + which files you are committing, so it will have to check every 19.650 + modified file in the repository for trailing white space. If 19.651 + you want to commit a change to just the file 19.652 + <filename>foo</filename>, but the file 19.653 + <filename>bar</filename> contains trailing whitespace, doing a 19.654 + check in the <literal role="hook">precommit</literal> hook 19.655 + will prevent you from committing <filename>foo</filename> due 19.656 + to the problem with <filename>bar</filename>. This doesn't 19.657 + seem right. 19.658 + </para> 19.659 + 19.660 + <para>Should you choose the <literal 19.661 + role="hook">pretxncommit</literal> hook, the check won't 19.662 + occur until just before the transaction for the commit 19.663 + completes. This will allow you to check for problems only the 19.664 + exact files that are being committed. However, if you entered 19.665 + the commit message interactively and the hook fails, the 19.666 + transaction will roll back; you'll have to re-enter the commit 19.667 + message after you fix the trailing whitespace and run <command 19.668 + role="hg-cmd">hg commit</command> again. 19.669 + </para> 19.670 + 19.671 +&interaction.hook.ws.simple; 19.672 + 19.673 + <para>In this example, we introduce a simple <literal 19.674 + role="hook">pretxncommit</literal> hook that checks for 19.675 + trailing whitespace. This hook is short, but not very 19.676 + helpful. It exits with an error status if a change adds a 19.677 + line with trailing whitespace to any file, but does not print 19.678 + any information that might help us to identify the offending 19.679 + file or line. It also has the nice property of not paying 19.680 + attention to unmodified lines; only lines that introduce new 19.681 + trailing whitespace cause problems. 19.682 + </para> 19.683 + 19.684 + <para>The above version is much more complex, but also more 19.685 + useful. It parses a unified diff to see if any lines add 19.686 + trailing whitespace, and prints the name of the file and the 19.687 + line number of each such occurrence. Even better, if the 19.688 + change adds trailing whitespace, this hook saves the commit 19.689 + comment and prints the name of the save file before exiting 19.690 + and telling Mercurial to roll the transaction back, so you can 19.691 + use the <option role="hg-opt-commit">-l filename</option> 19.692 + option to <command role="hg-cmd">hg commit</command> to reuse 19.693 + the saved commit message once you've corrected the problem. 19.694 + </para> 19.695 + 19.696 +&interaction.hook.ws.better; 19.697 + 19.698 + <para>As a final aside, note in the example above the use of 19.699 + <command>perl</command>'s in-place editing feature to get rid 19.700 + of trailing whitespace from a file. This is concise and 19.701 + useful enough that I will reproduce it here. 19.702 + </para> 19.703 + <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting> 19.704 + 19.705 + </sect2> 19.706 + </sect1> 19.707 + <sect1> 19.708 + <title>Bundled hooks</title> 19.709 + 19.710 + <para>Mercurial ships with several bundled hooks. You can find 19.711 + them in the <filename class="directory">hgext</filename> 19.712 + directory of a Mercurial source tree. If you are using a 19.713 + Mercurial binary package, the hooks will be located in the 19.714 + <filename class="directory">hgext</filename> directory of 19.715 + wherever your package installer put Mercurial. 19.716 + </para> 19.717 + 19.718 + <sect2> 19.719 + <title><literal role="hg-ext">acl</literal>&emdash;access 19.720 + control for parts of a repository</title> 19.721 + 19.722 + <para>The <literal role="hg-ext">acl</literal> extension lets 19.723 + you control which remote users are allowed to push changesets 19.724 + to a networked server. You can protect any portion of a 19.725 + repository (including the entire repo), so that a specific 19.726 + remote user can push changes that do not affect the protected 19.727 + portion. 19.728 + </para> 19.729 + 19.730 + <para>This extension implements access control based on the 19.731 + identity of the user performing a push, 19.732 + <emphasis>not</emphasis> on who committed the changesets 19.733 + they're pushing. It makes sense to use this hook only if you 19.734 + have a locked-down server environment that authenticates 19.735 + remote users, and you want to be sure that only specific users 19.736 + are allowed to push changes to that server. 19.737 + </para> 19.738 + 19.739 + <sect3> 19.740 + <title>Configuring the <literal role="hook">acl</literal> 19.741 + hook</title> 19.742 + 19.743 + <para>In order to manage incoming changesets, the <literal 19.744 + role="hg-ext">acl</literal> hook must be used as a 19.745 + <literal role="hook">pretxnchangegroup</literal> hook. This 19.746 + lets it see which files are modified by each incoming 19.747 + changeset, and roll back a group of changesets if they 19.748 + modify <quote>forbidden</quote> files. Example: 19.749 + </para> 19.750 + <programlisting>[hooks] 19.751 +pretxnchangegroup.acl = python:hgext.acl.hook</programlisting> 19.752 + 19.753 + <para>The <literal role="hg-ext">acl</literal> extension is 19.754 + configured using three sections. 19.755 + </para> 19.756 + 19.757 + <para>The <literal role="rc-acl">acl</literal> section has 19.758 + only one entry, <envar role="rc-item-acl">sources</envar>, 19.759 + which lists the sources of incoming changesets that the hook 19.760 + should pay attention to. You don't normally need to 19.761 + configure this section. 19.762 + </para> 19.763 + <itemizedlist> 19.764 + <listitem><para><envar role="rc-item-acl">serve</envar>: 19.765 + Control incoming changesets that are arriving from a 19.766 + remote repository over http or ssh. This is the default 19.767 + value of <envar role="rc-item-acl">sources</envar>, and 19.768 + usually the only setting you'll need for this 19.769 + configuration item. 19.770 + </para> 19.771 + </listitem> 19.772 + <listitem><para><envar role="rc-item-acl">pull</envar>: 19.773 + Control incoming changesets that are arriving via a pull 19.774 + from a local repository. 19.775 + </para> 19.776 + </listitem> 19.777 + <listitem><para><envar role="rc-item-acl">push</envar>: 19.778 + Control incoming changesets that are arriving via a push 19.779 + from a local repository. 19.780 + </para> 19.781 + </listitem> 19.782 + <listitem><para><envar role="rc-item-acl">bundle</envar>: 19.783 + Control incoming changesets that are arriving from 19.784 + another repository via a bundle. 19.785 + </para> 19.786 + </listitem></itemizedlist> 19.787 + 19.788 + <para>The <literal role="rc-acl.allow">acl.allow</literal> 19.789 + section controls the users that are allowed to add 19.790 + changesets to the repository. If this section is not 19.791 + present, all users that are not explicitly denied are 19.792 + allowed. If this section is present, all users that are not 19.793 + explicitly allowed are denied (so an empty section means 19.794 + that all users are denied). 19.795 + </para> 19.796 + 19.797 + <para>The <literal role="rc-acl.deny">acl.deny</literal> 19.798 + section determines which users are denied from adding 19.799 + changesets to the repository. If this section is not 19.800 + present or is empty, no users are denied. 19.801 + </para> 19.802 + 19.803 + <para>The syntaxes for the <literal 19.804 + role="rc-acl.allow">acl.allow</literal> and <literal 19.805 + role="rc-acl.deny">acl.deny</literal> sections are 19.806 + identical. On the left of each entry is a glob pattern that 19.807 + matches files or directories, relative to the root of the 19.808 + repository; on the right, a user name. 19.809 + </para> 19.810 + 19.811 + <para>In the following example, the user 19.812 + <literal>docwriter</literal> can only push changes to the 19.813 + <filename class="directory">docs</filename> subtree of the 19.814 + repository, while <literal>intern</literal> can push changes 19.815 + to any file or directory except <filename 19.816 + class="directory">source/sensitive</filename>. 19.817 + </para> 19.818 + <programlisting>[acl.allow] 19.819 +docs/** = docwriter 19.820 +[acl.deny] 19.821 +source/sensitive/** = intern</programlisting> 19.822 + 19.823 + </sect3> 19.824 + <sect3> 19.825 + <title>Testing and troubleshooting</title> 19.826 + 19.827 + <para>If you want to test the <literal 19.828 + role="hg-ext">acl</literal> hook, run it with Mercurial's 19.829 + debugging output enabled. Since you'll probably be running 19.830 + it on a server where it's not convenient (or sometimes 19.831 + possible) to pass in the <option 19.832 + role="hg-opt-global">--debug</option> option, don't forget 19.833 + that you can enable debugging output in your <filename 19.834 + role="special">~/.hgrc</filename>: 19.835 + </para> 19.836 + <programlisting>[ui] 19.837 +debug = true</programlisting> 19.838 + <para>With this enabled, the <literal 19.839 + role="hg-ext">acl</literal> hook will print enough 19.840 + information to let you figure out why it is allowing or 19.841 + forbidding pushes from specific users. 19.842 + </para> 19.843 + 19.844 + </sect3> 19.845 + </sect2> 19.846 + <sect2> 19.847 + <title><literal 19.848 + role="hg-ext">bugzilla</literal>&emdash;integration with 19.849 + Bugzilla</title> 19.850 + 19.851 + <para>The <literal role="hg-ext">bugzilla</literal> extension 19.852 + adds a comment to a Bugzilla bug whenever it finds a reference 19.853 + to that bug ID in a commit comment. You can install this hook 19.854 + on a shared server, so that any time a remote user pushes 19.855 + changes to this server, the hook gets run. 19.856 + </para> 19.857 + 19.858 + <para>It adds a comment to the bug that looks like this (you can 19.859 + configure the contents of the comment&emdash;see below): 19.860 + </para> 19.861 + <programlisting>Changeset aad8b264143a, made by Joe User 19.862 + <joe.user@domain.com> in the frobnitz repository, refers 19.863 + to this bug. For complete details, see 19.864 + http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a 19.865 + Changeset description: Fix bug 10483 by guarding against some 19.866 + NULL pointers</programlisting> 19.867 + <para>The value of this hook is that it automates the process of 19.868 + updating a bug any time a changeset refers to it. If you 19.869 + configure the hook properly, it makes it easy for people to 19.870 + browse straight from a Bugzilla bug to a changeset that refers 19.871 + to that bug. 19.872 + </para> 19.873 + 19.874 + <para>You can use the code in this hook as a starting point for 19.875 + some more exotic Bugzilla integration recipes. Here are a few 19.876 + possibilities: 19.877 + </para> 19.878 + <itemizedlist> 19.879 + <listitem><para>Require that every changeset pushed to the 19.880 + server have a valid bug ID in its commit comment. In this 19.881 + case, you'd want to configure the hook as a <literal 19.882 + role="hook">pretxncommit</literal> hook. This would 19.883 + allow the hook to reject changes that didn't contain bug 19.884 + IDs. 19.885 + </para> 19.886 + </listitem> 19.887 + <listitem><para>Allow incoming changesets to automatically 19.888 + modify the <emphasis>state</emphasis> of a bug, as well as 19.889 + simply adding a comment. For example, the hook could 19.890 + recognise the string <quote>fixed bug 31337</quote> as 19.891 + indicating that it should update the state of bug 31337 to 19.892 + <quote>requires testing</quote>. 19.893 + </para> 19.894 + </listitem></itemizedlist> 19.895 + 19.896 + <sect3 id="sec:hook:bugzilla:config"> 19.897 + <title>Configuring the <literal role="hook">bugzilla</literal> 19.898 + hook</title> 19.899 + 19.900 + <para>You should configure this hook in your server's 19.901 + <filename role="special">~/.hgrc</filename> as an <literal 19.902 + role="hook">incoming</literal> hook, for example as 19.903 + follows: 19.904 + </para> 19.905 + <programlisting>[hooks] 19.906 +incoming.bugzilla = python:hgext.bugzilla.hook</programlisting> 19.907 + 19.908 + <para>Because of the specialised nature of this hook, and 19.909 + because Bugzilla was not written with this kind of 19.910 + integration in mind, configuring this hook is a somewhat 19.911 + involved process. 19.912 + </para> 19.913 + 19.914 + <para>Before you begin, you must install the MySQL bindings 19.915 + for Python on the host(s) where you'll be running the hook. 19.916 + If this is not available as a binary package for your 19.917 + system, you can download it from 19.918 + <citation>web:mysql-python</citation>. 19.919 + </para> 19.920 + 19.921 + <para>Configuration information for this hook lives in the 19.922 + <literal role="rc-bugzilla">bugzilla</literal> section of 19.923 + your <filename role="special">~/.hgrc</filename>. 19.924 + </para> 19.925 + <itemizedlist> 19.926 + <listitem><para><envar 19.927 + role="rc-item-bugzilla">version</envar>: The version 19.928 + of Bugzilla installed on the server. The database 19.929 + schema that Bugzilla uses changes occasionally, so this 19.930 + hook has to know exactly which schema to use. At the 19.931 + moment, the only version supported is 19.932 + <literal>2.16</literal>. 19.933 + </para> 19.934 + </listitem> 19.935 + <listitem><para><envar role="rc-item-bugzilla">host</envar>: 19.936 + The hostname of the MySQL server that stores your 19.937 + Bugzilla data. The database must be configured to allow 19.938 + connections from whatever host you are running the 19.939 + <literal role="hook">bugzilla</literal> hook on. 19.940 + </para> 19.941 + </listitem> 19.942 + <listitem><para><envar role="rc-item-bugzilla">user</envar>: 19.943 + The username with which to connect to the MySQL server. 19.944 + The database must be configured to allow this user to 19.945 + connect from whatever host you are running the <literal 19.946 + role="hook">bugzilla</literal> hook on. This user 19.947 + must be able to access and modify Bugzilla tables. The 19.948 + default value of this item is <literal>bugs</literal>, 19.949 + which is the standard name of the Bugzilla user in a 19.950 + MySQL database. 19.951 + </para> 19.952 + </listitem> 19.953 + <listitem><para><envar 19.954 + role="rc-item-bugzilla">password</envar>: The MySQL 19.955 + password for the user you configured above. This is 19.956 + stored as plain text, so you should make sure that 19.957 + unauthorised users cannot read the <filename 19.958 + role="special">~/.hgrc</filename> file where you 19.959 + store this information. 19.960 + </para> 19.961 + </listitem> 19.962 + <listitem><para><envar role="rc-item-bugzilla">db</envar>: 19.963 + The name of the Bugzilla database on the MySQL server. 19.964 + The default value of this item is 19.965 + <literal>bugs</literal>, which is the standard name of 19.966 + the MySQL database where Bugzilla stores its data. 19.967 + </para> 19.968 + </listitem> 19.969 + <listitem><para><envar 19.970 + role="rc-item-bugzilla">notify</envar>: If you want 19.971 + Bugzilla to send out a notification email to subscribers 19.972 + after this hook has added a comment to a bug, you will 19.973 + need this hook to run a command whenever it updates the 19.974 + database. The command to run depends on where you have 19.975 + installed Bugzilla, but it will typically look something 19.976 + like this, if you have Bugzilla installed in <filename 19.977 + class="directory">/var/www/html/bugzilla</filename>: 19.978 + </para> 19.979 + <programlisting>cd /var/www/html/bugzilla && 19.980 + ./processmail %s nobody@nowhere.com</programlisting> 19.981 + </listitem> 19.982 + <listitem><para> The Bugzilla 19.983 + <literal>processmail</literal> program expects to be 19.984 + given a bug ID (the hook replaces 19.985 + <quote><literal>%s</literal></quote> with the bug ID) 19.986 + and an email address. It also expects to be able to 19.987 + write to some files in the directory that it runs in. 19.988 + If Bugzilla and this hook are not installed on the same 19.989 + machine, you will need to find a way to run 19.990 + <literal>processmail</literal> on the server where 19.991 + Bugzilla is installed. 19.992 + </para> 19.993 + </listitem></itemizedlist> 19.994 + 19.995 + </sect3> 19.996 + <sect3> 19.997 + <title>Mapping committer names to Bugzilla user names</title> 19.998 + 19.999 + <para>By default, the <literal 19.1000 + role="hg-ext">bugzilla</literal> hook tries to use the 19.1001 + email address of a changeset's committer as the Bugzilla 19.1002 + user name with which to update a bug. If this does not suit 19.1003 + your needs, you can map committer email addresses to 19.1004 + Bugzilla user names using a <literal 19.1005 + role="rc-usermap">usermap</literal> section. 19.1006 + </para> 19.1007 + 19.1008 + <para>Each item in the <literal 19.1009 + role="rc-usermap">usermap</literal> section contains an 19.1010 + email address on the left, and a Bugzilla user name on the 19.1011 + right. 19.1012 + </para> 19.1013 + <programlisting>[usermap] 19.1014 +jane.user@example.com = jane</programlisting> 19.1015 + <para>You can either keep the <literal 19.1016 + role="rc-usermap">usermap</literal> data in a normal 19.1017 + <filename role="special">~/.hgrc</filename>, or tell the 19.1018 + <literal role="hg-ext">bugzilla</literal> hook to read the 19.1019 + information from an external <filename>usermap</filename> 19.1020 + file. In the latter case, you can store 19.1021 + <filename>usermap</filename> data by itself in (for example) 19.1022 + a user-modifiable repository. This makes it possible to let 19.1023 + your users maintain their own <envar 19.1024 + role="rc-item-bugzilla">usermap</envar> entries. The main 19.1025 + <filename role="special">~/.hgrc</filename> file might look 19.1026 + like this: 19.1027 + </para> 19.1028 + <programlisting># regular hgrc file refers to external usermap file 19.1029 +[bugzilla] 19.1030 +usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting> 19.1031 + <para>While the <filename>usermap</filename> file that it 19.1032 + refers to might look like this: 19.1033 + </para> 19.1034 + <programlisting># bugzilla-usermap.conf - inside a hg repository 19.1035 +[usermap] stephanie@example.com = steph</programlisting> 19.1036 + 19.1037 + </sect3> 19.1038 + <sect3> 19.1039 + <title>Configuring the text that gets added to a bug</title> 19.1040 + 19.1041 + <para>You can configure the text that this hook adds as a 19.1042 + comment; you specify it in the form of a Mercurial template. 19.1043 + Several <filename role="special">~/.hgrc</filename> entries 19.1044 + (still in the <literal role="rc-bugzilla">bugzilla</literal> 19.1045 + section) control this behaviour. 19.1046 + </para> 19.1047 + <itemizedlist> 19.1048 + <listitem><para><literal>strip</literal>: The number of 19.1049 + leading path elements to strip from a repository's path 19.1050 + name to construct a partial path for a URL. For example, 19.1051 + if the repositories on your server live under <filename 19.1052 + class="directory">/home/hg/repos</filename>, and you 19.1053 + have a repository whose path is <filename 19.1054 + class="directory">/home/hg/repos/app/tests</filename>, 19.1055 + then setting <literal>strip</literal> to 19.1056 + <literal>4</literal> will give a partial path of 19.1057 + <filename class="directory">app/tests</filename>. The 19.1058 + hook will make this partial path available when 19.1059 + expanding a template, as <literal>webroot</literal>. 19.1060 + </para> 19.1061 + </listitem> 19.1062 + <listitem><para><literal>template</literal>: The text of the 19.1063 + template to use. In addition to the usual 19.1064 + changeset-related variables, this template can use 19.1065 + <literal>hgweb</literal> (the value of the 19.1066 + <literal>hgweb</literal> configuration item above) and 19.1067 + <literal>webroot</literal> (the path constructed using 19.1068 + <literal>strip</literal> above). 19.1069 + </para> 19.1070 + </listitem></itemizedlist> 19.1071 + 19.1072 + <para>In addition, you can add a <envar 19.1073 + role="rc-item-web">baseurl</envar> item to the <literal 19.1074 + role="rc-web">web</literal> section of your <filename 19.1075 + role="special">~/.hgrc</filename>. The <literal 19.1076 + role="hg-ext">bugzilla</literal> hook will make this 19.1077 + available when expanding a template, as the base string to 19.1078 + use when constructing a URL that will let users browse from 19.1079 + a Bugzilla comment to view a changeset. Example: 19.1080 + </para> 19.1081 + <programlisting>[web] 19.1082 +baseurl = http://hg.domain.com/</programlisting> 19.1083 + 19.1084 + <para>Here is an example set of <literal 19.1085 + role="hg-ext">bugzilla</literal> hook config information. 19.1086 + </para> 19.1087 + 19.1088 + &ch10-bugzilla-config.lst; 19.1089 + 19.1090 + </sect3> 19.1091 + <sect3> 19.1092 + <title>Testing and troubleshooting</title> 19.1093 + 19.1094 + <para>The most common problems with configuring the <literal 19.1095 + role="hg-ext">bugzilla</literal> hook relate to running 19.1096 + Bugzilla's <filename>processmail</filename> script and 19.1097 + mapping committer names to user names. 19.1098 + </para> 19.1099 + 19.1100 + <para>Recall from section <xref 19.1101 + linkend="sec:hook:bugzilla:config"/> above that the user 19.1102 + that runs the Mercurial process on the server is also the 19.1103 + one that will run the <filename>processmail</filename> 19.1104 + script. The <filename>processmail</filename> script 19.1105 + sometimes causes Bugzilla to write to files in its 19.1106 + configuration directory, and Bugzilla's configuration files 19.1107 + are usually owned by the user that your web server runs 19.1108 + under. 19.1109 + </para> 19.1110 + 19.1111 + <para>You can cause <filename>processmail</filename> to be run 19.1112 + with the suitable user's identity using the 19.1113 + <command>sudo</command> command. Here is an example entry 19.1114 + for a <filename>sudoers</filename> file. 19.1115 + </para> 19.1116 + <programlisting>hg_user = (httpd_user) 19.1117 +NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting> 19.1118 + <para>This allows the <literal>hg_user</literal> user to run a 19.1119 + <filename>processmail-wrapper</filename> program under the 19.1120 + identity of <literal>httpd_user</literal>. 19.1121 + </para> 19.1122 + 19.1123 + <para>This indirection through a wrapper script is necessary, 19.1124 + because <filename>processmail</filename> expects to be run 19.1125 + with its current directory set to wherever you installed 19.1126 + Bugzilla; you can't specify that kind of constraint in a 19.1127 + <filename>sudoers</filename> file. The contents of the 19.1128 + wrapper script are simple: 19.1129 + </para> 19.1130 + <programlisting>#!/bin/sh 19.1131 +cd `dirname $0` && ./processmail "$1" nobody@example.com</programlisting> 19.1132 + <para>It doesn't seem to matter what email address you pass to 19.1133 + <filename>processmail</filename>. 19.1134 + </para> 19.1135 + 19.1136 + <para>If your <literal role="rc-usermap">usermap</literal> is 19.1137 + not set up correctly, users will see an error message from 19.1138 + the <literal role="hg-ext">bugzilla</literal> hook when they 19.1139 + push changes to the server. The error message will look 19.1140 + like this: 19.1141 + </para> 19.1142 + <programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting> 19.1143 + <para>What this means is that the committer's address, 19.1144 + <literal>john.q.public@example.com</literal>, is not a valid 19.1145 + Bugzilla user name, nor does it have an entry in your 19.1146 + <literal role="rc-usermap">usermap</literal> that maps it to 19.1147 + a valid Bugzilla user name. 19.1148 + </para> 19.1149 + 19.1150 + </sect3> 19.1151 + </sect2> 19.1152 + <sect2> 19.1153 + <title><literal role="hg-ext">notify</literal>&emdash;send email 19.1154 + notifications</title> 19.1155 + 19.1156 + <para>Although Mercurial's built-in web server provides RSS 19.1157 + feeds of changes in every repository, many people prefer to 19.1158 + receive change notifications via email. The <literal 19.1159 + role="hg-ext">notify</literal> hook lets you send out 19.1160 + notifications to a set of email addresses whenever changesets 19.1161 + arrive that those subscribers are interested in. 19.1162 + </para> 19.1163 + 19.1164 + <para>As with the <literal role="hg-ext">bugzilla</literal> 19.1165 + hook, the <literal role="hg-ext">notify</literal> hook is 19.1166 + template-driven, so you can customise the contents of the 19.1167 + notification messages that it sends. 19.1168 + </para> 19.1169 + 19.1170 + <para>By default, the <literal role="hg-ext">notify</literal> 19.1171 + hook includes a diff of every changeset that it sends out; you 19.1172 + can limit the size of the diff, or turn this feature off 19.1173 + entirely. It is useful for letting subscribers review changes 19.1174 + immediately, rather than clicking to follow a URL. 19.1175 + </para> 19.1176 + 19.1177 + <sect3> 19.1178 + <title>Configuring the <literal role="hg-ext">notify</literal> 19.1179 + hook</title> 19.1180 + 19.1181 + <para>You can set up the <literal 19.1182 + role="hg-ext">notify</literal> hook to send one email 19.1183 + message per incoming changeset, or one per incoming group of 19.1184 + changesets (all those that arrived in a single pull or 19.1185 + push). 19.1186 + </para> 19.1187 + <programlisting>[hooks] 19.1188 +# send one email per group of changes 19.1189 +changegroup.notify = python:hgext.notify.hook 19.1190 +# send one email per change 19.1191 +incoming.notify = python:hgext.notify.hook</programlisting> 19.1192 + 19.1193 + <para>Configuration information for this hook lives in the 19.1194 + <literal role="rc-notify">notify</literal> section of a 19.1195 + <filename role="special">~/.hgrc</filename> file. 19.1196 + </para> 19.1197 + <itemizedlist> 19.1198 + <listitem><para><envar role="rc-item-notify">test</envar>: 19.1199 + By default, this hook does not send out email at all; 19.1200 + instead, it prints the message that it 19.1201 + <emphasis>would</emphasis> send. Set this item to 19.1202 + <literal>false</literal> to allow email to be sent. The 19.1203 + reason that sending of email is turned off by default is 19.1204 + that it takes several tries to configure this extension 19.1205 + exactly as you would like, and it would be bad form to 19.1206 + spam subscribers with a number of <quote>broken</quote> 19.1207 + notifications while you debug your configuration. 19.1208 + </para> 19.1209 + </listitem> 19.1210 + <listitem><para><envar role="rc-item-notify">config</envar>: 19.1211 + The path to a configuration file that contains 19.1212 + subscription information. This is kept separate from 19.1213 + the main <filename role="special">~/.hgrc</filename> so 19.1214 + that you can maintain it in a repository of its own. 19.1215 + People can then clone that repository, update their 19.1216 + subscriptions, and push the changes back to your server. 19.1217 + </para> 19.1218 + </listitem> 19.1219 + <listitem><para><envar role="rc-item-notify">strip</envar>: 19.1220 + The number of leading path separator characters to strip 19.1221 + from a repository's path, when deciding whether a 19.1222 + repository has subscribers. For example, if the 19.1223 + repositories on your server live in <filename 19.1224 + class="directory">/home/hg/repos</filename>, and 19.1225 + <literal role="hg-ext">notify</literal> is considering a 19.1226 + repository named <filename 19.1227 + class="directory">/home/hg/repos/shared/test</filename>, 19.1228 + setting <envar role="rc-item-notify">strip</envar> to 19.1229 + <literal>4</literal> will cause <literal 19.1230 + role="hg-ext">notify</literal> to trim the path it 19.1231 + considers down to <filename 19.1232 + class="directory">shared/test</filename>, and it will 19.1233 + match subscribers against that. 19.1234 + </para> 19.1235 + </listitem> 19.1236 + <listitem><para><envar 19.1237 + role="rc-item-notify">template</envar>: The template 19.1238 + text to use when sending messages. This specifies both 19.1239 + the contents of the message header and its body. 19.1240 + </para> 19.1241 + </listitem> 19.1242 + <listitem><para><envar 19.1243 + role="rc-item-notify">maxdiff</envar>: The maximum 19.1244 + number of lines of diff data to append to the end of a 19.1245 + message. If a diff is longer than this, it is 19.1246 + truncated. By default, this is set to 300. Set this to 19.1247 + <literal>0</literal> to omit diffs from notification 19.1248 + emails. 19.1249 + </para> 19.1250 + </listitem> 19.1251 + <listitem><para><envar 19.1252 + role="rc-item-notify">sources</envar>: A list of 19.1253 + sources of changesets to consider. This lets you limit 19.1254 + <literal role="hg-ext">notify</literal> to only sending 19.1255 + out email about changes that remote users pushed into 19.1256 + this repository via a server, for example. See section 19.1257 + <xref 19.1258 + linkend="sec:hook:sources"/> for the sources you can 19.1259 + specify here. 19.1260 + </para> 19.1261 + </listitem></itemizedlist> 19.1262 + 19.1263 + <para>If you set the <envar role="rc-item-web">baseurl</envar> 19.1264 + item in the <literal role="rc-web">web</literal> section, 19.1265 + you can use it in a template; it will be available as 19.1266 + <literal>webroot</literal>. 19.1267 + </para> 19.1268 + 19.1269 + <para>Here is an example set of <literal 19.1270 + role="hg-ext">notify</literal> configuration information. 19.1271 + </para> 19.1272 + 19.1273 + &ch10-notify-config.lst; 19.1274 + 19.1275 + <para>This will produce a message that looks like the 19.1276 + following: 19.1277 + </para> 19.1278 + 19.1279 + &ch10-notify-config-mail.lst; 19.1280 + 19.1281 + </sect3> 19.1282 + <sect3> 19.1283 + <title>Testing and troubleshooting</title> 19.1284 + 19.1285 + <para>Do not forget that by default, the <literal 19.1286 + role="hg-ext">notify</literal> extension <emphasis>will not 19.1287 + send any mail</emphasis> until you explicitly configure it to do so, 19.1288 + by setting <envar role="rc-item-notify">test</envar> to 19.1289 + <literal>false</literal>. Until you do that, it simply 19.1290 + prints the message it <emphasis>would</emphasis> send. 19.1291 + </para> 19.1292 + 19.1293 + </sect3> 19.1294 + </sect2> 19.1295 + </sect1> 19.1296 + <sect1 id="sec:hook:ref"> 19.1297 + <title>Information for writers of hooks</title> 19.1298 + 19.1299 + <sect2> 19.1300 + <title>In-process hook execution</title> 19.1301 + 19.1302 + <para>An in-process hook is called with arguments of the 19.1303 + following form: 19.1304 + </para> 19.1305 + <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting> 19.1306 + <para>The <literal>ui</literal> parameter is a <literal 19.1307 + role="py-mod-mercurial.ui">ui</literal> object. The 19.1308 + <literal>repo</literal> parameter is a <literal 19.1309 + role="py-mod-mercurial.localrepo">localrepository</literal> 19.1310 + object. The names and values of the 19.1311 + <literal>**kwargs</literal> parameters depend on the hook 19.1312 + being invoked, with the following common features: 19.1313 + </para> 19.1314 + <itemizedlist> 19.1315 + <listitem><para>If a parameter is named 19.1316 + <literal>node</literal> or <literal>parentN</literal>, it 19.1317 + will contain a hexadecimal changeset ID. The empty string 19.1318 + is used to represent <quote>null changeset ID</quote> 19.1319 + instead of a string of zeroes. 19.1320 + </para> 19.1321 + </listitem> 19.1322 + <listitem><para>If a parameter is named 19.1323 + <literal>url</literal>, it will contain the URL of a 19.1324 + remote repository, if that can be determined. 19.1325 + </para> 19.1326 + </listitem> 19.1327 + <listitem><para>Boolean-valued parameters are represented as 19.1328 + Python <literal>bool</literal> objects. 19.1329 + </para> 19.1330 + </listitem></itemizedlist> 19.1331 + 19.1332 + <para>An in-process hook is called without a change to the 19.1333 + process's working directory (unlike external hooks, which are 19.1334 + run in the root of the repository). It must not change the 19.1335 + process's working directory, or it will cause any calls it 19.1336 + makes into the Mercurial API to fail. 19.1337 + </para> 19.1338 + 19.1339 + <para>If a hook returns a boolean <quote>false</quote> value, it 19.1340 + is considered to have succeeded. If it returns a boolean 19.1341 + <quote>true</quote> value or raises an exception, it is 19.1342 + considered to have failed. A useful way to think of the 19.1343 + calling convention is <quote>tell me if you fail</quote>. 19.1344 + </para> 19.1345 + 19.1346 + <para>Note that changeset IDs are passed into Python hooks as 19.1347 + hexadecimal strings, not the binary hashes that Mercurial's 19.1348 + APIs normally use. To convert a hash from hex to binary, use 19.1349 + the <literal>bin</literal> function. 19.1350 + </para> 19.1351 + 19.1352 + </sect2> 19.1353 + <sect2> 19.1354 + <title>External hook execution</title> 19.1355 + 19.1356 + <para>An external hook is passed to the shell of the user 19.1357 + running Mercurial. Features of that shell, such as variable 19.1358 + substitution and command redirection, are available. The hook 19.1359 + is run in the root directory of the repository (unlike 19.1360 + in-process hooks, which are run in the same directory that 19.1361 + Mercurial was run in). 19.1362 + </para> 19.1363 + 19.1364 + <para>Hook parameters are passed to the hook as environment 19.1365 + variables. Each environment variable's name is converted in 19.1366 + upper case and prefixed with the string 19.1367 + <quote><literal>HG_</literal></quote>. For example, if the 19.1368 + name of a parameter is <quote><literal>node</literal></quote>, 19.1369 + the name of the environment variable representing that 19.1370 + parameter will be <quote><literal>HG_NODE</literal></quote>. 19.1371 + </para> 19.1372 + 19.1373 + <para>A boolean parameter is represented as the string 19.1374 + <quote><literal>1</literal></quote> for <quote>true</quote>, 19.1375 + <quote><literal>0</literal></quote> for <quote>false</quote>. 19.1376 + If an environment variable is named <envar>HG_NODE</envar>, 19.1377 + <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it 19.1378 + contains a changeset ID represented as a hexadecimal string. 19.1379 + The empty string is used to represent <quote>null changeset 19.1380 + ID</quote> instead of a string of zeroes. If an environment 19.1381 + variable is named <envar>HG_URL</envar>, it will contain the 19.1382 + URL of a remote repository, if that can be determined. 19.1383 + </para> 19.1384 + 19.1385 + <para>If a hook exits with a status of zero, it is considered to 19.1386 + have succeeded. If it exits with a non-zero status, it is 19.1387 + considered to have failed. 19.1388 + </para> 19.1389 + 19.1390 + </sect2> 19.1391 + <sect2> 19.1392 + <title>Finding out where changesets come from</title> 19.1393 + 19.1394 + <para>A hook that involves the transfer of changesets between a 19.1395 + local repository and another may be able to find out 19.1396 + information about the <quote>far side</quote>. Mercurial 19.1397 + knows <emphasis>how</emphasis> changes are being transferred, 19.1398 + and in many cases <emphasis>where</emphasis> they are being 19.1399 + transferred to or from. 19.1400 + </para> 19.1401 + 19.1402 + <sect3 id="sec:hook:sources"> 19.1403 + <title>Sources of changesets</title> 19.1404 + 19.1405 + <para>Mercurial will tell a hook what means are, or were, used 19.1406 + to transfer changesets between repositories. This is 19.1407 + provided by Mercurial in a Python parameter named 19.1408 + <literal>source</literal>, or an environment variable named 19.1409 + <envar>HG_SOURCE</envar>. 19.1410 + </para> 19.1411 + 19.1412 + <itemizedlist> 19.1413 + <listitem><para><literal>serve</literal>: Changesets are 19.1414 + transferred to or from a remote repository over http or 19.1415 + ssh. 19.1416 + </para> 19.1417 + </listitem> 19.1418 + <listitem><para><literal>pull</literal>: Changesets are 19.1419 + being transferred via a pull from one repository into 19.1420 + another. 19.1421 + </para> 19.1422 + </listitem> 19.1423 + <listitem><para><literal>push</literal>: Changesets are 19.1424 + being transferred via a push from one repository into 19.1425 + another. 19.1426 + </para> 19.1427 + </listitem> 19.1428 + <listitem><para><literal>bundle</literal>: Changesets are 19.1429 + being transferred to or from a bundle. 19.1430 + </para> 19.1431 + </listitem></itemizedlist> 19.1432 + 19.1433 + </sect3> 19.1434 + <sect3 id="sec:hook:url"> 19.1435 + <title>Where changes are going&emdash;remote repository 19.1436 + URLs</title> 19.1437 + 19.1438 + <para>When possible, Mercurial will tell a hook the location 19.1439 + of the <quote>far side</quote> of an activity that transfers 19.1440 + changeset data between repositories. This is provided by 19.1441 + Mercurial in a Python parameter named 19.1442 + <literal>url</literal>, or an environment variable named 19.1443 + <envar>HG_URL</envar>. 19.1444 + </para> 19.1445 + 19.1446 + <para>This information is not always known. If a hook is 19.1447 + invoked in a repository that is being served via http or 19.1448 + ssh, Mercurial cannot tell where the remote repository is, 19.1449 + but it may know where the client is connecting from. In 19.1450 + such cases, the URL will take one of the following forms: 19.1451 + </para> 19.1452 + <itemizedlist> 19.1453 + <listitem><para><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 19.1454 + ssh client, at the IP address 19.1455 + <literal>1.2.3.4</literal>. 19.1456 + </para> 19.1457 + </listitem> 19.1458 + <listitem><para><literal>remote:http:1.2.3.4</literal>&emdash;remote 19.1459 + http client, at the IP address 19.1460 + <literal>1.2.3.4</literal>. If the client is using SSL, 19.1461 + this will be of the form 19.1462 + <literal>remote:https:1.2.3.4</literal>. 19.1463 + </para> 19.1464 + </listitem> 19.1465 + <listitem><para>Empty&emdash;no information could be 19.1466 + discovered about the remote client. 19.1467 + </para> 19.1468 + </listitem></itemizedlist> 19.1469 + 19.1470 + </sect3> 19.1471 + </sect2> 19.1472 + </sect1> 19.1473 + <sect1> 19.1474 + <title>Hook reference</title> 19.1475 + 19.1476 + <sect2 id="sec:hook:changegroup"> 19.1477 + <title><literal role="hook">changegroup</literal>&emdash;after 19.1478 + remote changesets added</title> 19.1479 + 19.1480 + <para>This hook is run after a group of pre-existing changesets 19.1481 + has been added to the repository, for example via a <command 19.1482 + role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg 19.1483 + unbundle</command>. This hook is run once per operation 19.1484 + that added one or more changesets. This is in contrast to the 19.1485 + <literal role="hook">incoming</literal> hook, which is run 19.1486 + once per changeset, regardless of whether the changesets 19.1487 + arrive in a group. 19.1488 + </para> 19.1489 + 19.1490 + <para>Some possible uses for this hook include kicking off an 19.1491 + automated build or test of the added changesets, updating a 19.1492 + bug database, or notifying subscribers that a repository 19.1493 + contains new changes. 19.1494 + </para> 19.1495 + 19.1496 + <para>Parameters to this hook: 19.1497 + </para> 19.1498 + <itemizedlist> 19.1499 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1500 + changeset ID of the first changeset in the group that was 19.1501 + added. All changesets between this and 19.1502 + <literal role="tag">tip</literal>, inclusive, were added by a single 19.1503 + <command role="hg-cmd">hg pull</command>, <command 19.1504 + role="hg-cmd">hg push</command> or <command 19.1505 + role="hg-cmd">hg unbundle</command>. 19.1506 + </para> 19.1507 + </listitem> 19.1508 + <listitem><para><literal>source</literal>: A string. The 19.1509 + source of these changes. See section <xref 19.1510 + linkend="sec:hook:sources"/> for details. 19.1511 + </para> 19.1512 + </listitem> 19.1513 + <listitem><para><literal>url</literal>: A URL. The location 19.1514 + of the remote repository, if known. See section <xref 19.1515 + linkend="sec:hook:url"/> for more 19.1516 + information. 19.1517 + </para> 19.1518 + </listitem></itemizedlist> 19.1519 + 19.1520 + <para>See also: <literal role="hook">incoming</literal> (section 19.1521 + <xref linkend="sec:hook:incoming"/>), <literal 19.1522 + role="hook">prechangegroup</literal> (section <xref 19.1523 + linkend="sec:hook:prechangegroup"/>), <literal 19.1524 + role="hook">pretxnchangegroup</literal> (section <xref 19.1525 + linkend="sec:hook:pretxnchangegroup"/>) 19.1526 + </para> 19.1527 + 19.1528 + </sect2> 19.1529 + <sect2 id="sec:hook:commit"> 19.1530 + <title><literal role="hook">commit</literal>&emdash;after a new 19.1531 + changeset is created</title> 19.1532 + 19.1533 + <para>This hook is run after a new changeset has been created. 19.1534 + </para> 19.1535 + 19.1536 + <para>Parameters to this hook: 19.1537 + </para> 19.1538 + <itemizedlist> 19.1539 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1540 + changeset ID of the newly committed changeset. 19.1541 + </para> 19.1542 + </listitem> 19.1543 + <listitem><para><literal>parent1</literal>: A changeset ID. 19.1544 + The changeset ID of the first parent of the newly 19.1545 + committed changeset. 19.1546 + </para> 19.1547 + </listitem> 19.1548 + <listitem><para><literal>parent2</literal>: A changeset ID. 19.1549 + The changeset ID of the second parent of the newly 19.1550 + committed changeset. 19.1551 + </para> 19.1552 + </listitem></itemizedlist> 19.1553 + 19.1554 + <para>See also: <literal role="hook">precommit</literal> 19.1555 + (section <xref linkend="sec:hook:precommit"/>), <literal 19.1556 + role="hook">pretxncommit</literal> (section <xref 19.1557 + linkend="sec:hook:pretxncommit"/>) 19.1558 + </para> 19.1559 + 19.1560 + </sect2> 19.1561 + <sect2 id="sec:hook:incoming"> 19.1562 + <title><literal role="hook">incoming</literal>&emdash;after one 19.1563 + remote changeset is added</title> 19.1564 + 19.1565 + <para>This hook is run after a pre-existing changeset has been 19.1566 + added to the repository, for example via a <command 19.1567 + role="hg-cmd">hg push</command>. If a group of changesets 19.1568 + was added in a single operation, this hook is called once for 19.1569 + each added changeset. 19.1570 + </para> 19.1571 + 19.1572 + <para>You can use this hook for the same purposes as the 19.1573 + <literal role="hook">changegroup</literal> hook (section <xref 19.1574 + linkend="sec:hook:changegroup"/>); it's simply 19.1575 + more convenient sometimes to run a hook once per group of 19.1576 + changesets, while other times it's handier once per changeset. 19.1577 + </para> 19.1578 + 19.1579 + <para>Parameters to this hook: 19.1580 + </para> 19.1581 + <itemizedlist> 19.1582 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1583 + ID of the newly added changeset. 19.1584 + </para> 19.1585 + </listitem> 19.1586 + <listitem><para><literal>source</literal>: A string. The 19.1587 + source of these changes. See section <xref 19.1588 + linkend="sec:hook:sources"/> for details. 19.1589 + </para> 19.1590 + </listitem> 19.1591 + <listitem><para><literal>url</literal>: A URL. The location 19.1592 + of the remote repository, if known. See section <xref 19.1593 + linkend="sec:hook:url"/> for more 19.1594 + information. 19.1595 + </para> 19.1596 + </listitem></itemizedlist> 19.1597 + 19.1598 + <para>See also: <literal role="hook">changegroup</literal> 19.1599 + (section <xref linkend="sec:hook:changegroup"/>) <literal 19.1600 + role="hook">prechangegroup</literal> (section <xref 19.1601 + linkend="sec:hook:prechangegroup"/>), <literal 19.1602 + role="hook">pretxnchangegroup</literal> (section <xref 19.1603 + linkend="sec:hook:pretxnchangegroup"/>) 19.1604 + </para> 19.1605 + 19.1606 + </sect2> 19.1607 + <sect2 id="sec:hook:outgoing"> 19.1608 + <title><literal role="hook">outgoing</literal>&emdash;after 19.1609 + changesets are propagated</title> 19.1610 + 19.1611 + <para>This hook is run after a group of changesets has been 19.1612 + propagated out of this repository, for example by a <command 19.1613 + role="hg-cmd">hg push</command> or <command role="hg-cmd">hg 19.1614 + bundle</command> command. 19.1615 + </para> 19.1616 + 19.1617 + <para>One possible use for this hook is to notify administrators 19.1618 + that changes have been pulled. 19.1619 + </para> 19.1620 + 19.1621 + <para>Parameters to this hook: 19.1622 + </para> 19.1623 + <itemizedlist> 19.1624 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1625 + changeset ID of the first changeset of the group that was 19.1626 + sent. 19.1627 + </para> 19.1628 + </listitem> 19.1629 + <listitem><para><literal>source</literal>: A string. The 19.1630 + source of the of the operation (see section <xref 19.1631 + linkend="sec:hook:sources"/>). If a remote 19.1632 + client pulled changes from this repository, 19.1633 + <literal>source</literal> will be 19.1634 + <literal>serve</literal>. If the client that obtained 19.1635 + changes from this repository was local, 19.1636 + <literal>source</literal> will be 19.1637 + <literal>bundle</literal>, <literal>pull</literal>, or 19.1638 + <literal>push</literal>, depending on the operation the 19.1639 + client performed. 19.1640 + </para> 19.1641 + </listitem> 19.1642 + <listitem><para><literal>url</literal>: A URL. The location 19.1643 + of the remote repository, if known. See section <xref 19.1644 + linkend="sec:hook:url"/> for more 19.1645 + information. 19.1646 + </para> 19.1647 + </listitem></itemizedlist> 19.1648 + 19.1649 + <para>See also: <literal role="hook">preoutgoing</literal> 19.1650 + (section <xref linkend="sec:hook:preoutgoing"/>) 19.1651 + </para> 19.1652 + 19.1653 + </sect2> 19.1654 + <sect2 id="sec:hook:prechangegroup"> 19.1655 + <title><literal 19.1656 + role="hook">prechangegroup</literal>&emdash;before starting 19.1657 + to add remote changesets</title> 19.1658 + 19.1659 + <para>This controlling hook is run before Mercurial begins to 19.1660 + add a group of changesets from another repository. 19.1661 + </para> 19.1662 + 19.1663 + <para>This hook does not have any information about the 19.1664 + changesets to be added, because it is run before transmission 19.1665 + of those changesets is allowed to begin. If this hook fails, 19.1666 + the changesets will not be transmitted. 19.1667 + </para> 19.1668 + 19.1669 + <para>One use for this hook is to prevent external changes from 19.1670 + being added to a repository. For example, you could use this 19.1671 + to <quote>freeze</quote> a server-hosted branch temporarily or 19.1672 + permanently so that users cannot push to it, while still 19.1673 + allowing a local administrator to modify the repository. 19.1674 + </para> 19.1675 + 19.1676 + <para>Parameters to this hook: 19.1677 + </para> 19.1678 + <itemizedlist> 19.1679 + <listitem><para><literal>source</literal>: A string. The 19.1680 + source of these changes. See section <xref 19.1681 + linkend="sec:hook:sources"/> for details. 19.1682 + </para> 19.1683 + </listitem> 19.1684 + <listitem><para><literal>url</literal>: A URL. The location 19.1685 + of the remote repository, if known. See section <xref 19.1686 + linkend="sec:hook:url"/> for more 19.1687 + information. 19.1688 + </para> 19.1689 + </listitem></itemizedlist> 19.1690 + 19.1691 + <para>See also: <literal role="hook">changegroup</literal> 19.1692 + (section <xref linkend="sec:hook:changegroup"/>), <literal 19.1693 + role="hook">incoming</literal> (section <xref 19.1694 + linkend="sec:hook:incoming"/>), , <literal 19.1695 + role="hook">pretxnchangegroup</literal> (section <xref 19.1696 + linkend="sec:hook:pretxnchangegroup"/>) 19.1697 + </para> 19.1698 + 19.1699 + </sect2> 19.1700 + <sect2 id="sec:hook:precommit"> 19.1701 + <title><literal role="hook">precommit</literal>&emdash;before 19.1702 + starting to commit a changeset</title> 19.1703 + 19.1704 + <para>This hook is run before Mercurial begins to commit a new 19.1705 + changeset. It is run before Mercurial has any of the metadata 19.1706 + for the commit, such as the files to be committed, the commit 19.1707 + message, or the commit date. 19.1708 + </para> 19.1709 + 19.1710 + <para>One use for this hook is to disable the ability to commit 19.1711 + new changesets, while still allowing incoming changesets. 19.1712 + Another is to run a build or test, and only allow the commit 19.1713 + to begin if the build or test succeeds. 19.1714 + </para> 19.1715 + 19.1716 + <para>Parameters to this hook: 19.1717 + </para> 19.1718 + <itemizedlist> 19.1719 + <listitem><para><literal>parent1</literal>: A changeset ID. 19.1720 + The changeset ID of the first parent of the working 19.1721 + directory. 19.1722 + </para> 19.1723 + </listitem> 19.1724 + <listitem><para><literal>parent2</literal>: A changeset ID. 19.1725 + The changeset ID of the second parent of the working 19.1726 + directory. 19.1727 + </para> 19.1728 + </listitem></itemizedlist> 19.1729 + <para>If the commit proceeds, the parents of the working 19.1730 + directory will become the parents of the new changeset. 19.1731 + </para> 19.1732 + 19.1733 + <para>See also: <literal role="hook">commit</literal> (section 19.1734 + <xref linkend="sec:hook:commit"/>), <literal 19.1735 + role="hook">pretxncommit</literal> (section <xref 19.1736 + linkend="sec:hook:pretxncommit"/>) 19.1737 + </para> 19.1738 + 19.1739 + </sect2> 19.1740 + <sect2 id="sec:hook:preoutgoing"> 19.1741 + <title><literal role="hook">preoutgoing</literal>&emdash;before 19.1742 + starting to propagate changesets</title> 19.1743 + 19.1744 + <para>This hook is invoked before Mercurial knows the identities 19.1745 + of the changesets to be transmitted. 19.1746 + </para> 19.1747 + 19.1748 + <para>One use for this hook is to prevent changes from being 19.1749 + transmitted to another repository. 19.1750 + </para> 19.1751 + 19.1752 + <para>Parameters to this hook: 19.1753 + </para> 19.1754 + <itemizedlist> 19.1755 + <listitem><para><literal>source</literal>: A string. The 19.1756 + source of the operation that is attempting to obtain 19.1757 + changes from this repository (see section <xref 19.1758 + linkend="sec:hook:sources"/>). See the documentation 19.1759 + for the <literal>source</literal> parameter to the 19.1760 + <literal role="hook">outgoing</literal> hook, in section 19.1761 + <xref linkend="sec:hook:outgoing"/>, for possible values 19.1762 + of 19.1763 + this parameter. 19.1764 + </para> 19.1765 + </listitem> 19.1766 + <listitem><para><literal>url</literal>: A URL. The location 19.1767 + of the remote repository, if known. See section <xref 19.1768 + linkend="sec:hook:url"/> for more 19.1769 + information. 19.1770 + </para> 19.1771 + </listitem></itemizedlist> 19.1772 + 19.1773 + <para>See also: <literal role="hook">outgoing</literal> (section 19.1774 + <xref linkend="sec:hook:outgoing"/>) 19.1775 + </para> 19.1776 + 19.1777 + </sect2> 19.1778 + <sect2 id="sec:hook:pretag"> 19.1779 + <title><literal role="hook">pretag</literal>&emdash;before 19.1780 + tagging a changeset</title> 19.1781 + 19.1782 + <para>This controlling hook is run before a tag is created. If 19.1783 + the hook succeeds, creation of the tag proceeds. If the hook 19.1784 + fails, the tag is not created. 19.1785 + </para> 19.1786 + 19.1787 + <para>Parameters to this hook: 19.1788 + </para> 19.1789 + <itemizedlist> 19.1790 + <listitem><para><literal>local</literal>: A boolean. Whether 19.1791 + the tag is local to this repository instance (i.e. stored 19.1792 + in <filename role="special">.hg/localtags</filename>) or 19.1793 + managed by Mercurial (stored in <filename 19.1794 + role="special">.hgtags</filename>). 19.1795 + </para> 19.1796 + </listitem> 19.1797 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1798 + ID of the changeset to be tagged. 19.1799 + </para> 19.1800 + </listitem> 19.1801 + <listitem><para><literal>tag</literal>: A string. The name of 19.1802 + the tag to be created. 19.1803 + </para> 19.1804 + </listitem></itemizedlist> 19.1805 + 19.1806 + <para>If the tag to be created is revision-controlled, the 19.1807 + <literal role="hook">precommit</literal> and <literal 19.1808 + role="hook">pretxncommit</literal> hooks (sections <xref 19.1809 + linkend="sec:hook:commit"/> and <xref 19.1810 + linkend="sec:hook:pretxncommit"/>) will also be run. 19.1811 + </para> 19.1812 + 19.1813 + <para>See also: <literal role="hook">tag</literal> (section 19.1814 + <xref linkend="sec:hook:tag"/>) 19.1815 + </para> 19.1816 + </sect2> 19.1817 + <sect2 id="sec:hook:pretxnchangegroup"> 19.1818 + <title><literal 19.1819 + role="hook">pretxnchangegroup</literal>&emdash;before 19.1820 + completing addition of remote changesets</title> 19.1821 + 19.1822 + <para>This controlling hook is run before a 19.1823 + transaction&emdash;that manages the addition of a group of new 19.1824 + changesets from outside the repository&emdash;completes. If 19.1825 + the hook succeeds, the transaction completes, and all of the 19.1826 + changesets become permanent within this repository. If the 19.1827 + hook fails, the transaction is rolled back, and the data for 19.1828 + the changesets is erased. 19.1829 + </para> 19.1830 + 19.1831 + <para>This hook can access the metadata associated with the 19.1832 + almost-added changesets, but it should not do anything 19.1833 + permanent with this data. It must also not modify the working 19.1834 + directory. 19.1835 + </para> 19.1836 + 19.1837 + <para>While this hook is running, if other Mercurial processes 19.1838 + access this repository, they will be able to see the 19.1839 + almost-added changesets as if they are permanent. This may 19.1840 + lead to race conditions if you do not take steps to avoid 19.1841 + them. 19.1842 + </para> 19.1843 + 19.1844 + <para>This hook can be used to automatically vet a group of 19.1845 + changesets. If the hook fails, all of the changesets are 19.1846 + <quote>rejected</quote> when the transaction rolls back. 19.1847 + </para> 19.1848 + 19.1849 + <para>Parameters to this hook: 19.1850 + </para> 19.1851 + <itemizedlist> 19.1852 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1853 + changeset ID of the first changeset in the group that was 19.1854 + added. All changesets between this and 19.1855 + <literal role="tag">tip</literal>, 19.1856 + inclusive, were added by a single <command 19.1857 + role="hg-cmd">hg pull</command>, <command 19.1858 + role="hg-cmd">hg push</command> or <command 19.1859 + role="hg-cmd">hg unbundle</command>. 19.1860 + </para> 19.1861 + </listitem> 19.1862 + <listitem><para><literal>source</literal>: A string. The 19.1863 + source of these changes. See section <xref 19.1864 + linkend="sec:hook:sources"/> for details. 19.1865 + </para> 19.1866 + </listitem> 19.1867 + <listitem><para><literal>url</literal>: A URL. The location 19.1868 + of the remote repository, if known. See section <xref 19.1869 + linkend="sec:hook:url"/> for more 19.1870 + information. 19.1871 + </para> 19.1872 + </listitem></itemizedlist> 19.1873 + 19.1874 + <para>See also: <literal role="hook">changegroup</literal> 19.1875 + (section <xref linkend="sec:hook:changegroup"/>), <literal 19.1876 + role="hook">incoming</literal> (section <xref 19.1877 + linkend="sec:hook:incoming"/>), <literal 19.1878 + role="hook">prechangegroup</literal> (section <xref 19.1879 + linkend="sec:hook:prechangegroup"/>) 19.1880 + </para> 19.1881 + 19.1882 + </sect2> 19.1883 + <sect2 id="sec:hook:pretxncommit"> 19.1884 + <title><literal role="hook">pretxncommit</literal>&emdash;before 19.1885 + completing commit of new changeset</title> 19.1886 + 19.1887 + <para>This controlling hook is run before a 19.1888 + transaction&emdash;that manages a new commit&emdash;completes. 19.1889 + If the hook succeeds, the transaction completes and the 19.1890 + changeset becomes permanent within this repository. If the 19.1891 + hook fails, the transaction is rolled back, and the commit 19.1892 + data is erased. 19.1893 + </para> 19.1894 + 19.1895 + <para>This hook can access the metadata associated with the 19.1896 + almost-new changeset, but it should not do anything permanent 19.1897 + with this data. It must also not modify the working 19.1898 + directory. 19.1899 + </para> 19.1900 + 19.1901 + <para>While this hook is running, if other Mercurial processes 19.1902 + access this repository, they will be able to see the 19.1903 + almost-new changeset as if it is permanent. This may lead to 19.1904 + race conditions if you do not take steps to avoid them. 19.1905 + </para> 19.1906 + 19.1907 + <para>Parameters to this hook: 19.1908 + </para> 19.1909 + <itemizedlist> 19.1910 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1911 + changeset ID of the newly committed changeset. 19.1912 + </para> 19.1913 + </listitem> 19.1914 + <listitem><para><literal>parent1</literal>: A changeset ID. 19.1915 + The changeset ID of the first parent of the newly 19.1916 + committed changeset. 19.1917 + </para> 19.1918 + </listitem> 19.1919 + <listitem><para><literal>parent2</literal>: A changeset ID. 19.1920 + The changeset ID of the second parent of the newly 19.1921 + committed changeset. 19.1922 + </para> 19.1923 + </listitem></itemizedlist> 19.1924 + 19.1925 + <para>See also: <literal role="hook">precommit</literal> 19.1926 + (section <xref linkend="sec:hook:precommit"/>) 19.1927 + </para> 19.1928 + 19.1929 + </sect2> 19.1930 + <sect2 id="sec:hook:preupdate"> 19.1931 + <title><literal role="hook">preupdate</literal>&emdash;before 19.1932 + updating or merging working directory</title> 19.1933 + 19.1934 + <para>This controlling hook is run before an update or merge of 19.1935 + the working directory begins. It is run only if Mercurial's 19.1936 + normal pre-update checks determine that the update or merge 19.1937 + can proceed. If the hook succeeds, the update or merge may 19.1938 + proceed; if it fails, the update or merge does not start. 19.1939 + </para> 19.1940 + 19.1941 + <para>Parameters to this hook: 19.1942 + </para> 19.1943 + <itemizedlist> 19.1944 + <listitem><para><literal>parent1</literal>: A changeset ID. 19.1945 + The ID of the parent that the working directory is to be 19.1946 + updated to. If the working directory is being merged, it 19.1947 + will not change this parent. 19.1948 + </para> 19.1949 + </listitem> 19.1950 + <listitem><para><literal>parent2</literal>: A changeset ID. 19.1951 + Only set if the working directory is being merged. The ID 19.1952 + of the revision that the working directory is being merged 19.1953 + with. 19.1954 + </para> 19.1955 + </listitem></itemizedlist> 19.1956 + 19.1957 + <para>See also: <literal role="hook">update</literal> (section 19.1958 + <xref linkend="sec:hook:update"/>) 19.1959 + </para> 19.1960 + 19.1961 + </sect2> 19.1962 + <sect2 id="sec:hook:tag"> 19.1963 + <title><literal role="hook">tag</literal>&emdash;after tagging a 19.1964 + changeset</title> 19.1965 + 19.1966 + <para>This hook is run after a tag has been created. 19.1967 + </para> 19.1968 + 19.1969 + <para>Parameters to this hook: 19.1970 + </para> 19.1971 + <itemizedlist> 19.1972 + <listitem><para><literal>local</literal>: A boolean. Whether 19.1973 + the new tag is local to this repository instance (i.e. 19.1974 + stored in <filename 19.1975 + role="special">.hg/localtags</filename>) or managed by 19.1976 + Mercurial (stored in <filename 19.1977 + role="special">.hgtags</filename>). 19.1978 + </para> 19.1979 + </listitem> 19.1980 + <listitem><para><literal>node</literal>: A changeset ID. The 19.1981 + ID of the changeset that was tagged. 19.1982 + </para> 19.1983 + </listitem> 19.1984 + <listitem><para><literal>tag</literal>: A string. The name of 19.1985 + the tag that was created. 19.1986 + </para> 19.1987 + </listitem></itemizedlist> 19.1988 + 19.1989 + <para>If the created tag is revision-controlled, the <literal 19.1990 + role="hook">commit</literal> hook (section <xref 19.1991 + linkend="sec:hook:commit"/>) is run before this hook. 19.1992 + </para> 19.1993 + 19.1994 + <para>See also: <literal role="hook">pretag</literal> (section 19.1995 + <xref linkend="sec:hook:pretag"/>) 19.1996 + </para> 19.1997 + 19.1998 + </sect2> 19.1999 + <sect2 id="sec:hook:update"> 19.2000 + <title><literal role="hook">update</literal>&emdash;after 19.2001 + updating or merging working directory</title> 19.2002 + 19.2003 + <para>This hook is run after an update or merge of the working 19.2004 + directory completes. Since a merge can fail (if the external 19.2005 + <command>hgmerge</command> command fails to resolve conflicts 19.2006 + in a file), this hook communicates whether the update or merge 19.2007 + completed cleanly. 19.2008 + </para> 19.2009 + 19.2010 + <itemizedlist> 19.2011 + <listitem><para><literal>error</literal>: A boolean. 19.2012 + Indicates whether the update or merge completed 19.2013 + successfully. 19.2014 + </para> 19.2015 + </listitem> 19.2016 + <listitem><para><literal>parent1</literal>: A changeset ID. 19.2017 + The ID of the parent that the working directory was 19.2018 + updated to. If the working directory was merged, it will 19.2019 + not have changed this parent. 19.2020 + </para> 19.2021 + </listitem> 19.2022 + <listitem><para><literal>parent2</literal>: A changeset ID. 19.2023 + Only set if the working directory was merged. The ID of 19.2024 + the revision that the working directory was merged with. 19.2025 + </para> 19.2026 + </listitem></itemizedlist> 19.2027 + 19.2028 + <para>See also: <literal role="hook">preupdate</literal> 19.2029 + (section <xref linkend="sec:hook:preupdate"/>) 19.2030 + </para> 19.2031 + 19.2032 + </sect2> 19.2033 + </sect1> 19.2034 +</chapter> 19.2035 + 19.2036 +<!-- 19.2037 +local variables: 19.2038 +sgml-parent-document: ("00book.xml" "book" "chapter") 19.2039 +end: 19.2040 +-->
20.1 --- a/en/ch09-undo.xml Wed Mar 18 00:08:22 2009 -0700 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,1072 +0,0 @@ 20.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 20.5 - 20.6 -<chapter id="chap:undo"> 20.7 - <?dbhtml filename="finding-and-fixing-mistakes.html"?> 20.8 - <title>Finding and fixing mistakes</title> 20.9 - 20.10 - <para>To err might be human, but to really handle the consequences 20.11 - well takes a top-notch revision control system. In this chapter, 20.12 - we'll discuss some of the techniques you can use when you find 20.13 - that a problem has crept into your project. Mercurial has some 20.14 - highly capable features that will help you to isolate the sources 20.15 - of problems, and to handle them appropriately.</para> 20.16 - 20.17 - <sect1> 20.18 - <title>Erasing local history</title> 20.19 - 20.20 - <sect2> 20.21 - <title>The accidental commit</title> 20.22 - 20.23 - <para>I have the occasional but persistent problem of typing 20.24 - rather more quickly than I can think, which sometimes results 20.25 - in me committing a changeset that is either incomplete or 20.26 - plain wrong. In my case, the usual kind of incomplete 20.27 - changeset is one in which I've created a new source file, but 20.28 - forgotten to <command role="hg-cmd">hg add</command> it. A 20.29 - <quote>plain wrong</quote> changeset is not as common, but no 20.30 - less annoying.</para> 20.31 - 20.32 - </sect2> 20.33 - <sect2 id="sec:undo:rollback"> 20.34 - <title>Rolling back a transaction</title> 20.35 - 20.36 - <para>In section <xref linkend="sec:concepts:txn"/>, I mentioned 20.37 - that Mercurial treats each modification of a repository as a 20.38 - <emphasis>transaction</emphasis>. Every time you commit a 20.39 - changeset or pull changes from another repository, Mercurial 20.40 - remembers what you did. You can undo, or <emphasis>roll 20.41 - back</emphasis>, exactly one of these actions using the 20.42 - <command role="hg-cmd">hg rollback</command> command. (See 20.43 - section <xref linkend="sec:undo:rollback-after-push"/> for an 20.44 - important caveat about the use of this command.)</para> 20.45 - 20.46 - <para>Here's a mistake that I often find myself making: 20.47 - committing a change in which I've created a new file, but 20.48 - forgotten to <command role="hg-cmd">hg add</command> 20.49 - it.</para> 20.50 - 20.51 - &interaction.rollback.commit; 20.52 - 20.53 - <para>Looking at the output of <command role="hg-cmd">hg 20.54 - status</command> after the commit immediately confirms the 20.55 - error.</para> 20.56 - 20.57 - &interaction.rollback.status; 20.58 - 20.59 - <para>The commit captured the changes to the file 20.60 - <filename>a</filename>, but not the new file 20.61 - <filename>b</filename>. If I were to push this changeset to a 20.62 - repository that I shared with a colleague, the chances are 20.63 - high that something in <filename>a</filename> would refer to 20.64 - <filename>b</filename>, which would not be present in their 20.65 - repository when they pulled my changes. I would thus become 20.66 - the object of some indignation.</para> 20.67 - 20.68 - <para>However, luck is with me&emdash;I've caught my error 20.69 - before I pushed the changeset. I use the <command 20.70 - role="hg-cmd">hg rollback</command> command, and Mercurial 20.71 - makes that last changeset vanish.</para> 20.72 - 20.73 - &interaction.rollback.rollback; 20.74 - 20.75 - <para>Notice that the changeset is no longer present in the 20.76 - repository's history, and the working directory once again 20.77 - thinks that the file <filename>a</filename> is modified. The 20.78 - commit and rollback have left the working directory exactly as 20.79 - it was prior to the commit; the changeset has been completely 20.80 - erased. I can now safely <command role="hg-cmd">hg 20.81 - add</command> the file <filename>b</filename>, and rerun my 20.82 - commit.</para> 20.83 - 20.84 - &interaction.rollback.add; 20.85 - 20.86 - </sect2> 20.87 - <sect2> 20.88 - <title>The erroneous pull</title> 20.89 - 20.90 - <para>It's common practice with Mercurial to maintain separate 20.91 - development branches of a project in different repositories. 20.92 - Your development team might have one shared repository for 20.93 - your project's <quote>0.9</quote> release, and another, 20.94 - containing different changes, for the <quote>1.0</quote> 20.95 - release.</para> 20.96 - 20.97 - <para>Given this, you can imagine that the consequences could be 20.98 - messy if you had a local <quote>0.9</quote> repository, and 20.99 - accidentally pulled changes from the shared <quote>1.0</quote> 20.100 - repository into it. At worst, you could be paying 20.101 - insufficient attention, and push those changes into the shared 20.102 - <quote>0.9</quote> tree, confusing your entire team (but don't 20.103 - worry, we'll return to this horror scenario later). However, 20.104 - it's more likely that you'll notice immediately, because 20.105 - Mercurial will display the URL it's pulling from, or you will 20.106 - see it pull a suspiciously large number of changes into the 20.107 - repository.</para> 20.108 - 20.109 - <para>The <command role="hg-cmd">hg rollback</command> command 20.110 - will work nicely to expunge all of the changesets that you 20.111 - just pulled. Mercurial groups all changes from one <command 20.112 - role="hg-cmd">hg pull</command> into a single transaction, 20.113 - so one <command role="hg-cmd">hg rollback</command> is all you 20.114 - need to undo this mistake.</para> 20.115 - 20.116 - </sect2> 20.117 - <sect2 id="sec:undo:rollback-after-push"> 20.118 - <title>Rolling back is useless once you've pushed</title> 20.119 - 20.120 - <para>The value of the <command role="hg-cmd">hg 20.121 - rollback</command> command drops to zero once you've pushed 20.122 - your changes to another repository. Rolling back a change 20.123 - makes it disappear entirely, but <emphasis>only</emphasis> in 20.124 - the repository in which you perform the <command 20.125 - role="hg-cmd">hg rollback</command>. Because a rollback 20.126 - eliminates history, there's no way for the disappearance of a 20.127 - change to propagate between repositories.</para> 20.128 - 20.129 - <para>If you've pushed a change to another 20.130 - repository&emdash;particularly if it's a shared 20.131 - repository&emdash;it has essentially <quote>escaped into the 20.132 - wild,</quote> and you'll have to recover from your mistake 20.133 - in a different way. What will happen if you push a changeset 20.134 - somewhere, then roll it back, then pull from the repository 20.135 - you pushed to, is that the changeset will reappear in your 20.136 - repository.</para> 20.137 - 20.138 - <para>(If you absolutely know for sure that the change you want 20.139 - to roll back is the most recent change in the repository that 20.140 - you pushed to, <emphasis>and</emphasis> you know that nobody 20.141 - else could have pulled it from that repository, you can roll 20.142 - back the changeset there, too, but you really should really 20.143 - not rely on this working reliably. If you do this, sooner or 20.144 - later a change really will make it into a repository that you 20.145 - don't directly control (or have forgotten about), and come 20.146 - back to bite you.)</para> 20.147 - 20.148 - </sect2> 20.149 - <sect2> 20.150 - <title>You can only roll back once</title> 20.151 - 20.152 - <para>Mercurial stores exactly one transaction in its 20.153 - transaction log; that transaction is the most recent one that 20.154 - occurred in the repository. This means that you can only roll 20.155 - back one transaction. If you expect to be able to roll back 20.156 - one transaction, then its predecessor, this is not the 20.157 - behaviour you will get.</para> 20.158 - 20.159 - &interaction.rollback.twice; 20.160 - 20.161 - <para>Once you've rolled back one transaction in a repository, 20.162 - you can't roll back again in that repository until you perform 20.163 - another commit or pull.</para> 20.164 - 20.165 - </sect2> 20.166 - </sect1> 20.167 - <sect1> 20.168 - <title>Reverting the mistaken change</title> 20.169 - 20.170 - <para>If you make a modification to a file, and decide that you 20.171 - really didn't want to change the file at all, and you haven't 20.172 - yet committed your changes, the <command role="hg-cmd">hg 20.173 - revert</command> command is the one you'll need. It looks at 20.174 - the changeset that's the parent of the working directory, and 20.175 - restores the contents of the file to their state as of that 20.176 - changeset. (That's a long-winded way of saying that, in the 20.177 - normal case, it undoes your modifications.)</para> 20.178 - 20.179 - <para>Let's illustrate how the <command role="hg-cmd">hg 20.180 - revert</command> command works with yet another small example. 20.181 - We'll begin by modifying a file that Mercurial is already 20.182 - tracking.</para> 20.183 - 20.184 - &interaction.daily.revert.modify; 20.185 - 20.186 - <para>If we don't 20.187 - want that change, we can simply <command role="hg-cmd">hg 20.188 - revert</command> the file.</para> 20.189 - 20.190 - &interaction.daily.revert.unmodify; 20.191 - 20.192 - <para>The <command role="hg-cmd">hg revert</command> command 20.193 - provides us with an extra degree of safety by saving our 20.194 - modified file with a <filename>.orig</filename> 20.195 - extension.</para> 20.196 - 20.197 - &interaction.daily.revert.status; 20.198 - 20.199 - <para>Here is a summary of the cases that the <command 20.200 - role="hg-cmd">hg revert</command> command can deal with. We 20.201 - will describe each of these in more detail in the section that 20.202 - follows.</para> 20.203 - <itemizedlist> 20.204 - <listitem><para>If you modify a file, it will restore the file 20.205 - to its unmodified state.</para> 20.206 - </listitem> 20.207 - <listitem><para>If you <command role="hg-cmd">hg add</command> a 20.208 - file, it will undo the <quote>added</quote> state of the 20.209 - file, but leave the file itself untouched.</para> 20.210 - </listitem> 20.211 - <listitem><para>If you delete a file without telling Mercurial, 20.212 - it will restore the file to its unmodified contents.</para> 20.213 - </listitem> 20.214 - <listitem><para>If you use the <command role="hg-cmd">hg 20.215 - remove</command> command to remove a file, it will undo 20.216 - the <quote>removed</quote> state of the file, and restore 20.217 - the file to its unmodified contents.</para> 20.218 - </listitem></itemizedlist> 20.219 - 20.220 - <sect2 id="sec:undo:mgmt"> 20.221 - <title>File management errors</title> 20.222 - 20.223 - <para>The <command role="hg-cmd">hg revert</command> command is 20.224 - useful for more than just modified files. It lets you reverse 20.225 - the results of all of Mercurial's file management 20.226 - commands&emdash;<command role="hg-cmd">hg add</command>, 20.227 - <command role="hg-cmd">hg remove</command>, and so on.</para> 20.228 - 20.229 - <para>If you <command role="hg-cmd">hg add</command> a file, 20.230 - then decide that in fact you don't want Mercurial to track it, 20.231 - use <command role="hg-cmd">hg revert</command> to undo the 20.232 - add. Don't worry; Mercurial will not modify the file in any 20.233 - way. It will just <quote>unmark</quote> the file.</para> 20.234 - 20.235 - &interaction.daily.revert.add; 20.236 - 20.237 - <para>Similarly, if you ask Mercurial to <command 20.238 - role="hg-cmd">hg remove</command> a file, you can use 20.239 - <command role="hg-cmd">hg revert</command> to restore it to 20.240 - the contents it had as of the parent of the working directory. 20.241 - &interaction.daily.revert.remove; This works just as 20.242 - well for a file that you deleted by hand, without telling 20.243 - Mercurial (recall that in Mercurial terminology, this kind of 20.244 - file is called <quote>missing</quote>).</para> 20.245 - 20.246 - &interaction.daily.revert.missing; 20.247 - 20.248 - <para>If you revert a <command role="hg-cmd">hg copy</command>, 20.249 - the copied-to file remains in your working directory 20.250 - afterwards, untracked. Since a copy doesn't affect the 20.251 - copied-from file in any way, Mercurial doesn't do anything 20.252 - with the copied-from file.</para> 20.253 - 20.254 - &interaction.daily.revert.copy; 20.255 - 20.256 - <sect3> 20.257 - <title>A slightly special case: reverting a rename</title> 20.258 - 20.259 - <para>If you <command role="hg-cmd">hg rename</command> a 20.260 - file, there is one small detail that you should remember. 20.261 - When you <command role="hg-cmd">hg revert</command> a 20.262 - rename, it's not enough to provide the name of the 20.263 - renamed-to file, as you can see here.</para> 20.264 - 20.265 - &interaction.daily.revert.rename; 20.266 - 20.267 - <para>As you can see from the output of <command 20.268 - role="hg-cmd">hg status</command>, the renamed-to file is 20.269 - no longer identified as added, but the 20.270 - renamed-<emphasis>from</emphasis> file is still removed! 20.271 - This is counter-intuitive (at least to me), but at least 20.272 - it's easy to deal with.</para> 20.273 - 20.274 - &interaction.daily.revert.rename-orig; 20.275 - 20.276 - <para>So remember, to revert a <command role="hg-cmd">hg 20.277 - rename</command>, you must provide 20.278 - <emphasis>both</emphasis> the source and destination 20.279 - names.</para> 20.280 - 20.281 - <para>% TODO: the output doesn't look like it will be 20.282 - removed!</para> 20.283 - 20.284 - <para>(By the way, if you rename a file, then modify the 20.285 - renamed-to file, then revert both components of the rename, 20.286 - when Mercurial restores the file that was removed as part of 20.287 - the rename, it will be unmodified. If you need the 20.288 - modifications in the renamed-to file to show up in the 20.289 - renamed-from file, don't forget to copy them over.)</para> 20.290 - 20.291 - <para>These fiddly aspects of reverting a rename arguably 20.292 - constitute a small bug in Mercurial.</para> 20.293 - 20.294 - </sect3> 20.295 - </sect2> 20.296 - </sect1> 20.297 - <sect1> 20.298 - <title>Dealing with committed changes</title> 20.299 - 20.300 - <para>Consider a case where you have committed a change $a$, and 20.301 - another change $b$ on top of it; you then realise that change 20.302 - $a$ was incorrect. Mercurial lets you <quote>back out</quote> 20.303 - an entire changeset automatically, and building blocks that let 20.304 - you reverse part of a changeset by hand.</para> 20.305 - 20.306 - <para>Before you read this section, here's something to keep in 20.307 - mind: the <command role="hg-cmd">hg backout</command> command 20.308 - undoes changes by <emphasis>adding</emphasis> history, not by 20.309 - modifying or erasing it. It's the right tool to use if you're 20.310 - fixing bugs, but not if you're trying to undo some change that 20.311 - has catastrophic consequences. To deal with those, see section 20.312 - <xref linkend="sec:undo:aaaiiieee"/>.</para> 20.313 - 20.314 - <sect2> 20.315 - <title>Backing out a changeset</title> 20.316 - 20.317 - <para>The <command role="hg-cmd">hg backout</command> command 20.318 - lets you <quote>undo</quote> the effects of an entire 20.319 - changeset in an automated fashion. Because Mercurial's 20.320 - history is immutable, this command <emphasis>does 20.321 - not</emphasis> get rid of the changeset you want to undo. 20.322 - Instead, it creates a new changeset that 20.323 - <emphasis>reverses</emphasis> the effect of the to-be-undone 20.324 - changeset.</para> 20.325 - 20.326 - <para>The operation of the <command role="hg-cmd">hg 20.327 - backout</command> command is a little intricate, so let's 20.328 - illustrate it with some examples. First, we'll create a 20.329 - repository with some simple changes.</para> 20.330 - 20.331 - &interaction.backout.init; 20.332 - 20.333 - <para>The <command role="hg-cmd">hg backout</command> command 20.334 - takes a single changeset ID as its argument; this is the 20.335 - changeset to back out. Normally, <command role="hg-cmd">hg 20.336 - backout</command> will drop you into a text editor to write 20.337 - a commit message, so you can record why you're backing the 20.338 - change out. In this example, we provide a commit message on 20.339 - the command line using the <option 20.340 - role="hg-opt-backout">-m</option> option.</para> 20.341 - 20.342 - </sect2> 20.343 - <sect2> 20.344 - <title>Backing out the tip changeset</title> 20.345 - 20.346 - <para>We're going to start by backing out the last changeset we 20.347 - committed.</para> 20.348 - 20.349 - &interaction.backout.simple; 20.350 - 20.351 - <para>You can see that the second line from 20.352 - <filename>myfile</filename> is no longer present. Taking a 20.353 - look at the output of <command role="hg-cmd">hg log</command> 20.354 - gives us an idea of what the <command role="hg-cmd">hg 20.355 - backout</command> command has done. 20.356 - &interaction.backout.simple.log; Notice that the new changeset 20.357 - that <command role="hg-cmd">hg backout</command> has created 20.358 - is a child of the changeset we backed out. It's easier to see 20.359 - this in figure <xref 20.360 - linkend="fig:undo:backout"/>, which presents a graphical 20.361 - view of the change history. As you can see, the history is 20.362 - nice and linear.</para> 20.363 - 20.364 - <informalfigure id="fig:undo:backout"> 20.365 - <mediaobject><imageobject><imagedata 20.366 - fileref="undo-simple"/></imageobject><textobject><phrase>XXX 20.367 - add text</phrase></textobject><caption><para>Backing out 20.368 - a change using the <command role="hg-cmd">hg 20.369 - backout</command> 20.370 - command</para></caption></mediaobject> 20.371 - 20.372 - </informalfigure> 20.373 - 20.374 - </sect2> 20.375 - <sect2> 20.376 - <title>Backing out a non-tip change</title> 20.377 - 20.378 - <para>If you want to back out a change other than the last one 20.379 - you committed, pass the <option 20.380 - role="hg-opt-backout">--merge</option> option to the 20.381 - <command role="hg-cmd">hg backout</command> command.</para> 20.382 - 20.383 - &interaction.backout.non-tip.clone; 20.384 - 20.385 - <para>This makes backing out any changeset a 20.386 - <quote>one-shot</quote> operation that's usually simple and 20.387 - fast.</para> 20.388 - 20.389 - &interaction.backout.non-tip.backout; 20.390 - 20.391 - <para>If you take a look at the contents of 20.392 - <filename>myfile</filename> after the backout finishes, you'll 20.393 - see that the first and third changes are present, but not the 20.394 - second.</para> 20.395 - 20.396 - &interaction.backout.non-tip.cat; 20.397 - 20.398 - <para>As the graphical history in figure <xref 20.399 - linkend="fig:undo:backout-non-tip"/> illustrates, Mercurial 20.400 - actually commits <emphasis>two</emphasis> changes in this kind 20.401 - of situation (the box-shaped nodes are the ones that Mercurial 20.402 - commits automatically). Before Mercurial begins the backout 20.403 - process, it first remembers what the current parent of the 20.404 - working directory is. It then backs out the target changeset, 20.405 - and commits that as a changeset. Finally, it merges back to 20.406 - the previous parent of the working directory, and commits the 20.407 - result of the merge.</para> 20.408 - 20.409 - <para>% TODO: to me it looks like mercurial doesn't commit the 20.410 - second merge automatically!</para> 20.411 - 20.412 - <informalfigure id="fig:undo:backout-non-tip"> 20.413 - <mediaobject><imageobject><imagedata 20.414 - fileref="undo-non-tip"/></imageobject><textobject><phrase>XXX 20.415 - add text</phrase></textobject><caption><para>Automated 20.416 - backout of a non-tip change using the <command 20.417 - role="hg-cmd">hg backout</command> 20.418 - command</para></caption></mediaobject> 20.419 - </informalfigure> 20.420 - 20.421 - <para>The result is that you end up <quote>back where you 20.422 - were</quote>, only with some extra history that undoes the 20.423 - effect of the changeset you wanted to back out.</para> 20.424 - 20.425 - <sect3> 20.426 - <title>Always use the <option 20.427 - role="hg-opt-backout">--merge</option> option</title> 20.428 - 20.429 - <para>In fact, since the <option 20.430 - role="hg-opt-backout">--merge</option> option will do the 20.431 - <quote>right thing</quote> whether or not the changeset 20.432 - you're backing out is the tip (i.e. it won't try to merge if 20.433 - it's backing out the tip, since there's no need), you should 20.434 - <emphasis>always</emphasis> use this option when you run the 20.435 - <command role="hg-cmd">hg backout</command> command.</para> 20.436 - 20.437 - </sect3> 20.438 - </sect2> 20.439 - <sect2> 20.440 - <title>Gaining more control of the backout process</title> 20.441 - 20.442 - <para>While I've recommended that you always use the <option 20.443 - role="hg-opt-backout">--merge</option> option when backing 20.444 - out a change, the <command role="hg-cmd">hg backout</command> 20.445 - command lets you decide how to merge a backout changeset. 20.446 - Taking control of the backout process by hand is something you 20.447 - will rarely need to do, but it can be useful to understand 20.448 - what the <command role="hg-cmd">hg backout</command> command 20.449 - is doing for you automatically. To illustrate this, let's 20.450 - clone our first repository, but omit the backout change that 20.451 - it contains.</para> 20.452 - 20.453 - &interaction.backout.manual.clone; 20.454 - 20.455 - <para>As with our 20.456 - earlier example, We'll commit a third changeset, then back out 20.457 - its parent, and see what happens.</para> 20.458 - 20.459 - &interaction.backout.manual.backout; 20.460 - 20.461 - <para>Our new changeset is again a descendant of the changeset 20.462 - we backout out; it's thus a new head, <emphasis>not</emphasis> 20.463 - a descendant of the changeset that was the tip. The <command 20.464 - role="hg-cmd">hg backout</command> command was quite 20.465 - explicit in telling us this.</para> 20.466 - 20.467 - &interaction.backout.manual.log; 20.468 - 20.469 - <para>Again, it's easier to see what has happened by looking at 20.470 - a graph of the revision history, in figure <xref 20.471 - linkend="fig:undo:backout-manual"/>. This makes it clear 20.472 - that when we use <command role="hg-cmd">hg backout</command> 20.473 - to back out a change other than the tip, Mercurial adds a new 20.474 - head to the repository (the change it committed is 20.475 - box-shaped).</para> 20.476 - 20.477 - <informalfigure id="fig:undo:backout-manual"> 20.478 - <mediaobject><imageobject><imagedata 20.479 - fileref="undo-manual"/></imageobject><textobject><phrase>XXX 20.480 - add text</phrase></textobject><caption><para>Backing out 20.481 - a change using the <command role="hg-cmd">hg 20.482 - backout</command> 20.483 - command</para></caption></mediaobject> 20.484 - 20.485 - </informalfigure> 20.486 - 20.487 - <para>After the <command role="hg-cmd">hg backout</command> 20.488 - command has completed, it leaves the new 20.489 - <quote>backout</quote> changeset as the parent of the working 20.490 - directory.</para> 20.491 - 20.492 - &interaction.backout.manual.parents; 20.493 - 20.494 - <para>Now we have two isolated sets of changes.</para> 20.495 - 20.496 - &interaction.backout.manual.heads; 20.497 - 20.498 - <para>Let's think about what we expect to see as the contents of 20.499 - <filename>myfile</filename> now. The first change should be 20.500 - present, because we've never backed it out. The second change 20.501 - should be missing, as that's the change we backed out. Since 20.502 - the history graph shows the third change as a separate head, 20.503 - we <emphasis>don't</emphasis> expect to see the third change 20.504 - present in <filename>myfile</filename>.</para> 20.505 - 20.506 - &interaction.backout.manual.cat; 20.507 - 20.508 - <para>To get the third change back into the file, we just do a 20.509 - normal merge of our two heads.</para> 20.510 - 20.511 - &interaction.backout.manual.merge; 20.512 - 20.513 - <para>Afterwards, the graphical history of our repository looks 20.514 - like figure 20.515 - <xref linkend="fig:undo:backout-manual-merge"/>.</para> 20.516 - 20.517 - <informalfigure id="fig:undo:backout-manual-merge"> 20.518 - <mediaobject><imageobject><imagedata 20.519 - fileref="undo-manual-merge"/></imageobject><textobject><phrase>XXX 20.520 - add text</phrase></textobject><caption><para>Manually 20.521 - merging a backout change</para></caption></mediaobject> 20.522 - 20.523 - </informalfigure> 20.524 - 20.525 - </sect2> 20.526 - <sect2> 20.527 - <title>Why <command role="hg-cmd">hg backout</command> works as 20.528 - it does</title> 20.529 - 20.530 - <para>Here's a brief description of how the <command 20.531 - role="hg-cmd">hg backout</command> command works.</para> 20.532 - <orderedlist> 20.533 - <listitem><para>It ensures that the working directory is 20.534 - <quote>clean</quote>, i.e. that the output of <command 20.535 - role="hg-cmd">hg status</command> would be empty.</para> 20.536 - </listitem> 20.537 - <listitem><para>It remembers the current parent of the working 20.538 - directory. Let's call this changeset 20.539 - <literal>orig</literal></para> 20.540 - </listitem> 20.541 - <listitem><para>It does the equivalent of a <command 20.542 - role="hg-cmd">hg update</command> to sync the working 20.543 - directory to the changeset you want to back out. Let's 20.544 - call this changeset <literal>backout</literal></para> 20.545 - </listitem> 20.546 - <listitem><para>It finds the parent of that changeset. Let's 20.547 - call that changeset <literal>parent</literal>.</para> 20.548 - </listitem> 20.549 - <listitem><para>For each file that the 20.550 - <literal>backout</literal> changeset affected, it does the 20.551 - equivalent of a <command role="hg-cmd">hg revert -r 20.552 - parent</command> on that file, to restore it to the 20.553 - contents it had before that changeset was 20.554 - committed.</para> 20.555 - </listitem> 20.556 - <listitem><para>It commits the result as a new changeset. 20.557 - This changeset has <literal>backout</literal> as its 20.558 - parent.</para> 20.559 - </listitem> 20.560 - <listitem><para>If you specify <option 20.561 - role="hg-opt-backout">--merge</option> on the command 20.562 - line, it merges with <literal>orig</literal>, and commits 20.563 - the result of the merge.</para> 20.564 - </listitem></orderedlist> 20.565 - 20.566 - <para>An alternative way to implement the <command 20.567 - role="hg-cmd">hg backout</command> command would be to 20.568 - <command role="hg-cmd">hg export</command> the 20.569 - to-be-backed-out changeset as a diff, then use the <option 20.570 - role="cmd-opt-patch">--reverse</option> option to the 20.571 - <command>patch</command> command to reverse the effect of the 20.572 - change without fiddling with the working directory. This 20.573 - sounds much simpler, but it would not work nearly as 20.574 - well.</para> 20.575 - 20.576 - <para>The reason that <command role="hg-cmd">hg 20.577 - backout</command> does an update, a commit, a merge, and 20.578 - another commit is to give the merge machinery the best chance 20.579 - to do a good job when dealing with all the changes 20.580 - <emphasis>between</emphasis> the change you're backing out and 20.581 - the current tip.</para> 20.582 - 20.583 - <para>If you're backing out a changeset that's 100 revisions 20.584 - back in your project's history, the chances that the 20.585 - <command>patch</command> command will be able to apply a 20.586 - reverse diff cleanly are not good, because intervening changes 20.587 - are likely to have <quote>broken the context</quote> that 20.588 - <command>patch</command> uses to determine whether it can 20.589 - apply a patch (if this sounds like gibberish, see <xref 20.590 - linkend="sec:mq:patch"/> for a 20.591 - discussion of the <command>patch</command> command). Also, 20.592 - Mercurial's merge machinery will handle files and directories 20.593 - being renamed, permission changes, and modifications to binary 20.594 - files, none of which <command>patch</command> can deal 20.595 - with.</para> 20.596 - 20.597 - </sect2> 20.598 - </sect1> 20.599 - <sect1 id="sec:undo:aaaiiieee"> 20.600 - <title>Changes that should never have been</title> 20.601 - 20.602 - <para>Most of the time, the <command role="hg-cmd">hg 20.603 - backout</command> command is exactly what you need if you want 20.604 - to undo the effects of a change. It leaves a permanent record 20.605 - of exactly what you did, both when committing the original 20.606 - changeset and when you cleaned up after it.</para> 20.607 - 20.608 - <para>On rare occasions, though, you may find that you've 20.609 - committed a change that really should not be present in the 20.610 - repository at all. For example, it would be very unusual, and 20.611 - usually considered a mistake, to commit a software project's 20.612 - object files as well as its source files. Object files have 20.613 - almost no intrinsic value, and they're <emphasis>big</emphasis>, 20.614 - so they increase the size of the repository and the amount of 20.615 - time it takes to clone or pull changes.</para> 20.616 - 20.617 - <para>Before I discuss the options that you have if you commit a 20.618 - <quote>brown paper bag</quote> change (the kind that's so bad 20.619 - that you want to pull a brown paper bag over your head), let me 20.620 - first discuss some approaches that probably won't work.</para> 20.621 - 20.622 - <para>Since Mercurial treats history as accumulative&emdash;every 20.623 - change builds on top of all changes that preceded it&emdash;you 20.624 - generally can't just make disastrous changes disappear. The one 20.625 - exception is when you've just committed a change, and it hasn't 20.626 - been pushed or pulled into another repository. That's when you 20.627 - can safely use the <command role="hg-cmd">hg rollback</command> 20.628 - command, as I detailed in section <xref 20.629 - linkend="sec:undo:rollback"/>.</para> 20.630 - 20.631 - <para>After you've pushed a bad change to another repository, you 20.632 - <emphasis>could</emphasis> still use <command role="hg-cmd">hg 20.633 - rollback</command> to make your local copy of the change 20.634 - disappear, but it won't have the consequences you want. The 20.635 - change will still be present in the remote repository, so it 20.636 - will reappear in your local repository the next time you 20.637 - pull.</para> 20.638 - 20.639 - <para>If a situation like this arises, and you know which 20.640 - repositories your bad change has propagated into, you can 20.641 - <emphasis>try</emphasis> to get rid of the changeefrom 20.642 - <emphasis>every</emphasis> one of those repositories. This is, 20.643 - of course, not a satisfactory solution: if you miss even a 20.644 - single repository while you're expunging, the change is still 20.645 - <quote>in the wild</quote>, and could propagate further.</para> 20.646 - 20.647 - <para>If you've committed one or more changes 20.648 - <emphasis>after</emphasis> the change that you'd like to see 20.649 - disappear, your options are further reduced. Mercurial doesn't 20.650 - provide a way to <quote>punch a hole</quote> in history, leaving 20.651 - changesets intact.</para> 20.652 - 20.653 - <para>XXX This needs filling out. The 20.654 - <literal>hg-replay</literal> script in the 20.655 - <literal>examples</literal> directory works, but doesn't handle 20.656 - merge changesets. Kind of an important omission.</para> 20.657 - 20.658 - <sect2> 20.659 - <title>Protect yourself from <quote>escaped</quote> 20.660 - changes</title> 20.661 - 20.662 - <para>If you've committed some changes to your local repository 20.663 - and they've been pushed or pulled somewhere else, this isn't 20.664 - necessarily a disaster. You can protect yourself ahead of 20.665 - time against some classes of bad changeset. This is 20.666 - particularly easy if your team usually pulls changes from a 20.667 - central repository.</para> 20.668 - 20.669 - <para>By configuring some hooks on that repository to validate 20.670 - incoming changesets (see chapter <xref linkend="chap:hook"/>), 20.671 - you can 20.672 - automatically prevent some kinds of bad changeset from being 20.673 - pushed to the central repository at all. With such a 20.674 - configuration in place, some kinds of bad changeset will 20.675 - naturally tend to <quote>die out</quote> because they can't 20.676 - propagate into the central repository. Better yet, this 20.677 - happens without any need for explicit intervention.</para> 20.678 - 20.679 - <para>For instance, an incoming change hook that verifies that a 20.680 - changeset will actually compile can prevent people from 20.681 - inadvertantly <quote>breaking the build</quote>.</para> 20.682 - 20.683 - </sect2> 20.684 - </sect1> 20.685 - <sect1 id="sec:undo:bisect"> 20.686 - <title>Finding the source of a bug</title> 20.687 - 20.688 - <para>While it's all very well to be able to back out a changeset 20.689 - that introduced a bug, this requires that you know which 20.690 - changeset to back out. Mercurial provides an invaluable 20.691 - command, called <command role="hg-cmd">hg bisect</command>, that 20.692 - helps you to automate this process and accomplish it very 20.693 - efficiently.</para> 20.694 - 20.695 - <para>The idea behind the <command role="hg-cmd">hg 20.696 - bisect</command> command is that a changeset has introduced 20.697 - some change of behaviour that you can identify with a simple 20.698 - binary test. You don't know which piece of code introduced the 20.699 - change, but you know how to test for the presence of the bug. 20.700 - The <command role="hg-cmd">hg bisect</command> command uses your 20.701 - test to direct its search for the changeset that introduced the 20.702 - code that caused the bug.</para> 20.703 - 20.704 - <para>Here are a few scenarios to help you understand how you 20.705 - might apply this command.</para> 20.706 - <itemizedlist> 20.707 - <listitem><para>The most recent version of your software has a 20.708 - bug that you remember wasn't present a few weeks ago, but 20.709 - you don't know when it was introduced. Here, your binary 20.710 - test checks for the presence of that bug.</para> 20.711 - </listitem> 20.712 - <listitem><para>You fixed a bug in a rush, and now it's time to 20.713 - close the entry in your team's bug database. The bug 20.714 - database requires a changeset ID when you close an entry, 20.715 - but you don't remember which changeset you fixed the bug in. 20.716 - Once again, your binary test checks for the presence of the 20.717 - bug.</para> 20.718 - </listitem> 20.719 - <listitem><para>Your software works correctly, but runs 15% 20.720 - slower than the last time you measured it. You want to know 20.721 - which changeset introduced the performance regression. In 20.722 - this case, your binary test measures the performance of your 20.723 - software, to see whether it's <quote>fast</quote> or 20.724 - <quote>slow</quote>.</para> 20.725 - </listitem> 20.726 - <listitem><para>The sizes of the components of your project that 20.727 - you ship exploded recently, and you suspect that something 20.728 - changed in the way you build your project.</para> 20.729 - </listitem></itemizedlist> 20.730 - 20.731 - <para>From these examples, it should be clear that the <command 20.732 - role="hg-cmd">hg bisect</command> command is not useful only 20.733 - for finding the sources of bugs. You can use it to find any 20.734 - <quote>emergent property</quote> of a repository (anything that 20.735 - you can't find from a simple text search of the files in the 20.736 - tree) for which you can write a binary test.</para> 20.737 - 20.738 - <para>We'll introduce a little bit of terminology here, just to 20.739 - make it clear which parts of the search process are your 20.740 - responsibility, and which are Mercurial's. A 20.741 - <emphasis>test</emphasis> is something that 20.742 - <emphasis>you</emphasis> run when <command role="hg-cmd">hg 20.743 - bisect</command> chooses a changeset. A 20.744 - <emphasis>probe</emphasis> is what <command role="hg-cmd">hg 20.745 - bisect</command> runs to tell whether a revision is good. 20.746 - Finally, we'll use the word <quote>bisect</quote>, as both a 20.747 - noun and a verb, to stand in for the phrase <quote>search using 20.748 - the <command role="hg-cmd">hg bisect</command> 20.749 - command</quote>.</para> 20.750 - 20.751 - <para>One simple way to automate the searching process would be 20.752 - simply to probe every changeset. However, this scales poorly. 20.753 - If it took ten minutes to test a single changeset, and you had 20.754 - 10,000 changesets in your repository, the exhaustive approach 20.755 - would take on average 35 <emphasis>days</emphasis> to find the 20.756 - changeset that introduced a bug. Even if you knew that the bug 20.757 - was introduced by one of the last 500 changesets, and limited 20.758 - your search to those, you'd still be looking at over 40 hours to 20.759 - find the changeset that introduced your bug.</para> 20.760 - 20.761 - <para>What the <command role="hg-cmd">hg bisect</command> command 20.762 - does is use its knowledge of the <quote>shape</quote> of your 20.763 - project's revision history to perform a search in time 20.764 - proportional to the <emphasis>logarithm</emphasis> of the number 20.765 - of changesets to check (the kind of search it performs is called 20.766 - a dichotomic search). With this approach, searching through 20.767 - 10,000 changesets will take less than three hours, even at ten 20.768 - minutes per test (the search will require about 14 tests). 20.769 - Limit your search to the last hundred changesets, and it will 20.770 - take only about an hour (roughly seven tests).</para> 20.771 - 20.772 - <para>The <command role="hg-cmd">hg bisect</command> command is 20.773 - aware of the <quote>branchy</quote> nature of a Mercurial 20.774 - project's revision history, so it has no problems dealing with 20.775 - branches, merges, or multiple heads in a repository. It can 20.776 - prune entire branches of history with a single probe, which is 20.777 - how it operates so efficiently.</para> 20.778 - 20.779 - <sect2> 20.780 - <title>Using the <command role="hg-cmd">hg bisect</command> 20.781 - command</title> 20.782 - 20.783 - <para>Here's an example of <command role="hg-cmd">hg 20.784 - bisect</command> in action.</para> 20.785 - 20.786 - <note> 20.787 - <para> In versions 0.9.5 and earlier of Mercurial, <command 20.788 - role="hg-cmd">hg bisect</command> was not a core command: 20.789 - it was distributed with Mercurial as an extension. This 20.790 - section describes the built-in command, not the old 20.791 - extension.</para> 20.792 - </note> 20.793 - 20.794 - <para>Now let's create a repository, so that we can try out the 20.795 - <command role="hg-cmd">hg bisect</command> command in 20.796 - isolation.</para> 20.797 - 20.798 - &interaction.bisect.init; 20.799 - 20.800 - <para>We'll simulate a project that has a bug in it in a 20.801 - simple-minded way: create trivial changes in a loop, and 20.802 - nominate one specific change that will have the 20.803 - <quote>bug</quote>. This loop creates 35 changesets, each 20.804 - adding a single file to the repository. We'll represent our 20.805 - <quote>bug</quote> with a file that contains the text <quote>i 20.806 - have a gub</quote>.</para> 20.807 - 20.808 - &interaction.bisect.commits; 20.809 - 20.810 - <para>The next thing that we'd like to do is figure out how to 20.811 - use the <command role="hg-cmd">hg bisect</command> command. 20.812 - We can use Mercurial's normal built-in help mechanism for 20.813 - this.</para> 20.814 - 20.815 - &interaction.bisect.help; 20.816 - 20.817 - <para>The <command role="hg-cmd">hg bisect</command> command 20.818 - works in steps. Each step proceeds as follows.</para> 20.819 - <orderedlist> 20.820 - <listitem><para>You run your binary test.</para> 20.821 - <itemizedlist> 20.822 - <listitem><para>If the test succeeded, you tell <command 20.823 - role="hg-cmd">hg bisect</command> by running the 20.824 - <command role="hg-cmd">hg bisect good</command> 20.825 - command.</para> 20.826 - </listitem> 20.827 - <listitem><para>If it failed, run the <command 20.828 - role="hg-cmd">hg bisect bad</command> 20.829 - command.</para></listitem></itemizedlist> 20.830 - </listitem> 20.831 - <listitem><para>The command uses your information to decide 20.832 - which changeset to test next.</para> 20.833 - </listitem> 20.834 - <listitem><para>It updates the working directory to that 20.835 - changeset, and the process begins again.</para> 20.836 - </listitem></orderedlist> 20.837 - <para>The process ends when <command role="hg-cmd">hg 20.838 - bisect</command> identifies a unique changeset that marks 20.839 - the point where your test transitioned from 20.840 - <quote>succeeding</quote> to <quote>failing</quote>.</para> 20.841 - 20.842 - <para>To start the search, we must run the <command 20.843 - role="hg-cmd">hg bisect --reset</command> command.</para> 20.844 - 20.845 - &interaction.bisect.search.init; 20.846 - 20.847 - <para>In our case, the binary test we use is simple: we check to 20.848 - see if any file in the repository contains the string <quote>i 20.849 - have a gub</quote>. If it does, this changeset contains the 20.850 - change that <quote>caused the bug</quote>. By convention, a 20.851 - changeset that has the property we're searching for is 20.852 - <quote>bad</quote>, while one that doesn't is 20.853 - <quote>good</quote>.</para> 20.854 - 20.855 - <para>Most of the time, the revision to which the working 20.856 - directory is synced (usually the tip) already exhibits the 20.857 - problem introduced by the buggy change, so we'll mark it as 20.858 - <quote>bad</quote>.</para> 20.859 - 20.860 - &interaction.bisect.search.bad-init; 20.861 - 20.862 - <para>Our next task is to nominate a changeset that we know 20.863 - <emphasis>doesn't</emphasis> have the bug; the <command 20.864 - role="hg-cmd">hg bisect</command> command will 20.865 - <quote>bracket</quote> its search between the first pair of 20.866 - good and bad changesets. In our case, we know that revision 20.867 - 10 didn't have the bug. (I'll have more words about choosing 20.868 - the first <quote>good</quote> changeset later.)</para> 20.869 - 20.870 - &interaction.bisect.search.good-init; 20.871 - 20.872 - <para>Notice that this command printed some output.</para> 20.873 - <itemizedlist> 20.874 - <listitem><para>It told us how many changesets it must 20.875 - consider before it can identify the one that introduced 20.876 - the bug, and how many tests that will require.</para> 20.877 - </listitem> 20.878 - <listitem><para>It updated the working directory to the next 20.879 - changeset to test, and told us which changeset it's 20.880 - testing.</para> 20.881 - </listitem></itemizedlist> 20.882 - 20.883 - <para>We now run our test in the working directory. We use the 20.884 - <command>grep</command> command to see if our 20.885 - <quote>bad</quote> file is present in the working directory. 20.886 - If it is, this revision is bad; if not, this revision is good. 20.887 - &interaction.bisect.search.step1;</para> 20.888 - 20.889 - <para>This test looks like a perfect candidate for automation, 20.890 - so let's turn it into a shell function.</para> 20.891 - &interaction.bisect.search.mytest; 20.892 - 20.893 - <para>We can now run an entire test step with a single command, 20.894 - <literal>mytest</literal>.</para> 20.895 - 20.896 - &interaction.bisect.search.step2; 20.897 - 20.898 - <para>A few more invocations of our canned test step command, 20.899 - and we're done.</para> 20.900 - 20.901 - &interaction.bisect.search.rest; 20.902 - 20.903 - <para>Even though we had 40 changesets to search through, the 20.904 - <command role="hg-cmd">hg bisect</command> command let us find 20.905 - the changeset that introduced our <quote>bug</quote> with only 20.906 - five tests. Because the number of tests that the <command 20.907 - role="hg-cmd">hg bisect</command> command performs grows 20.908 - logarithmically with the number of changesets to search, the 20.909 - advantage that it has over the <quote>brute force</quote> 20.910 - search approach increases with every changeset you add.</para> 20.911 - 20.912 - </sect2> 20.913 - <sect2> 20.914 - <title>Cleaning up after your search</title> 20.915 - 20.916 - <para>When you're finished using the <command role="hg-cmd">hg 20.917 - bisect</command> command in a repository, you can use the 20.918 - <command role="hg-cmd">hg bisect reset</command> command to 20.919 - drop the information it was using to drive your search. The 20.920 - command doesn't use much space, so it doesn't matter if you 20.921 - forget to run this command. However, <command 20.922 - role="hg-cmd">hg bisect</command> won't let you start a new 20.923 - search in that repository until you do a <command 20.924 - role="hg-cmd">hg bisect reset</command>.</para> 20.925 - 20.926 - &interaction.bisect.search.reset; 20.927 - 20.928 - </sect2> 20.929 - </sect1> 20.930 - <sect1> 20.931 - <title>Tips for finding bugs effectively</title> 20.932 - 20.933 - <sect2> 20.934 - <title>Give consistent input</title> 20.935 - 20.936 - <para>The <command role="hg-cmd">hg bisect</command> command 20.937 - requires that you correctly report the result of every test 20.938 - you perform. If you tell it that a test failed when it really 20.939 - succeeded, it <emphasis>might</emphasis> be able to detect the 20.940 - inconsistency. If it can identify an inconsistency in your 20.941 - reports, it will tell you that a particular changeset is both 20.942 - good and bad. However, it can't do this perfectly; it's about 20.943 - as likely to report the wrong changeset as the source of the 20.944 - bug.</para> 20.945 - 20.946 - </sect2> 20.947 - <sect2> 20.948 - <title>Automate as much as possible</title> 20.949 - 20.950 - <para>When I started using the <command role="hg-cmd">hg 20.951 - bisect</command> command, I tried a few times to run my 20.952 - tests by hand, on the command line. This is an approach that 20.953 - I, at least, am not suited to. After a few tries, I found 20.954 - that I was making enough mistakes that I was having to restart 20.955 - my searches several times before finally getting correct 20.956 - results.</para> 20.957 - 20.958 - <para>My initial problems with driving the <command 20.959 - role="hg-cmd">hg bisect</command> command by hand occurred 20.960 - even with simple searches on small repositories; if the 20.961 - problem you're looking for is more subtle, or the number of 20.962 - tests that <command role="hg-cmd">hg bisect</command> must 20.963 - perform increases, the likelihood of operator error ruining 20.964 - the search is much higher. Once I started automating my 20.965 - tests, I had much better results.</para> 20.966 - 20.967 - <para>The key to automated testing is twofold:</para> 20.968 - <itemizedlist> 20.969 - <listitem><para>always test for the same symptom, and</para> 20.970 - </listitem> 20.971 - <listitem><para>always feed consistent input to the <command 20.972 - role="hg-cmd">hg bisect</command> command.</para> 20.973 - </listitem></itemizedlist> 20.974 - <para>In my tutorial example above, the <command>grep</command> 20.975 - command tests for the symptom, and the <literal>if</literal> 20.976 - statement takes the result of this check and ensures that we 20.977 - always feed the same input to the <command role="hg-cmd">hg 20.978 - bisect</command> command. The <literal>mytest</literal> 20.979 - function marries these together in a reproducible way, so that 20.980 - every test is uniform and consistent.</para> 20.981 - 20.982 - </sect2> 20.983 - <sect2> 20.984 - <title>Check your results</title> 20.985 - 20.986 - <para>Because the output of a <command role="hg-cmd">hg 20.987 - bisect</command> search is only as good as the input you 20.988 - give it, don't take the changeset it reports as the absolute 20.989 - truth. A simple way to cross-check its report is to manually 20.990 - run your test at each of the following changesets:</para> 20.991 - <itemizedlist> 20.992 - <listitem><para>The changeset that it reports as the first bad 20.993 - revision. Your test should still report this as 20.994 - bad.</para> 20.995 - </listitem> 20.996 - <listitem><para>The parent of that changeset (either parent, 20.997 - if it's a merge). Your test should report this changeset 20.998 - as good.</para> 20.999 - </listitem> 20.1000 - <listitem><para>A child of that changeset. Your test should 20.1001 - report this changeset as bad.</para> 20.1002 - </listitem></itemizedlist> 20.1003 - 20.1004 - </sect2> 20.1005 - <sect2> 20.1006 - <title>Beware interference between bugs</title> 20.1007 - 20.1008 - <para>It's possible that your search for one bug could be 20.1009 - disrupted by the presence of another. For example, let's say 20.1010 - your software crashes at revision 100, and worked correctly at 20.1011 - revision 50. Unknown to you, someone else introduced a 20.1012 - different crashing bug at revision 60, and fixed it at 20.1013 - revision 80. This could distort your results in one of 20.1014 - several ways.</para> 20.1015 - 20.1016 - <para>It is possible that this other bug completely 20.1017 - <quote>masks</quote> yours, which is to say that it occurs 20.1018 - before your bug has a chance to manifest itself. If you can't 20.1019 - avoid that other bug (for example, it prevents your project 20.1020 - from building), and so can't tell whether your bug is present 20.1021 - in a particular changeset, the <command role="hg-cmd">hg 20.1022 - bisect</command> command cannot help you directly. Instead, 20.1023 - you can mark a changeset as untested by running <command 20.1024 - role="hg-cmd">hg bisect --skip</command>.</para> 20.1025 - 20.1026 - <para>A different problem could arise if your test for a bug's 20.1027 - presence is not specific enough. If you check for <quote>my 20.1028 - program crashes</quote>, then both your crashing bug and an 20.1029 - unrelated crashing bug that masks it will look like the same 20.1030 - thing, and mislead <command role="hg-cmd">hg 20.1031 - bisect</command>.</para> 20.1032 - 20.1033 - <para>Another useful situation in which to use <command 20.1034 - role="hg-cmd">hg bisect --skip</command> is if you can't 20.1035 - test a revision because your project was in a broken and hence 20.1036 - untestable state at that revision, perhaps because someone 20.1037 - checked in a change that prevented the project from 20.1038 - building.</para> 20.1039 - 20.1040 - </sect2> 20.1041 - <sect2> 20.1042 - <title>Bracket your search lazily</title> 20.1043 - 20.1044 - <para>Choosing the first <quote>good</quote> and 20.1045 - <quote>bad</quote> changesets that will mark the end points of 20.1046 - your search is often easy, but it bears a little discussion 20.1047 - nevertheless. From the perspective of <command 20.1048 - role="hg-cmd">hg bisect</command>, the <quote>newest</quote> 20.1049 - changeset is conventionally <quote>bad</quote>, and the older 20.1050 - changeset is <quote>good</quote>.</para> 20.1051 - 20.1052 - <para>If you're having trouble remembering when a suitable 20.1053 - <quote>good</quote> change was, so that you can tell <command 20.1054 - role="hg-cmd">hg bisect</command>, you could do worse than 20.1055 - testing changesets at random. Just remember to eliminate 20.1056 - contenders that can't possibly exhibit the bug (perhaps 20.1057 - because the feature with the bug isn't present yet) and those 20.1058 - where another problem masks the bug (as I discussed 20.1059 - above).</para> 20.1060 - 20.1061 - <para>Even if you end up <quote>early</quote> by thousands of 20.1062 - changesets or months of history, you will only add a handful 20.1063 - of tests to the total number that <command role="hg-cmd">hg 20.1064 - bisect</command> must perform, thanks to its logarithmic 20.1065 - behaviour.</para> 20.1066 - 20.1067 - </sect2> 20.1068 - </sect1> 20.1069 -</chapter> 20.1070 - 20.1071 -<!-- 20.1072 -local variables: 20.1073 -sgml-parent-document: ("00book.xml" "book" "chapter") 20.1074 -end: 20.1075 --->
21.1 --- a/en/ch10-hook.xml Wed Mar 18 00:08:22 2009 -0700 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,2037 +0,0 @@ 21.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 21.5 - 21.6 -<chapter id="chap:hook"> 21.7 - <?dbhtml filename="handling-repository-events-with-hooks.html"?> 21.8 - <title>Handling repository events with hooks</title> 21.9 - 21.10 - <para>Mercurial offers a powerful mechanism to let you perform 21.11 - automated actions in response to events that occur in a 21.12 - repository. In some cases, you can even control Mercurial's 21.13 - response to those events.</para> 21.14 - 21.15 - <para>The name Mercurial uses for one of these actions is a 21.16 - <emphasis>hook</emphasis>. Hooks are called 21.17 - <quote>triggers</quote> in some revision control systems, but the 21.18 - two names refer to the same idea.</para> 21.19 - 21.20 - <sect1> 21.21 - <title>An overview of hooks in Mercurial</title> 21.22 - 21.23 - <para>Here is a brief list of the hooks that Mercurial supports. 21.24 - We will revisit each of these hooks in more detail later, in 21.25 - section <xref linkend="sec:hook:ref"/>.</para> 21.26 - 21.27 - <itemizedlist> 21.28 - <listitem><para><literal role="hook">changegroup</literal>: This 21.29 - is run after a group of changesets has been brought into the 21.30 - repository from elsewhere.</para> 21.31 - </listitem> 21.32 - <listitem><para><literal role="hook">commit</literal>: This is 21.33 - run after a new changeset has been created in the local 21.34 - repository.</para> 21.35 - </listitem> 21.36 - <listitem><para><literal role="hook">incoming</literal>: This is 21.37 - run once for each new changeset that is brought into the 21.38 - repository from elsewhere. Notice the difference from 21.39 - <literal role="hook">changegroup</literal>, which is run 21.40 - once per <emphasis>group</emphasis> of changesets brought 21.41 - in.</para> 21.42 - </listitem> 21.43 - <listitem><para><literal role="hook">outgoing</literal>: This is 21.44 - run after a group of changesets has been transmitted from 21.45 - this repository.</para> 21.46 - </listitem> 21.47 - <listitem><para><literal role="hook">prechangegroup</literal>: 21.48 - This is run before starting to bring a group of changesets 21.49 - into the repository. 21.50 - </para> 21.51 - </listitem> 21.52 - <listitem><para><literal role="hook">precommit</literal>: 21.53 - Controlling. This is run before starting a commit. 21.54 - </para> 21.55 - </listitem> 21.56 - <listitem><para><literal role="hook">preoutgoing</literal>: 21.57 - Controlling. This is run before starting to transmit a group 21.58 - of changesets from this repository. 21.59 - </para> 21.60 - </listitem> 21.61 - <listitem><para><literal role="hook">pretag</literal>: 21.62 - Controlling. This is run before creating a tag. 21.63 - </para> 21.64 - </listitem> 21.65 - <listitem><para><literal 21.66 - role="hook">pretxnchangegroup</literal>: Controlling. This 21.67 - is run after a group of changesets has been brought into the 21.68 - local repository from another, but before the transaction 21.69 - completes that will make the changes permanent in the 21.70 - repository. 21.71 - </para> 21.72 - </listitem> 21.73 - <listitem><para><literal role="hook">pretxncommit</literal>: 21.74 - Controlling. This is run after a new changeset has been 21.75 - created in the local repository, but before the transaction 21.76 - completes that will make it permanent. 21.77 - </para> 21.78 - </listitem> 21.79 - <listitem><para><literal role="hook">preupdate</literal>: 21.80 - Controlling. This is run before starting an update or merge 21.81 - of the working directory. 21.82 - </para> 21.83 - </listitem> 21.84 - <listitem><para><literal role="hook">tag</literal>: This is run 21.85 - after a tag is created. 21.86 - </para> 21.87 - </listitem> 21.88 - <listitem><para><literal role="hook">update</literal>: This is 21.89 - run after an update or merge of the working directory has 21.90 - finished. 21.91 - </para> 21.92 - </listitem></itemizedlist> 21.93 - <para>Each of the hooks whose description begins with the word 21.94 - <quote>Controlling</quote> has the ability to determine whether 21.95 - an activity can proceed. If the hook succeeds, the activity may 21.96 - proceed; if it fails, the activity is either not permitted or 21.97 - undone, depending on the hook. 21.98 - </para> 21.99 - 21.100 - </sect1> 21.101 - <sect1> 21.102 - <title>Hooks and security</title> 21.103 - 21.104 - <sect2> 21.105 - <title>Hooks are run with your privileges</title> 21.106 - 21.107 - <para>When you run a Mercurial command in a repository, and the 21.108 - command causes a hook to run, that hook runs on 21.109 - <emphasis>your</emphasis> system, under 21.110 - <emphasis>your</emphasis> user account, with 21.111 - <emphasis>your</emphasis> privilege level. Since hooks are 21.112 - arbitrary pieces of executable code, you should treat them 21.113 - with an appropriate level of suspicion. Do not install a hook 21.114 - unless you are confident that you know who created it and what 21.115 - it does. 21.116 - </para> 21.117 - 21.118 - <para>In some cases, you may be exposed to hooks that you did 21.119 - not install yourself. If you work with Mercurial on an 21.120 - unfamiliar system, Mercurial will run hooks defined in that 21.121 - system's global <filename role="special">~/.hgrc</filename> 21.122 - file. 21.123 - </para> 21.124 - 21.125 - <para>If you are working with a repository owned by another 21.126 - user, Mercurial can run hooks defined in that user's 21.127 - repository, but it will still run them as <quote>you</quote>. 21.128 - For example, if you <command role="hg-cmd">hg pull</command> 21.129 - from that repository, and its <filename 21.130 - role="special">.hg/hgrc</filename> defines a local <literal 21.131 - role="hook">outgoing</literal> hook, that hook will run 21.132 - under your user account, even though you don't own that 21.133 - repository. 21.134 - </para> 21.135 - 21.136 - <note> 21.137 - <para> This only applies if you are pulling from a repository 21.138 - on a local or network filesystem. If you're pulling over 21.139 - http or ssh, any <literal role="hook">outgoing</literal> 21.140 - hook will run under whatever account is executing the server 21.141 - process, on the server. 21.142 - </para> 21.143 - </note> 21.144 - 21.145 - <para>XXX To see what hooks are defined in a repository, use the 21.146 - <command role="hg-cmd">hg config hooks</command> command. If 21.147 - you are working in one repository, but talking to another that 21.148 - you do not own (e.g. using <command role="hg-cmd">hg 21.149 - pull</command> or <command role="hg-cmd">hg 21.150 - incoming</command>), remember that it is the other 21.151 - repository's hooks you should be checking, not your own. 21.152 - </para> 21.153 - 21.154 - </sect2> 21.155 - <sect2> 21.156 - <title>Hooks do not propagate</title> 21.157 - 21.158 - <para>In Mercurial, hooks are not revision controlled, and do 21.159 - not propagate when you clone, or pull from, a repository. The 21.160 - reason for this is simple: a hook is a completely arbitrary 21.161 - piece of executable code. It runs under your user identity, 21.162 - with your privilege level, on your machine. 21.163 - </para> 21.164 - 21.165 - <para>It would be extremely reckless for any distributed 21.166 - revision control system to implement revision-controlled 21.167 - hooks, as this would offer an easily exploitable way to 21.168 - subvert the accounts of users of the revision control system. 21.169 - </para> 21.170 - 21.171 - <para>Since Mercurial does not propagate hooks, if you are 21.172 - collaborating with other people on a common project, you 21.173 - should not assume that they are using the same Mercurial hooks 21.174 - as you are, or that theirs are correctly configured. You 21.175 - should document the hooks you expect people to use. 21.176 - </para> 21.177 - 21.178 - <para>In a corporate intranet, this is somewhat easier to 21.179 - control, as you can for example provide a 21.180 - <quote>standard</quote> installation of Mercurial on an NFS 21.181 - filesystem, and use a site-wide <filename role="special">~/.hgrc</filename> file to define hooks that all users will 21.182 - see. However, this too has its limits; see below. 21.183 - </para> 21.184 - 21.185 - </sect2> 21.186 - <sect2> 21.187 - <title>Hooks can be overridden</title> 21.188 - 21.189 - <para>Mercurial allows you to override a hook definition by 21.190 - redefining the hook. You can disable it by setting its value 21.191 - to the empty string, or change its behaviour as you wish. 21.192 - </para> 21.193 - 21.194 - <para>If you deploy a system- or site-wide <filename 21.195 - role="special">~/.hgrc</filename> file that defines some 21.196 - hooks, you should thus understand that your users can disable 21.197 - or override those hooks. 21.198 - </para> 21.199 - 21.200 - </sect2> 21.201 - <sect2> 21.202 - <title>Ensuring that critical hooks are run</title> 21.203 - 21.204 - <para>Sometimes you may want to enforce a policy that you do not 21.205 - want others to be able to work around. For example, you may 21.206 - have a requirement that every changeset must pass a rigorous 21.207 - set of tests. Defining this requirement via a hook in a 21.208 - site-wide <filename role="special">~/.hgrc</filename> won't 21.209 - work for remote users on laptops, and of course local users 21.210 - can subvert it at will by overriding the hook. 21.211 - </para> 21.212 - 21.213 - <para>Instead, you can set up your policies for use of Mercurial 21.214 - so that people are expected to propagate changes through a 21.215 - well-known <quote>canonical</quote> server that you have 21.216 - locked down and configured appropriately. 21.217 - </para> 21.218 - 21.219 - <para>One way to do this is via a combination of social 21.220 - engineering and technology. Set up a restricted-access 21.221 - account; users can push changes over the network to 21.222 - repositories managed by this account, but they cannot log into 21.223 - the account and run normal shell commands. In this scenario, 21.224 - a user can commit a changeset that contains any old garbage 21.225 - they want. 21.226 - </para> 21.227 - 21.228 - <para>When someone pushes a changeset to the server that 21.229 - everyone pulls from, the server will test the changeset before 21.230 - it accepts it as permanent, and reject it if it fails to pass 21.231 - the test suite. If people only pull changes from this 21.232 - filtering server, it will serve to ensure that all changes 21.233 - that people pull have been automatically vetted. 21.234 - </para> 21.235 - 21.236 - </sect2> 21.237 - </sect1> 21.238 - <sect1> 21.239 - <title>Care with <literal>pretxn</literal> hooks in a 21.240 - shared-access repository</title> 21.241 - 21.242 - <para>If you want to use hooks to do some automated work in a 21.243 - repository that a number of people have shared access to, you 21.244 - need to be careful in how you do this. 21.245 - </para> 21.246 - 21.247 - <para>Mercurial only locks a repository when it is writing to the 21.248 - repository, and only the parts of Mercurial that write to the 21.249 - repository pay attention to locks. Write locks are necessary to 21.250 - prevent multiple simultaneous writers from scribbling on each 21.251 - other's work, corrupting the repository. 21.252 - </para> 21.253 - 21.254 - <para>Because Mercurial is careful with the order in which it 21.255 - reads and writes data, it does not need to acquire a lock when 21.256 - it wants to read data from the repository. The parts of 21.257 - Mercurial that read from the repository never pay attention to 21.258 - locks. This lockless reading scheme greatly increases 21.259 - performance and concurrency. 21.260 - </para> 21.261 - 21.262 - <para>With great performance comes a trade-off, though, one which 21.263 - has the potential to cause you trouble unless you're aware of 21.264 - it. To describe this requires a little detail about how 21.265 - Mercurial adds changesets to a repository and reads those 21.266 - changes. 21.267 - </para> 21.268 - 21.269 - <para>When Mercurial <emphasis>writes</emphasis> metadata, it 21.270 - writes it straight into the destination file. It writes file 21.271 - data first, then manifest data (which contains pointers to the 21.272 - new file data), then changelog data (which contains pointers to 21.273 - the new manifest data). Before the first write to each file, it 21.274 - stores a record of where the end of the file was in its 21.275 - transaction log. If the transaction must be rolled back, 21.276 - Mercurial simply truncates each file back to the size it was 21.277 - before the transaction began. 21.278 - </para> 21.279 - 21.280 - <para>When Mercurial <emphasis>reads</emphasis> metadata, it reads 21.281 - the changelog first, then everything else. Since a reader will 21.282 - only access parts of the manifest or file metadata that it can 21.283 - see in the changelog, it can never see partially written data. 21.284 - </para> 21.285 - 21.286 - <para>Some controlling hooks (<literal 21.287 - role="hook">pretxncommit</literal> and <literal 21.288 - role="hook">pretxnchangegroup</literal>) run when a 21.289 - transaction is almost complete. All of the metadata has been 21.290 - written, but Mercurial can still roll the transaction back and 21.291 - cause the newly-written data to disappear. 21.292 - </para> 21.293 - 21.294 - <para>If one of these hooks runs for long, it opens a window of 21.295 - time during which a reader can see the metadata for changesets 21.296 - that are not yet permanent, and should not be thought of as 21.297 - <quote>really there</quote>. The longer the hook runs, the 21.298 - longer that window is open. 21.299 - </para> 21.300 - 21.301 - <sect2> 21.302 - <title>The problem illustrated</title> 21.303 - 21.304 - <para>In principle, a good use for the <literal 21.305 - role="hook">pretxnchangegroup</literal> hook would be to 21.306 - automatically build and test incoming changes before they are 21.307 - accepted into a central repository. This could let you 21.308 - guarantee that nobody can push changes to this repository that 21.309 - <quote>break the build</quote>. But if a client can pull 21.310 - changes while they're being tested, the usefulness of the test 21.311 - is zero; an unsuspecting someone can pull untested changes, 21.312 - potentially breaking their build. 21.313 - </para> 21.314 - 21.315 - <para>The safest technological answer to this challenge is to 21.316 - set up such a <quote>gatekeeper</quote> repository as 21.317 - <emphasis>unidirectional</emphasis>. Let it take changes 21.318 - pushed in from the outside, but do not allow anyone to pull 21.319 - changes from it (use the <literal 21.320 - role="hook">preoutgoing</literal> hook to lock it down). 21.321 - Configure a <literal role="hook">changegroup</literal> hook so 21.322 - that if a build or test succeeds, the hook will push the new 21.323 - changes out to another repository that people 21.324 - <emphasis>can</emphasis> pull from. 21.325 - </para> 21.326 - 21.327 - <para>In practice, putting a centralised bottleneck like this in 21.328 - place is not often a good idea, and transaction visibility has 21.329 - nothing to do with the problem. As the size of a 21.330 - project&emdash;and the time it takes to build and 21.331 - test&emdash;grows, you rapidly run into a wall with this 21.332 - <quote>try before you buy</quote> approach, where you have 21.333 - more changesets to test than time in which to deal with them. 21.334 - The inevitable result is frustration on the part of all 21.335 - involved. 21.336 - </para> 21.337 - 21.338 - <para>An approach that scales better is to get people to build 21.339 - and test before they push, then run automated builds and tests 21.340 - centrally <emphasis>after</emphasis> a push, to be sure all is 21.341 - well. The advantage of this approach is that it does not 21.342 - impose a limit on the rate at which the repository can accept 21.343 - changes. 21.344 - </para> 21.345 - 21.346 - </sect2> 21.347 - </sect1> 21.348 - <sect1 id="sec:hook:simple"> 21.349 - <title>A short tutorial on using hooks</title> 21.350 - 21.351 - <para>It is easy to write a Mercurial hook. Let's start with a 21.352 - hook that runs when you finish a <command role="hg-cmd">hg 21.353 - commit</command>, and simply prints the hash of the changeset 21.354 - you just created. The hook is called <literal 21.355 - role="hook">commit</literal>. 21.356 - </para> 21.357 - 21.358 - <para>All hooks follow the pattern in this example.</para> 21.359 - 21.360 -&interaction.hook.simple.init; 21.361 - 21.362 - <para>You add an entry to the <literal 21.363 - role="rc-hooks">hooks</literal> section of your <filename 21.364 - role="special">~/.hgrc</filename>. On the left is the name of 21.365 - the event to trigger on; on the right is the action to take. As 21.366 - you can see, you can run an arbitrary shell command in a hook. 21.367 - Mercurial passes extra information to the hook using environment 21.368 - variables (look for <envar>HG_NODE</envar> in the example). 21.369 - </para> 21.370 - 21.371 - <sect2> 21.372 - <title>Performing multiple actions per event</title> 21.373 - 21.374 - <para>Quite often, you will want to define more than one hook 21.375 - for a particular kind of event, as shown below.</para> 21.376 - 21.377 -&interaction.hook.simple.ext; 21.378 - 21.379 - <para>Mercurial lets you do this by adding an 21.380 - <emphasis>extension</emphasis> to the end of a hook's name. 21.381 - You extend a hook's name by giving the name of the hook, 21.382 - followed by a full stop (the 21.383 - <quote><literal>.</literal></quote> character), followed by 21.384 - some more text of your choosing. For example, Mercurial will 21.385 - run both <literal>commit.foo</literal> and 21.386 - <literal>commit.bar</literal> when the 21.387 - <literal>commit</literal> event occurs. 21.388 - </para> 21.389 - 21.390 - <para>To give a well-defined order of execution when there are 21.391 - multiple hooks defined for an event, Mercurial sorts hooks by 21.392 - extension, and executes the hook commands in this sorted 21.393 - order. In the above example, it will execute 21.394 - <literal>commit.bar</literal> before 21.395 - <literal>commit.foo</literal>, and <literal>commit</literal> 21.396 - before both. 21.397 - </para> 21.398 - 21.399 - <para>It is a good idea to use a somewhat descriptive extension 21.400 - when you define a new hook. This will help you to remember 21.401 - what the hook was for. If the hook fails, you'll get an error 21.402 - message that contains the hook name and extension, so using a 21.403 - descriptive extension could give you an immediate hint as to 21.404 - why the hook failed (see section <xref 21.405 - linkend="sec:hook:perm"/> for an example). 21.406 - </para> 21.407 - 21.408 - </sect2> 21.409 - <sect2 id="sec:hook:perm"> 21.410 - <title>Controlling whether an activity can proceed</title> 21.411 - 21.412 - <para>In our earlier examples, we used the <literal 21.413 - role="hook">commit</literal> hook, which is run after a 21.414 - commit has completed. This is one of several Mercurial hooks 21.415 - that run after an activity finishes. Such hooks have no way 21.416 - of influencing the activity itself. 21.417 - </para> 21.418 - 21.419 - <para>Mercurial defines a number of events that occur before an 21.420 - activity starts; or after it starts, but before it finishes. 21.421 - Hooks that trigger on these events have the added ability to 21.422 - choose whether the activity can continue, or will abort. 21.423 - </para> 21.424 - 21.425 - <para>The <literal role="hook">pretxncommit</literal> hook runs 21.426 - after a commit has all but completed. In other words, the 21.427 - metadata representing the changeset has been written out to 21.428 - disk, but the transaction has not yet been allowed to 21.429 - complete. The <literal role="hook">pretxncommit</literal> 21.430 - hook has the ability to decide whether the transaction can 21.431 - complete, or must be rolled back. 21.432 - </para> 21.433 - 21.434 - <para>If the <literal role="hook">pretxncommit</literal> hook 21.435 - exits with a status code of zero, the transaction is allowed 21.436 - to complete; the commit finishes; and the <literal 21.437 - role="hook">commit</literal> hook is run. If the <literal 21.438 - role="hook">pretxncommit</literal> hook exits with a 21.439 - non-zero status code, the transaction is rolled back; the 21.440 - metadata representing the changeset is erased; and the 21.441 - <literal role="hook">commit</literal> hook is not run. 21.442 - </para> 21.443 - 21.444 -&interaction.hook.simple.pretxncommit; 21.445 - 21.446 - <para>The hook in the example above checks that a commit comment 21.447 - contains a bug ID. If it does, the commit can complete. If 21.448 - not, the commit is rolled back. 21.449 - </para> 21.450 - 21.451 - </sect2> 21.452 - </sect1> 21.453 - <sect1> 21.454 - <title>Writing your own hooks</title> 21.455 - 21.456 - <para>When you are writing a hook, you might find it useful to run 21.457 - Mercurial either with the <option 21.458 - role="hg-opt-global">-v</option> option, or the <envar 21.459 - role="rc-item-ui">verbose</envar> config item set to 21.460 - <quote>true</quote>. When you do so, Mercurial will print a 21.461 - message before it calls each hook. 21.462 - </para> 21.463 - 21.464 - <sect2 id="sec:hook:lang"> 21.465 - <title>Choosing how your hook should run</title> 21.466 - 21.467 - <para>You can write a hook either as a normal 21.468 - program&emdash;typically a shell script&emdash;or as a Python 21.469 - function that is executed within the Mercurial process. 21.470 - </para> 21.471 - 21.472 - <para>Writing a hook as an external program has the advantage 21.473 - that it requires no knowledge of Mercurial's internals. You 21.474 - can call normal Mercurial commands to get any added 21.475 - information you need. The trade-off is that external hooks 21.476 - are slower than in-process hooks. 21.477 - </para> 21.478 - 21.479 - <para>An in-process Python hook has complete access to the 21.480 - Mercurial API, and does not <quote>shell out</quote> to 21.481 - another process, so it is inherently faster than an external 21.482 - hook. It is also easier to obtain much of the information 21.483 - that a hook requires by using the Mercurial API than by 21.484 - running Mercurial commands. 21.485 - </para> 21.486 - 21.487 - <para>If you are comfortable with Python, or require high 21.488 - performance, writing your hooks in Python may be a good 21.489 - choice. However, when you have a straightforward hook to 21.490 - write and you don't need to care about performance (probably 21.491 - the majority of hooks), a shell script is perfectly fine. 21.492 - </para> 21.493 - 21.494 - </sect2> 21.495 - <sect2 id="sec:hook:param"> 21.496 - <title>Hook parameters</title> 21.497 - 21.498 - <para>Mercurial calls each hook with a set of well-defined 21.499 - parameters. In Python, a parameter is passed as a keyword 21.500 - argument to your hook function. For an external program, a 21.501 - parameter is passed as an environment variable. 21.502 - </para> 21.503 - 21.504 - <para>Whether your hook is written in Python or as a shell 21.505 - script, the hook-specific parameter names and values will be 21.506 - the same. A boolean parameter will be represented as a 21.507 - boolean value in Python, but as the number 1 (for 21.508 - <quote>true</quote>) or 0 (for <quote>false</quote>) as an 21.509 - environment variable for an external hook. If a hook 21.510 - parameter is named <literal>foo</literal>, the keyword 21.511 - argument for a Python hook will also be named 21.512 - <literal>foo</literal>, while the environment variable for an 21.513 - external hook will be named <literal>HG_FOO</literal>. 21.514 - </para> 21.515 - 21.516 - </sect2> 21.517 - <sect2> 21.518 - <title>Hook return values and activity control</title> 21.519 - 21.520 - <para>A hook that executes successfully must exit with a status 21.521 - of zero if external, or return boolean <quote>false</quote> if 21.522 - in-process. Failure is indicated with a non-zero exit status 21.523 - from an external hook, or an in-process hook returning boolean 21.524 - <quote>true</quote>. If an in-process hook raises an 21.525 - exception, the hook is considered to have failed. 21.526 - </para> 21.527 - 21.528 - <para>For a hook that controls whether an activity can proceed, 21.529 - zero/false means <quote>allow</quote>, while 21.530 - non-zero/true/exception means <quote>deny</quote>. 21.531 - </para> 21.532 - 21.533 - </sect2> 21.534 - <sect2> 21.535 - <title>Writing an external hook</title> 21.536 - 21.537 - <para>When you define an external hook in your <filename 21.538 - role="special">~/.hgrc</filename> and the hook is run, its 21.539 - value is passed to your shell, which interprets it. This 21.540 - means that you can use normal shell constructs in the body of 21.541 - the hook. 21.542 - </para> 21.543 - 21.544 - <para>An executable hook is always run with its current 21.545 - directory set to a repository's root directory. 21.546 - </para> 21.547 - 21.548 - <para>Each hook parameter is passed in as an environment 21.549 - variable; the name is upper-cased, and prefixed with the 21.550 - string <quote><literal>HG_</literal></quote>. 21.551 - </para> 21.552 - 21.553 - <para>With the exception of hook parameters, Mercurial does not 21.554 - set or modify any environment variables when running a hook. 21.555 - This is useful to remember if you are writing a site-wide hook 21.556 - that may be run by a number of different users with differing 21.557 - environment variables set. In multi-user situations, you 21.558 - should not rely on environment variables being set to the 21.559 - values you have in your environment when testing the hook. 21.560 - </para> 21.561 - 21.562 - </sect2> 21.563 - <sect2> 21.564 - <title>Telling Mercurial to use an in-process hook</title> 21.565 - 21.566 - <para>The <filename role="special">~/.hgrc</filename> syntax 21.567 - for defining an in-process hook is slightly different than for 21.568 - an executable hook. The value of the hook must start with the 21.569 - text <quote><literal>python:</literal></quote>, and continue 21.570 - with the fully-qualified name of a callable object to use as 21.571 - the hook's value. 21.572 - </para> 21.573 - 21.574 - <para>The module in which a hook lives is automatically imported 21.575 - when a hook is run. So long as you have the module name and 21.576 - <envar>PYTHONPATH</envar> right, it should <quote>just 21.577 - work</quote>. 21.578 - </para> 21.579 - 21.580 - <para>The following <filename role="special">~/.hgrc</filename> 21.581 - example snippet illustrates the syntax and meaning of the 21.582 - notions we just described. 21.583 - </para> 21.584 - <programlisting>[hooks] 21.585 -commit.example = python:mymodule.submodule.myhook</programlisting> 21.586 - <para>When Mercurial runs the <literal>commit.example</literal> 21.587 - hook, it imports <literal>mymodule.submodule</literal>, looks 21.588 - for the callable object named <literal>myhook</literal>, and 21.589 - calls it. 21.590 - </para> 21.591 - 21.592 - </sect2> 21.593 - <sect2> 21.594 - <title>Writing an in-process hook</title> 21.595 - 21.596 - <para>The simplest in-process hook does nothing, but illustrates 21.597 - the basic shape of the hook API: 21.598 - </para> 21.599 - <programlisting>def myhook(ui, repo, **kwargs): 21.600 - pass</programlisting> 21.601 - <para>The first argument to a Python hook is always a <literal 21.602 - role="py-mod-mercurial.ui">ui</literal> object. The second 21.603 - is a repository object; at the moment, it is always an 21.604 - instance of <literal 21.605 - role="py-mod-mercurial.localrepo">localrepository</literal>. 21.606 - Following these two arguments are other keyword arguments. 21.607 - Which ones are passed in depends on the hook being called, but 21.608 - a hook can ignore arguments it doesn't care about by dropping 21.609 - them into a keyword argument dict, as with 21.610 - <literal>**kwargs</literal> above. 21.611 - </para> 21.612 - 21.613 - </sect2> 21.614 - </sect1> 21.615 - <sect1> 21.616 - <title>Some hook examples</title> 21.617 - 21.618 - <sect2> 21.619 - <title>Writing meaningful commit messages</title> 21.620 - 21.621 - <para>It's hard to imagine a useful commit message being very 21.622 - short. The simple <literal role="hook">pretxncommit</literal> 21.623 - hook of the example below will prevent you from committing a 21.624 - changeset with a message that is less than ten bytes long. 21.625 - </para> 21.626 - 21.627 -&interaction.hook.msglen.go; 21.628 - 21.629 - </sect2> 21.630 - <sect2> 21.631 - <title>Checking for trailing whitespace</title> 21.632 - 21.633 - <para>An interesting use of a commit-related hook is to help you 21.634 - to write cleaner code. A simple example of <quote>cleaner 21.635 - code</quote> is the dictum that a change should not add any 21.636 - new lines of text that contain <quote>trailing 21.637 - whitespace</quote>. Trailing whitespace is a series of 21.638 - space and tab characters at the end of a line of text. In 21.639 - most cases, trailing whitespace is unnecessary, invisible 21.640 - noise, but it is occasionally problematic, and people often 21.641 - prefer to get rid of it. 21.642 - </para> 21.643 - 21.644 - <para>You can use either the <literal 21.645 - role="hook">precommit</literal> or <literal 21.646 - role="hook">pretxncommit</literal> hook to tell whether you 21.647 - have a trailing whitespace problem. If you use the <literal 21.648 - role="hook">precommit</literal> hook, the hook will not know 21.649 - which files you are committing, so it will have to check every 21.650 - modified file in the repository for trailing white space. If 21.651 - you want to commit a change to just the file 21.652 - <filename>foo</filename>, but the file 21.653 - <filename>bar</filename> contains trailing whitespace, doing a 21.654 - check in the <literal role="hook">precommit</literal> hook 21.655 - will prevent you from committing <filename>foo</filename> due 21.656 - to the problem with <filename>bar</filename>. This doesn't 21.657 - seem right. 21.658 - </para> 21.659 - 21.660 - <para>Should you choose the <literal 21.661 - role="hook">pretxncommit</literal> hook, the check won't 21.662 - occur until just before the transaction for the commit 21.663 - completes. This will allow you to check for problems only the 21.664 - exact files that are being committed. However, if you entered 21.665 - the commit message interactively and the hook fails, the 21.666 - transaction will roll back; you'll have to re-enter the commit 21.667 - message after you fix the trailing whitespace and run <command 21.668 - role="hg-cmd">hg commit</command> again. 21.669 - </para> 21.670 - 21.671 -&interaction.hook.ws.simple; 21.672 - 21.673 - <para>In this example, we introduce a simple <literal 21.674 - role="hook">pretxncommit</literal> hook that checks for 21.675 - trailing whitespace. This hook is short, but not very 21.676 - helpful. It exits with an error status if a change adds a 21.677 - line with trailing whitespace to any file, but does not print 21.678 - any information that might help us to identify the offending 21.679 - file or line. It also has the nice property of not paying 21.680 - attention to unmodified lines; only lines that introduce new 21.681 - trailing whitespace cause problems. 21.682 - </para> 21.683 - 21.684 - <para>The above version is much more complex, but also more 21.685 - useful. It parses a unified diff to see if any lines add 21.686 - trailing whitespace, and prints the name of the file and the 21.687 - line number of each such occurrence. Even better, if the 21.688 - change adds trailing whitespace, this hook saves the commit 21.689 - comment and prints the name of the save file before exiting 21.690 - and telling Mercurial to roll the transaction back, so you can 21.691 - use the <option role="hg-opt-commit">-l filename</option> 21.692 - option to <command role="hg-cmd">hg commit</command> to reuse 21.693 - the saved commit message once you've corrected the problem. 21.694 - </para> 21.695 - 21.696 -&interaction.hook.ws.better; 21.697 - 21.698 - <para>As a final aside, note in the example above the use of 21.699 - <command>perl</command>'s in-place editing feature to get rid 21.700 - of trailing whitespace from a file. This is concise and 21.701 - useful enough that I will reproduce it here. 21.702 - </para> 21.703 - <programlisting>perl -pi -e 's,\s+$,,' filename</programlisting> 21.704 - 21.705 - </sect2> 21.706 - </sect1> 21.707 - <sect1> 21.708 - <title>Bundled hooks</title> 21.709 - 21.710 - <para>Mercurial ships with several bundled hooks. You can find 21.711 - them in the <filename class="directory">hgext</filename> 21.712 - directory of a Mercurial source tree. If you are using a 21.713 - Mercurial binary package, the hooks will be located in the 21.714 - <filename class="directory">hgext</filename> directory of 21.715 - wherever your package installer put Mercurial. 21.716 - </para> 21.717 - 21.718 - <sect2> 21.719 - <title><literal role="hg-ext">acl</literal>&emdash;access 21.720 - control for parts of a repository</title> 21.721 - 21.722 - <para>The <literal role="hg-ext">acl</literal> extension lets 21.723 - you control which remote users are allowed to push changesets 21.724 - to a networked server. You can protect any portion of a 21.725 - repository (including the entire repo), so that a specific 21.726 - remote user can push changes that do not affect the protected 21.727 - portion. 21.728 - </para> 21.729 - 21.730 - <para>This extension implements access control based on the 21.731 - identity of the user performing a push, 21.732 - <emphasis>not</emphasis> on who committed the changesets 21.733 - they're pushing. It makes sense to use this hook only if you 21.734 - have a locked-down server environment that authenticates 21.735 - remote users, and you want to be sure that only specific users 21.736 - are allowed to push changes to that server. 21.737 - </para> 21.738 - 21.739 - <sect3> 21.740 - <title>Configuring the <literal role="hook">acl</literal> 21.741 - hook</title> 21.742 - 21.743 - <para>In order to manage incoming changesets, the <literal 21.744 - role="hg-ext">acl</literal> hook must be used as a 21.745 - <literal role="hook">pretxnchangegroup</literal> hook. This 21.746 - lets it see which files are modified by each incoming 21.747 - changeset, and roll back a group of changesets if they 21.748 - modify <quote>forbidden</quote> files. Example: 21.749 - </para> 21.750 - <programlisting>[hooks] 21.751 -pretxnchangegroup.acl = python:hgext.acl.hook</programlisting> 21.752 - 21.753 - <para>The <literal role="hg-ext">acl</literal> extension is 21.754 - configured using three sections. 21.755 - </para> 21.756 - 21.757 - <para>The <literal role="rc-acl">acl</literal> section has 21.758 - only one entry, <envar role="rc-item-acl">sources</envar>, 21.759 - which lists the sources of incoming changesets that the hook 21.760 - should pay attention to. You don't normally need to 21.761 - configure this section. 21.762 - </para> 21.763 - <itemizedlist> 21.764 - <listitem><para><envar role="rc-item-acl">serve</envar>: 21.765 - Control incoming changesets that are arriving from a 21.766 - remote repository over http or ssh. This is the default 21.767 - value of <envar role="rc-item-acl">sources</envar>, and 21.768 - usually the only setting you'll need for this 21.769 - configuration item. 21.770 - </para> 21.771 - </listitem> 21.772 - <listitem><para><envar role="rc-item-acl">pull</envar>: 21.773 - Control incoming changesets that are arriving via a pull 21.774 - from a local repository. 21.775 - </para> 21.776 - </listitem> 21.777 - <listitem><para><envar role="rc-item-acl">push</envar>: 21.778 - Control incoming changesets that are arriving via a push 21.779 - from a local repository. 21.780 - </para> 21.781 - </listitem> 21.782 - <listitem><para><envar role="rc-item-acl">bundle</envar>: 21.783 - Control incoming changesets that are arriving from 21.784 - another repository via a bundle. 21.785 - </para> 21.786 - </listitem></itemizedlist> 21.787 - 21.788 - <para>The <literal role="rc-acl.allow">acl.allow</literal> 21.789 - section controls the users that are allowed to add 21.790 - changesets to the repository. If this section is not 21.791 - present, all users that are not explicitly denied are 21.792 - allowed. If this section is present, all users that are not 21.793 - explicitly allowed are denied (so an empty section means 21.794 - that all users are denied). 21.795 - </para> 21.796 - 21.797 - <para>The <literal role="rc-acl.deny">acl.deny</literal> 21.798 - section determines which users are denied from adding 21.799 - changesets to the repository. If this section is not 21.800 - present or is empty, no users are denied. 21.801 - </para> 21.802 - 21.803 - <para>The syntaxes for the <literal 21.804 - role="rc-acl.allow">acl.allow</literal> and <literal 21.805 - role="rc-acl.deny">acl.deny</literal> sections are 21.806 - identical. On the left of each entry is a glob pattern that 21.807 - matches files or directories, relative to the root of the 21.808 - repository; on the right, a user name. 21.809 - </para> 21.810 - 21.811 - <para>In the following example, the user 21.812 - <literal>docwriter</literal> can only push changes to the 21.813 - <filename class="directory">docs</filename> subtree of the 21.814 - repository, while <literal>intern</literal> can push changes 21.815 - to any file or directory except <filename 21.816 - class="directory">source/sensitive</filename>. 21.817 - </para> 21.818 - <programlisting>[acl.allow] 21.819 -docs/** = docwriter 21.820 -[acl.deny] 21.821 -source/sensitive/** = intern</programlisting> 21.822 - 21.823 - </sect3> 21.824 - <sect3> 21.825 - <title>Testing and troubleshooting</title> 21.826 - 21.827 - <para>If you want to test the <literal 21.828 - role="hg-ext">acl</literal> hook, run it with Mercurial's 21.829 - debugging output enabled. Since you'll probably be running 21.830 - it on a server where it's not convenient (or sometimes 21.831 - possible) to pass in the <option 21.832 - role="hg-opt-global">--debug</option> option, don't forget 21.833 - that you can enable debugging output in your <filename 21.834 - role="special">~/.hgrc</filename>: 21.835 - </para> 21.836 - <programlisting>[ui] 21.837 -debug = true</programlisting> 21.838 - <para>With this enabled, the <literal 21.839 - role="hg-ext">acl</literal> hook will print enough 21.840 - information to let you figure out why it is allowing or 21.841 - forbidding pushes from specific users. 21.842 - </para> 21.843 - 21.844 - </sect3> 21.845 - </sect2> 21.846 - <sect2> 21.847 - <title><literal 21.848 - role="hg-ext">bugzilla</literal>&emdash;integration with 21.849 - Bugzilla</title> 21.850 - 21.851 - <para>The <literal role="hg-ext">bugzilla</literal> extension 21.852 - adds a comment to a Bugzilla bug whenever it finds a reference 21.853 - to that bug ID in a commit comment. You can install this hook 21.854 - on a shared server, so that any time a remote user pushes 21.855 - changes to this server, the hook gets run. 21.856 - </para> 21.857 - 21.858 - <para>It adds a comment to the bug that looks like this (you can 21.859 - configure the contents of the comment&emdash;see below): 21.860 - </para> 21.861 - <programlisting>Changeset aad8b264143a, made by Joe User 21.862 - <joe.user@domain.com> in the frobnitz repository, refers 21.863 - to this bug. For complete details, see 21.864 - http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a 21.865 - Changeset description: Fix bug 10483 by guarding against some 21.866 - NULL pointers</programlisting> 21.867 - <para>The value of this hook is that it automates the process of 21.868 - updating a bug any time a changeset refers to it. If you 21.869 - configure the hook properly, it makes it easy for people to 21.870 - browse straight from a Bugzilla bug to a changeset that refers 21.871 - to that bug. 21.872 - </para> 21.873 - 21.874 - <para>You can use the code in this hook as a starting point for 21.875 - some more exotic Bugzilla integration recipes. Here are a few 21.876 - possibilities: 21.877 - </para> 21.878 - <itemizedlist> 21.879 - <listitem><para>Require that every changeset pushed to the 21.880 - server have a valid bug ID in its commit comment. In this 21.881 - case, you'd want to configure the hook as a <literal 21.882 - role="hook">pretxncommit</literal> hook. This would 21.883 - allow the hook to reject changes that didn't contain bug 21.884 - IDs. 21.885 - </para> 21.886 - </listitem> 21.887 - <listitem><para>Allow incoming changesets to automatically 21.888 - modify the <emphasis>state</emphasis> of a bug, as well as 21.889 - simply adding a comment. For example, the hook could 21.890 - recognise the string <quote>fixed bug 31337</quote> as 21.891 - indicating that it should update the state of bug 31337 to 21.892 - <quote>requires testing</quote>. 21.893 - </para> 21.894 - </listitem></itemizedlist> 21.895 - 21.896 - <sect3 id="sec:hook:bugzilla:config"> 21.897 - <title>Configuring the <literal role="hook">bugzilla</literal> 21.898 - hook</title> 21.899 - 21.900 - <para>You should configure this hook in your server's 21.901 - <filename role="special">~/.hgrc</filename> as an <literal 21.902 - role="hook">incoming</literal> hook, for example as 21.903 - follows: 21.904 - </para> 21.905 - <programlisting>[hooks] 21.906 -incoming.bugzilla = python:hgext.bugzilla.hook</programlisting> 21.907 - 21.908 - <para>Because of the specialised nature of this hook, and 21.909 - because Bugzilla was not written with this kind of 21.910 - integration in mind, configuring this hook is a somewhat 21.911 - involved process. 21.912 - </para> 21.913 - 21.914 - <para>Before you begin, you must install the MySQL bindings 21.915 - for Python on the host(s) where you'll be running the hook. 21.916 - If this is not available as a binary package for your 21.917 - system, you can download it from 21.918 - <citation>web:mysql-python</citation>. 21.919 - </para> 21.920 - 21.921 - <para>Configuration information for this hook lives in the 21.922 - <literal role="rc-bugzilla">bugzilla</literal> section of 21.923 - your <filename role="special">~/.hgrc</filename>. 21.924 - </para> 21.925 - <itemizedlist> 21.926 - <listitem><para><envar 21.927 - role="rc-item-bugzilla">version</envar>: The version 21.928 - of Bugzilla installed on the server. The database 21.929 - schema that Bugzilla uses changes occasionally, so this 21.930 - hook has to know exactly which schema to use. At the 21.931 - moment, the only version supported is 21.932 - <literal>2.16</literal>. 21.933 - </para> 21.934 - </listitem> 21.935 - <listitem><para><envar role="rc-item-bugzilla">host</envar>: 21.936 - The hostname of the MySQL server that stores your 21.937 - Bugzilla data. The database must be configured to allow 21.938 - connections from whatever host you are running the 21.939 - <literal role="hook">bugzilla</literal> hook on. 21.940 - </para> 21.941 - </listitem> 21.942 - <listitem><para><envar role="rc-item-bugzilla">user</envar>: 21.943 - The username with which to connect to the MySQL server. 21.944 - The database must be configured to allow this user to 21.945 - connect from whatever host you are running the <literal 21.946 - role="hook">bugzilla</literal> hook on. This user 21.947 - must be able to access and modify Bugzilla tables. The 21.948 - default value of this item is <literal>bugs</literal>, 21.949 - which is the standard name of the Bugzilla user in a 21.950 - MySQL database. 21.951 - </para> 21.952 - </listitem> 21.953 - <listitem><para><envar 21.954 - role="rc-item-bugzilla">password</envar>: The MySQL 21.955 - password for the user you configured above. This is 21.956 - stored as plain text, so you should make sure that 21.957 - unauthorised users cannot read the <filename 21.958 - role="special">~/.hgrc</filename> file where you 21.959 - store this information. 21.960 - </para> 21.961 - </listitem> 21.962 - <listitem><para><envar role="rc-item-bugzilla">db</envar>: 21.963 - The name of the Bugzilla database on the MySQL server. 21.964 - The default value of this item is 21.965 - <literal>bugs</literal>, which is the standard name of 21.966 - the MySQL database where Bugzilla stores its data. 21.967 - </para> 21.968 - </listitem> 21.969 - <listitem><para><envar 21.970 - role="rc-item-bugzilla">notify</envar>: If you want 21.971 - Bugzilla to send out a notification email to subscribers 21.972 - after this hook has added a comment to a bug, you will 21.973 - need this hook to run a command whenever it updates the 21.974 - database. The command to run depends on where you have 21.975 - installed Bugzilla, but it will typically look something 21.976 - like this, if you have Bugzilla installed in <filename 21.977 - class="directory">/var/www/html/bugzilla</filename>: 21.978 - </para> 21.979 - <programlisting>cd /var/www/html/bugzilla && 21.980 - ./processmail %s nobody@nowhere.com</programlisting> 21.981 - </listitem> 21.982 - <listitem><para> The Bugzilla 21.983 - <literal>processmail</literal> program expects to be 21.984 - given a bug ID (the hook replaces 21.985 - <quote><literal>%s</literal></quote> with the bug ID) 21.986 - and an email address. It also expects to be able to 21.987 - write to some files in the directory that it runs in. 21.988 - If Bugzilla and this hook are not installed on the same 21.989 - machine, you will need to find a way to run 21.990 - <literal>processmail</literal> on the server where 21.991 - Bugzilla is installed. 21.992 - </para> 21.993 - </listitem></itemizedlist> 21.994 - 21.995 - </sect3> 21.996 - <sect3> 21.997 - <title>Mapping committer names to Bugzilla user names</title> 21.998 - 21.999 - <para>By default, the <literal 21.1000 - role="hg-ext">bugzilla</literal> hook tries to use the 21.1001 - email address of a changeset's committer as the Bugzilla 21.1002 - user name with which to update a bug. If this does not suit 21.1003 - your needs, you can map committer email addresses to 21.1004 - Bugzilla user names using a <literal 21.1005 - role="rc-usermap">usermap</literal> section. 21.1006 - </para> 21.1007 - 21.1008 - <para>Each item in the <literal 21.1009 - role="rc-usermap">usermap</literal> section contains an 21.1010 - email address on the left, and a Bugzilla user name on the 21.1011 - right. 21.1012 - </para> 21.1013 - <programlisting>[usermap] 21.1014 -jane.user@example.com = jane</programlisting> 21.1015 - <para>You can either keep the <literal 21.1016 - role="rc-usermap">usermap</literal> data in a normal 21.1017 - <filename role="special">~/.hgrc</filename>, or tell the 21.1018 - <literal role="hg-ext">bugzilla</literal> hook to read the 21.1019 - information from an external <filename>usermap</filename> 21.1020 - file. In the latter case, you can store 21.1021 - <filename>usermap</filename> data by itself in (for example) 21.1022 - a user-modifiable repository. This makes it possible to let 21.1023 - your users maintain their own <envar 21.1024 - role="rc-item-bugzilla">usermap</envar> entries. The main 21.1025 - <filename role="special">~/.hgrc</filename> file might look 21.1026 - like this: 21.1027 - </para> 21.1028 - <programlisting># regular hgrc file refers to external usermap file 21.1029 -[bugzilla] 21.1030 -usermap = /home/hg/repos/userdata/bugzilla-usermap.conf</programlisting> 21.1031 - <para>While the <filename>usermap</filename> file that it 21.1032 - refers to might look like this: 21.1033 - </para> 21.1034 - <programlisting># bugzilla-usermap.conf - inside a hg repository 21.1035 -[usermap] stephanie@example.com = steph</programlisting> 21.1036 - 21.1037 - </sect3> 21.1038 - <sect3> 21.1039 - <title>Configuring the text that gets added to a bug</title> 21.1040 - 21.1041 - <para>You can configure the text that this hook adds as a 21.1042 - comment; you specify it in the form of a Mercurial template. 21.1043 - Several <filename role="special">~/.hgrc</filename> entries 21.1044 - (still in the <literal role="rc-bugzilla">bugzilla</literal> 21.1045 - section) control this behaviour. 21.1046 - </para> 21.1047 - <itemizedlist> 21.1048 - <listitem><para><literal>strip</literal>: The number of 21.1049 - leading path elements to strip from a repository's path 21.1050 - name to construct a partial path for a URL. For example, 21.1051 - if the repositories on your server live under <filename 21.1052 - class="directory">/home/hg/repos</filename>, and you 21.1053 - have a repository whose path is <filename 21.1054 - class="directory">/home/hg/repos/app/tests</filename>, 21.1055 - then setting <literal>strip</literal> to 21.1056 - <literal>4</literal> will give a partial path of 21.1057 - <filename class="directory">app/tests</filename>. The 21.1058 - hook will make this partial path available when 21.1059 - expanding a template, as <literal>webroot</literal>. 21.1060 - </para> 21.1061 - </listitem> 21.1062 - <listitem><para><literal>template</literal>: The text of the 21.1063 - template to use. In addition to the usual 21.1064 - changeset-related variables, this template can use 21.1065 - <literal>hgweb</literal> (the value of the 21.1066 - <literal>hgweb</literal> configuration item above) and 21.1067 - <literal>webroot</literal> (the path constructed using 21.1068 - <literal>strip</literal> above). 21.1069 - </para> 21.1070 - </listitem></itemizedlist> 21.1071 - 21.1072 - <para>In addition, you can add a <envar 21.1073 - role="rc-item-web">baseurl</envar> item to the <literal 21.1074 - role="rc-web">web</literal> section of your <filename 21.1075 - role="special">~/.hgrc</filename>. The <literal 21.1076 - role="hg-ext">bugzilla</literal> hook will make this 21.1077 - available when expanding a template, as the base string to 21.1078 - use when constructing a URL that will let users browse from 21.1079 - a Bugzilla comment to view a changeset. Example: 21.1080 - </para> 21.1081 - <programlisting>[web] 21.1082 -baseurl = http://hg.domain.com/</programlisting> 21.1083 - 21.1084 - <para>Here is an example set of <literal 21.1085 - role="hg-ext">bugzilla</literal> hook config information. 21.1086 - </para> 21.1087 - 21.1088 - &ch10-bugzilla-config.lst; 21.1089 - 21.1090 - </sect3> 21.1091 - <sect3> 21.1092 - <title>Testing and troubleshooting</title> 21.1093 - 21.1094 - <para>The most common problems with configuring the <literal 21.1095 - role="hg-ext">bugzilla</literal> hook relate to running 21.1096 - Bugzilla's <filename>processmail</filename> script and 21.1097 - mapping committer names to user names. 21.1098 - </para> 21.1099 - 21.1100 - <para>Recall from section <xref 21.1101 - linkend="sec:hook:bugzilla:config"/> above that the user 21.1102 - that runs the Mercurial process on the server is also the 21.1103 - one that will run the <filename>processmail</filename> 21.1104 - script. The <filename>processmail</filename> script 21.1105 - sometimes causes Bugzilla to write to files in its 21.1106 - configuration directory, and Bugzilla's configuration files 21.1107 - are usually owned by the user that your web server runs 21.1108 - under. 21.1109 - </para> 21.1110 - 21.1111 - <para>You can cause <filename>processmail</filename> to be run 21.1112 - with the suitable user's identity using the 21.1113 - <command>sudo</command> command. Here is an example entry 21.1114 - for a <filename>sudoers</filename> file. 21.1115 - </para> 21.1116 - <programlisting>hg_user = (httpd_user) 21.1117 -NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s</programlisting> 21.1118 - <para>This allows the <literal>hg_user</literal> user to run a 21.1119 - <filename>processmail-wrapper</filename> program under the 21.1120 - identity of <literal>httpd_user</literal>. 21.1121 - </para> 21.1122 - 21.1123 - <para>This indirection through a wrapper script is necessary, 21.1124 - because <filename>processmail</filename> expects to be run 21.1125 - with its current directory set to wherever you installed 21.1126 - Bugzilla; you can't specify that kind of constraint in a 21.1127 - <filename>sudoers</filename> file. The contents of the 21.1128 - wrapper script are simple: 21.1129 - </para> 21.1130 - <programlisting>#!/bin/sh 21.1131 -cd `dirname $0` && ./processmail "$1" nobody@example.com</programlisting> 21.1132 - <para>It doesn't seem to matter what email address you pass to 21.1133 - <filename>processmail</filename>. 21.1134 - </para> 21.1135 - 21.1136 - <para>If your <literal role="rc-usermap">usermap</literal> is 21.1137 - not set up correctly, users will see an error message from 21.1138 - the <literal role="hg-ext">bugzilla</literal> hook when they 21.1139 - push changes to the server. The error message will look 21.1140 - like this: 21.1141 - </para> 21.1142 - <programlisting>cannot find bugzilla user id for john.q.public@example.com</programlisting> 21.1143 - <para>What this means is that the committer's address, 21.1144 - <literal>john.q.public@example.com</literal>, is not a valid 21.1145 - Bugzilla user name, nor does it have an entry in your 21.1146 - <literal role="rc-usermap">usermap</literal> that maps it to 21.1147 - a valid Bugzilla user name. 21.1148 - </para> 21.1149 - 21.1150 - </sect3> 21.1151 - </sect2> 21.1152 - <sect2> 21.1153 - <title><literal role="hg-ext">notify</literal>&emdash;send email 21.1154 - notifications</title> 21.1155 - 21.1156 - <para>Although Mercurial's built-in web server provides RSS 21.1157 - feeds of changes in every repository, many people prefer to 21.1158 - receive change notifications via email. The <literal 21.1159 - role="hg-ext">notify</literal> hook lets you send out 21.1160 - notifications to a set of email addresses whenever changesets 21.1161 - arrive that those subscribers are interested in. 21.1162 - </para> 21.1163 - 21.1164 - <para>As with the <literal role="hg-ext">bugzilla</literal> 21.1165 - hook, the <literal role="hg-ext">notify</literal> hook is 21.1166 - template-driven, so you can customise the contents of the 21.1167 - notification messages that it sends. 21.1168 - </para> 21.1169 - 21.1170 - <para>By default, the <literal role="hg-ext">notify</literal> 21.1171 - hook includes a diff of every changeset that it sends out; you 21.1172 - can limit the size of the diff, or turn this feature off 21.1173 - entirely. It is useful for letting subscribers review changes 21.1174 - immediately, rather than clicking to follow a URL. 21.1175 - </para> 21.1176 - 21.1177 - <sect3> 21.1178 - <title>Configuring the <literal role="hg-ext">notify</literal> 21.1179 - hook</title> 21.1180 - 21.1181 - <para>You can set up the <literal 21.1182 - role="hg-ext">notify</literal> hook to send one email 21.1183 - message per incoming changeset, or one per incoming group of 21.1184 - changesets (all those that arrived in a single pull or 21.1185 - push). 21.1186 - </para> 21.1187 - <programlisting>[hooks] 21.1188 -# send one email per group of changes 21.1189 -changegroup.notify = python:hgext.notify.hook 21.1190 -# send one email per change 21.1191 -incoming.notify = python:hgext.notify.hook</programlisting> 21.1192 - 21.1193 - <para>Configuration information for this hook lives in the 21.1194 - <literal role="rc-notify">notify</literal> section of a 21.1195 - <filename role="special">~/.hgrc</filename> file. 21.1196 - </para> 21.1197 - <itemizedlist> 21.1198 - <listitem><para><envar role="rc-item-notify">test</envar>: 21.1199 - By default, this hook does not send out email at all; 21.1200 - instead, it prints the message that it 21.1201 - <emphasis>would</emphasis> send. Set this item to 21.1202 - <literal>false</literal> to allow email to be sent. The 21.1203 - reason that sending of email is turned off by default is 21.1204 - that it takes several tries to configure this extension 21.1205 - exactly as you would like, and it would be bad form to 21.1206 - spam subscribers with a number of <quote>broken</quote> 21.1207 - notifications while you debug your configuration. 21.1208 - </para> 21.1209 - </listitem> 21.1210 - <listitem><para><envar role="rc-item-notify">config</envar>: 21.1211 - The path to a configuration file that contains 21.1212 - subscription information. This is kept separate from 21.1213 - the main <filename role="special">~/.hgrc</filename> so 21.1214 - that you can maintain it in a repository of its own. 21.1215 - People can then clone that repository, update their 21.1216 - subscriptions, and push the changes back to your server. 21.1217 - </para> 21.1218 - </listitem> 21.1219 - <listitem><para><envar role="rc-item-notify">strip</envar>: 21.1220 - The number of leading path separator characters to strip 21.1221 - from a repository's path, when deciding whether a 21.1222 - repository has subscribers. For example, if the 21.1223 - repositories on your server live in <filename 21.1224 - class="directory">/home/hg/repos</filename>, and 21.1225 - <literal role="hg-ext">notify</literal> is considering a 21.1226 - repository named <filename 21.1227 - class="directory">/home/hg/repos/shared/test</filename>, 21.1228 - setting <envar role="rc-item-notify">strip</envar> to 21.1229 - <literal>4</literal> will cause <literal 21.1230 - role="hg-ext">notify</literal> to trim the path it 21.1231 - considers down to <filename 21.1232 - class="directory">shared/test</filename>, and it will 21.1233 - match subscribers against that. 21.1234 - </para> 21.1235 - </listitem> 21.1236 - <listitem><para><envar 21.1237 - role="rc-item-notify">template</envar>: The template 21.1238 - text to use when sending messages. This specifies both 21.1239 - the contents of the message header and its body. 21.1240 - </para> 21.1241 - </listitem> 21.1242 - <listitem><para><envar 21.1243 - role="rc-item-notify">maxdiff</envar>: The maximum 21.1244 - number of lines of diff data to append to the end of a 21.1245 - message. If a diff is longer than this, it is 21.1246 - truncated. By default, this is set to 300. Set this to 21.1247 - <literal>0</literal> to omit diffs from notification 21.1248 - emails. 21.1249 - </para> 21.1250 - </listitem> 21.1251 - <listitem><para><envar 21.1252 - role="rc-item-notify">sources</envar>: A list of 21.1253 - sources of changesets to consider. This lets you limit 21.1254 - <literal role="hg-ext">notify</literal> to only sending 21.1255 - out email about changes that remote users pushed into 21.1256 - this repository via a server, for example. See section 21.1257 - <xref 21.1258 - linkend="sec:hook:sources"/> for the sources you can 21.1259 - specify here. 21.1260 - </para> 21.1261 - </listitem></itemizedlist> 21.1262 - 21.1263 - <para>If you set the <envar role="rc-item-web">baseurl</envar> 21.1264 - item in the <literal role="rc-web">web</literal> section, 21.1265 - you can use it in a template; it will be available as 21.1266 - <literal>webroot</literal>. 21.1267 - </para> 21.1268 - 21.1269 - <para>Here is an example set of <literal 21.1270 - role="hg-ext">notify</literal> configuration information. 21.1271 - </para> 21.1272 - 21.1273 - &ch10-notify-config.lst; 21.1274 - 21.1275 - <para>This will produce a message that looks like the 21.1276 - following: 21.1277 - </para> 21.1278 - 21.1279 - &ch10-notify-config-mail.lst; 21.1280 - 21.1281 - </sect3> 21.1282 - <sect3> 21.1283 - <title>Testing and troubleshooting</title> 21.1284 - 21.1285 - <para>Do not forget that by default, the <literal 21.1286 - role="hg-ext">notify</literal> extension <emphasis>will not 21.1287 - send any mail</emphasis> until you explicitly configure it to do so, 21.1288 - by setting <envar role="rc-item-notify">test</envar> to 21.1289 - <literal>false</literal>. Until you do that, it simply 21.1290 - prints the message it <emphasis>would</emphasis> send. 21.1291 - </para> 21.1292 - 21.1293 - </sect3> 21.1294 - </sect2> 21.1295 - </sect1> 21.1296 - <sect1 id="sec:hook:ref"> 21.1297 - <title>Information for writers of hooks</title> 21.1298 - 21.1299 - <sect2> 21.1300 - <title>In-process hook execution</title> 21.1301 - 21.1302 - <para>An in-process hook is called with arguments of the 21.1303 - following form: 21.1304 - </para> 21.1305 - <programlisting>def myhook(ui, repo, **kwargs): pass</programlisting> 21.1306 - <para>The <literal>ui</literal> parameter is a <literal 21.1307 - role="py-mod-mercurial.ui">ui</literal> object. The 21.1308 - <literal>repo</literal> parameter is a <literal 21.1309 - role="py-mod-mercurial.localrepo">localrepository</literal> 21.1310 - object. The names and values of the 21.1311 - <literal>**kwargs</literal> parameters depend on the hook 21.1312 - being invoked, with the following common features: 21.1313 - </para> 21.1314 - <itemizedlist> 21.1315 - <listitem><para>If a parameter is named 21.1316 - <literal>node</literal> or <literal>parentN</literal>, it 21.1317 - will contain a hexadecimal changeset ID. The empty string 21.1318 - is used to represent <quote>null changeset ID</quote> 21.1319 - instead of a string of zeroes. 21.1320 - </para> 21.1321 - </listitem> 21.1322 - <listitem><para>If a parameter is named 21.1323 - <literal>url</literal>, it will contain the URL of a 21.1324 - remote repository, if that can be determined. 21.1325 - </para> 21.1326 - </listitem> 21.1327 - <listitem><para>Boolean-valued parameters are represented as 21.1328 - Python <literal>bool</literal> objects. 21.1329 - </para> 21.1330 - </listitem></itemizedlist> 21.1331 - 21.1332 - <para>An in-process hook is called without a change to the 21.1333 - process's working directory (unlike external hooks, which are 21.1334 - run in the root of the repository). It must not change the 21.1335 - process's working directory, or it will cause any calls it 21.1336 - makes into the Mercurial API to fail. 21.1337 - </para> 21.1338 - 21.1339 - <para>If a hook returns a boolean <quote>false</quote> value, it 21.1340 - is considered to have succeeded. If it returns a boolean 21.1341 - <quote>true</quote> value or raises an exception, it is 21.1342 - considered to have failed. A useful way to think of the 21.1343 - calling convention is <quote>tell me if you fail</quote>. 21.1344 - </para> 21.1345 - 21.1346 - <para>Note that changeset IDs are passed into Python hooks as 21.1347 - hexadecimal strings, not the binary hashes that Mercurial's 21.1348 - APIs normally use. To convert a hash from hex to binary, use 21.1349 - the <literal>bin</literal> function. 21.1350 - </para> 21.1351 - 21.1352 - </sect2> 21.1353 - <sect2> 21.1354 - <title>External hook execution</title> 21.1355 - 21.1356 - <para>An external hook is passed to the shell of the user 21.1357 - running Mercurial. Features of that shell, such as variable 21.1358 - substitution and command redirection, are available. The hook 21.1359 - is run in the root directory of the repository (unlike 21.1360 - in-process hooks, which are run in the same directory that 21.1361 - Mercurial was run in). 21.1362 - </para> 21.1363 - 21.1364 - <para>Hook parameters are passed to the hook as environment 21.1365 - variables. Each environment variable's name is converted in 21.1366 - upper case and prefixed with the string 21.1367 - <quote><literal>HG_</literal></quote>. For example, if the 21.1368 - name of a parameter is <quote><literal>node</literal></quote>, 21.1369 - the name of the environment variable representing that 21.1370 - parameter will be <quote><literal>HG_NODE</literal></quote>. 21.1371 - </para> 21.1372 - 21.1373 - <para>A boolean parameter is represented as the string 21.1374 - <quote><literal>1</literal></quote> for <quote>true</quote>, 21.1375 - <quote><literal>0</literal></quote> for <quote>false</quote>. 21.1376 - If an environment variable is named <envar>HG_NODE</envar>, 21.1377 - <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it 21.1378 - contains a changeset ID represented as a hexadecimal string. 21.1379 - The empty string is used to represent <quote>null changeset 21.1380 - ID</quote> instead of a string of zeroes. If an environment 21.1381 - variable is named <envar>HG_URL</envar>, it will contain the 21.1382 - URL of a remote repository, if that can be determined. 21.1383 - </para> 21.1384 - 21.1385 - <para>If a hook exits with a status of zero, it is considered to 21.1386 - have succeeded. If it exits with a non-zero status, it is 21.1387 - considered to have failed. 21.1388 - </para> 21.1389 - 21.1390 - </sect2> 21.1391 - <sect2> 21.1392 - <title>Finding out where changesets come from</title> 21.1393 - 21.1394 - <para>A hook that involves the transfer of changesets between a 21.1395 - local repository and another may be able to find out 21.1396 - information about the <quote>far side</quote>. Mercurial 21.1397 - knows <emphasis>how</emphasis> changes are being transferred, 21.1398 - and in many cases <emphasis>where</emphasis> they are being 21.1399 - transferred to or from. 21.1400 - </para> 21.1401 - 21.1402 - <sect3 id="sec:hook:sources"> 21.1403 - <title>Sources of changesets</title> 21.1404 - 21.1405 - <para>Mercurial will tell a hook what means are, or were, used 21.1406 - to transfer changesets between repositories. This is 21.1407 - provided by Mercurial in a Python parameter named 21.1408 - <literal>source</literal>, or an environment variable named 21.1409 - <envar>HG_SOURCE</envar>. 21.1410 - </para> 21.1411 - 21.1412 - <itemizedlist> 21.1413 - <listitem><para><literal>serve</literal>: Changesets are 21.1414 - transferred to or from a remote repository over http or 21.1415 - ssh. 21.1416 - </para> 21.1417 - </listitem> 21.1418 - <listitem><para><literal>pull</literal>: Changesets are 21.1419 - being transferred via a pull from one repository into 21.1420 - another. 21.1421 - </para> 21.1422 - </listitem> 21.1423 - <listitem><para><literal>push</literal>: Changesets are 21.1424 - being transferred via a push from one repository into 21.1425 - another. 21.1426 - </para> 21.1427 - </listitem> 21.1428 - <listitem><para><literal>bundle</literal>: Changesets are 21.1429 - being transferred to or from a bundle. 21.1430 - </para> 21.1431 - </listitem></itemizedlist> 21.1432 - 21.1433 - </sect3> 21.1434 - <sect3 id="sec:hook:url"> 21.1435 - <title>Where changes are going&emdash;remote repository 21.1436 - URLs</title> 21.1437 - 21.1438 - <para>When possible, Mercurial will tell a hook the location 21.1439 - of the <quote>far side</quote> of an activity that transfers 21.1440 - changeset data between repositories. This is provided by 21.1441 - Mercurial in a Python parameter named 21.1442 - <literal>url</literal>, or an environment variable named 21.1443 - <envar>HG_URL</envar>. 21.1444 - </para> 21.1445 - 21.1446 - <para>This information is not always known. If a hook is 21.1447 - invoked in a repository that is being served via http or 21.1448 - ssh, Mercurial cannot tell where the remote repository is, 21.1449 - but it may know where the client is connecting from. In 21.1450 - such cases, the URL will take one of the following forms: 21.1451 - </para> 21.1452 - <itemizedlist> 21.1453 - <listitem><para><literal>remote:ssh:1.2.3.4</literal>&emdash;remote 21.1454 - ssh client, at the IP address 21.1455 - <literal>1.2.3.4</literal>. 21.1456 - </para> 21.1457 - </listitem> 21.1458 - <listitem><para><literal>remote:http:1.2.3.4</literal>&emdash;remote 21.1459 - http client, at the IP address 21.1460 - <literal>1.2.3.4</literal>. If the client is using SSL, 21.1461 - this will be of the form 21.1462 - <literal>remote:https:1.2.3.4</literal>. 21.1463 - </para> 21.1464 - </listitem> 21.1465 - <listitem><para>Empty&emdash;no information could be 21.1466 - discovered about the remote client. 21.1467 - </para> 21.1468 - </listitem></itemizedlist> 21.1469 - 21.1470 - </sect3> 21.1471 - </sect2> 21.1472 - </sect1> 21.1473 - <sect1> 21.1474 - <title>Hook reference</title> 21.1475 - 21.1476 - <sect2 id="sec:hook:changegroup"> 21.1477 - <title><literal role="hook">changegroup</literal>&emdash;after 21.1478 - remote changesets added</title> 21.1479 - 21.1480 - <para>This hook is run after a group of pre-existing changesets 21.1481 - has been added to the repository, for example via a <command 21.1482 - role="hg-cmd">hg pull</command> or <command role="hg-cmd">hg 21.1483 - unbundle</command>. This hook is run once per operation 21.1484 - that added one or more changesets. This is in contrast to the 21.1485 - <literal role="hook">incoming</literal> hook, which is run 21.1486 - once per changeset, regardless of whether the changesets 21.1487 - arrive in a group. 21.1488 - </para> 21.1489 - 21.1490 - <para>Some possible uses for this hook include kicking off an 21.1491 - automated build or test of the added changesets, updating a 21.1492 - bug database, or notifying subscribers that a repository 21.1493 - contains new changes. 21.1494 - </para> 21.1495 - 21.1496 - <para>Parameters to this hook: 21.1497 - </para> 21.1498 - <itemizedlist> 21.1499 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1500 - changeset ID of the first changeset in the group that was 21.1501 - added. All changesets between this and 21.1502 - <literal role="tag">tip</literal>, inclusive, were added by a single 21.1503 - <command role="hg-cmd">hg pull</command>, <command 21.1504 - role="hg-cmd">hg push</command> or <command 21.1505 - role="hg-cmd">hg unbundle</command>. 21.1506 - </para> 21.1507 - </listitem> 21.1508 - <listitem><para><literal>source</literal>: A string. The 21.1509 - source of these changes. See section <xref 21.1510 - linkend="sec:hook:sources"/> for details. 21.1511 - </para> 21.1512 - </listitem> 21.1513 - <listitem><para><literal>url</literal>: A URL. The location 21.1514 - of the remote repository, if known. See section <xref 21.1515 - linkend="sec:hook:url"/> for more 21.1516 - information. 21.1517 - </para> 21.1518 - </listitem></itemizedlist> 21.1519 - 21.1520 - <para>See also: <literal role="hook">incoming</literal> (section 21.1521 - <xref linkend="sec:hook:incoming"/>), <literal 21.1522 - role="hook">prechangegroup</literal> (section <xref 21.1523 - linkend="sec:hook:prechangegroup"/>), <literal 21.1524 - role="hook">pretxnchangegroup</literal> (section <xref 21.1525 - linkend="sec:hook:pretxnchangegroup"/>) 21.1526 - </para> 21.1527 - 21.1528 - </sect2> 21.1529 - <sect2 id="sec:hook:commit"> 21.1530 - <title><literal role="hook">commit</literal>&emdash;after a new 21.1531 - changeset is created</title> 21.1532 - 21.1533 - <para>This hook is run after a new changeset has been created. 21.1534 - </para> 21.1535 - 21.1536 - <para>Parameters to this hook: 21.1537 - </para> 21.1538 - <itemizedlist> 21.1539 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1540 - changeset ID of the newly committed changeset. 21.1541 - </para> 21.1542 - </listitem> 21.1543 - <listitem><para><literal>parent1</literal>: A changeset ID. 21.1544 - The changeset ID of the first parent of the newly 21.1545 - committed changeset. 21.1546 - </para> 21.1547 - </listitem> 21.1548 - <listitem><para><literal>parent2</literal>: A changeset ID. 21.1549 - The changeset ID of the second parent of the newly 21.1550 - committed changeset. 21.1551 - </para> 21.1552 - </listitem></itemizedlist> 21.1553 - 21.1554 - <para>See also: <literal role="hook">precommit</literal> 21.1555 - (section <xref linkend="sec:hook:precommit"/>), <literal 21.1556 - role="hook">pretxncommit</literal> (section <xref 21.1557 - linkend="sec:hook:pretxncommit"/>) 21.1558 - </para> 21.1559 - 21.1560 - </sect2> 21.1561 - <sect2 id="sec:hook:incoming"> 21.1562 - <title><literal role="hook">incoming</literal>&emdash;after one 21.1563 - remote changeset is added</title> 21.1564 - 21.1565 - <para>This hook is run after a pre-existing changeset has been 21.1566 - added to the repository, for example via a <command 21.1567 - role="hg-cmd">hg push</command>. If a group of changesets 21.1568 - was added in a single operation, this hook is called once for 21.1569 - each added changeset. 21.1570 - </para> 21.1571 - 21.1572 - <para>You can use this hook for the same purposes as the 21.1573 - <literal role="hook">changegroup</literal> hook (section <xref 21.1574 - linkend="sec:hook:changegroup"/>); it's simply 21.1575 - more convenient sometimes to run a hook once per group of 21.1576 - changesets, while other times it's handier once per changeset. 21.1577 - </para> 21.1578 - 21.1579 - <para>Parameters to this hook: 21.1580 - </para> 21.1581 - <itemizedlist> 21.1582 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1583 - ID of the newly added changeset. 21.1584 - </para> 21.1585 - </listitem> 21.1586 - <listitem><para><literal>source</literal>: A string. The 21.1587 - source of these changes. See section <xref 21.1588 - linkend="sec:hook:sources"/> for details. 21.1589 - </para> 21.1590 - </listitem> 21.1591 - <listitem><para><literal>url</literal>: A URL. The location 21.1592 - of the remote repository, if known. See section <xref 21.1593 - linkend="sec:hook:url"/> for more 21.1594 - information. 21.1595 - </para> 21.1596 - </listitem></itemizedlist> 21.1597 - 21.1598 - <para>See also: <literal role="hook">changegroup</literal> 21.1599 - (section <xref linkend="sec:hook:changegroup"/>) <literal 21.1600 - role="hook">prechangegroup</literal> (section <xref 21.1601 - linkend="sec:hook:prechangegroup"/>), <literal 21.1602 - role="hook">pretxnchangegroup</literal> (section <xref 21.1603 - linkend="sec:hook:pretxnchangegroup"/>) 21.1604 - </para> 21.1605 - 21.1606 - </sect2> 21.1607 - <sect2 id="sec:hook:outgoing"> 21.1608 - <title><literal role="hook">outgoing</literal>&emdash;after 21.1609 - changesets are propagated</title> 21.1610 - 21.1611 - <para>This hook is run after a group of changesets has been 21.1612 - propagated out of this repository, for example by a <command 21.1613 - role="hg-cmd">hg push</command> or <command role="hg-cmd">hg 21.1614 - bundle</command> command. 21.1615 - </para> 21.1616 - 21.1617 - <para>One possible use for this hook is to notify administrators 21.1618 - that changes have been pulled. 21.1619 - </para> 21.1620 - 21.1621 - <para>Parameters to this hook: 21.1622 - </para> 21.1623 - <itemizedlist> 21.1624 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1625 - changeset ID of the first changeset of the group that was 21.1626 - sent. 21.1627 - </para> 21.1628 - </listitem> 21.1629 - <listitem><para><literal>source</literal>: A string. The 21.1630 - source of the of the operation (see section <xref 21.1631 - linkend="sec:hook:sources"/>). If a remote 21.1632 - client pulled changes from this repository, 21.1633 - <literal>source</literal> will be 21.1634 - <literal>serve</literal>. If the client that obtained 21.1635 - changes from this repository was local, 21.1636 - <literal>source</literal> will be 21.1637 - <literal>bundle</literal>, <literal>pull</literal>, or 21.1638 - <literal>push</literal>, depending on the operation the 21.1639 - client performed. 21.1640 - </para> 21.1641 - </listitem> 21.1642 - <listitem><para><literal>url</literal>: A URL. The location 21.1643 - of the remote repository, if known. See section <xref 21.1644 - linkend="sec:hook:url"/> for more 21.1645 - information. 21.1646 - </para> 21.1647 - </listitem></itemizedlist> 21.1648 - 21.1649 - <para>See also: <literal role="hook">preoutgoing</literal> 21.1650 - (section <xref linkend="sec:hook:preoutgoing"/>) 21.1651 - </para> 21.1652 - 21.1653 - </sect2> 21.1654 - <sect2 id="sec:hook:prechangegroup"> 21.1655 - <title><literal 21.1656 - role="hook">prechangegroup</literal>&emdash;before starting 21.1657 - to add remote changesets</title> 21.1658 - 21.1659 - <para>This controlling hook is run before Mercurial begins to 21.1660 - add a group of changesets from another repository. 21.1661 - </para> 21.1662 - 21.1663 - <para>This hook does not have any information about the 21.1664 - changesets to be added, because it is run before transmission 21.1665 - of those changesets is allowed to begin. If this hook fails, 21.1666 - the changesets will not be transmitted. 21.1667 - </para> 21.1668 - 21.1669 - <para>One use for this hook is to prevent external changes from 21.1670 - being added to a repository. For example, you could use this 21.1671 - to <quote>freeze</quote> a server-hosted branch temporarily or 21.1672 - permanently so that users cannot push to it, while still 21.1673 - allowing a local administrator to modify the repository. 21.1674 - </para> 21.1675 - 21.1676 - <para>Parameters to this hook: 21.1677 - </para> 21.1678 - <itemizedlist> 21.1679 - <listitem><para><literal>source</literal>: A string. The 21.1680 - source of these changes. See section <xref 21.1681 - linkend="sec:hook:sources"/> for details. 21.1682 - </para> 21.1683 - </listitem> 21.1684 - <listitem><para><literal>url</literal>: A URL. The location 21.1685 - of the remote repository, if known. See section <xref 21.1686 - linkend="sec:hook:url"/> for more 21.1687 - information. 21.1688 - </para> 21.1689 - </listitem></itemizedlist> 21.1690 - 21.1691 - <para>See also: <literal role="hook">changegroup</literal> 21.1692 - (section <xref linkend="sec:hook:changegroup"/>), <literal 21.1693 - role="hook">incoming</literal> (section <xref 21.1694 - linkend="sec:hook:incoming"/>), , <literal 21.1695 - role="hook">pretxnchangegroup</literal> (section <xref 21.1696 - linkend="sec:hook:pretxnchangegroup"/>) 21.1697 - </para> 21.1698 - 21.1699 - </sect2> 21.1700 - <sect2 id="sec:hook:precommit"> 21.1701 - <title><literal role="hook">precommit</literal>&emdash;before 21.1702 - starting to commit a changeset</title> 21.1703 - 21.1704 - <para>This hook is run before Mercurial begins to commit a new 21.1705 - changeset. It is run before Mercurial has any of the metadata 21.1706 - for the commit, such as the files to be committed, the commit 21.1707 - message, or the commit date. 21.1708 - </para> 21.1709 - 21.1710 - <para>One use for this hook is to disable the ability to commit 21.1711 - new changesets, while still allowing incoming changesets. 21.1712 - Another is to run a build or test, and only allow the commit 21.1713 - to begin if the build or test succeeds. 21.1714 - </para> 21.1715 - 21.1716 - <para>Parameters to this hook: 21.1717 - </para> 21.1718 - <itemizedlist> 21.1719 - <listitem><para><literal>parent1</literal>: A changeset ID. 21.1720 - The changeset ID of the first parent of the working 21.1721 - directory. 21.1722 - </para> 21.1723 - </listitem> 21.1724 - <listitem><para><literal>parent2</literal>: A changeset ID. 21.1725 - The changeset ID of the second parent of the working 21.1726 - directory. 21.1727 - </para> 21.1728 - </listitem></itemizedlist> 21.1729 - <para>If the commit proceeds, the parents of the working 21.1730 - directory will become the parents of the new changeset. 21.1731 - </para> 21.1732 - 21.1733 - <para>See also: <literal role="hook">commit</literal> (section 21.1734 - <xref linkend="sec:hook:commit"/>), <literal 21.1735 - role="hook">pretxncommit</literal> (section <xref 21.1736 - linkend="sec:hook:pretxncommit"/>) 21.1737 - </para> 21.1738 - 21.1739 - </sect2> 21.1740 - <sect2 id="sec:hook:preoutgoing"> 21.1741 - <title><literal role="hook">preoutgoing</literal>&emdash;before 21.1742 - starting to propagate changesets</title> 21.1743 - 21.1744 - <para>This hook is invoked before Mercurial knows the identities 21.1745 - of the changesets to be transmitted. 21.1746 - </para> 21.1747 - 21.1748 - <para>One use for this hook is to prevent changes from being 21.1749 - transmitted to another repository. 21.1750 - </para> 21.1751 - 21.1752 - <para>Parameters to this hook: 21.1753 - </para> 21.1754 - <itemizedlist> 21.1755 - <listitem><para><literal>source</literal>: A string. The 21.1756 - source of the operation that is attempting to obtain 21.1757 - changes from this repository (see section <xref 21.1758 - linkend="sec:hook:sources"/>). See the documentation 21.1759 - for the <literal>source</literal> parameter to the 21.1760 - <literal role="hook">outgoing</literal> hook, in section 21.1761 - <xref linkend="sec:hook:outgoing"/>, for possible values 21.1762 - of 21.1763 - this parameter. 21.1764 - </para> 21.1765 - </listitem> 21.1766 - <listitem><para><literal>url</literal>: A URL. The location 21.1767 - of the remote repository, if known. See section <xref 21.1768 - linkend="sec:hook:url"/> for more 21.1769 - information. 21.1770 - </para> 21.1771 - </listitem></itemizedlist> 21.1772 - 21.1773 - <para>See also: <literal role="hook">outgoing</literal> (section 21.1774 - <xref linkend="sec:hook:outgoing"/>) 21.1775 - </para> 21.1776 - 21.1777 - </sect2> 21.1778 - <sect2 id="sec:hook:pretag"> 21.1779 - <title><literal role="hook">pretag</literal>&emdash;before 21.1780 - tagging a changeset</title> 21.1781 - 21.1782 - <para>This controlling hook is run before a tag is created. If 21.1783 - the hook succeeds, creation of the tag proceeds. If the hook 21.1784 - fails, the tag is not created. 21.1785 - </para> 21.1786 - 21.1787 - <para>Parameters to this hook: 21.1788 - </para> 21.1789 - <itemizedlist> 21.1790 - <listitem><para><literal>local</literal>: A boolean. Whether 21.1791 - the tag is local to this repository instance (i.e. stored 21.1792 - in <filename role="special">.hg/localtags</filename>) or 21.1793 - managed by Mercurial (stored in <filename 21.1794 - role="special">.hgtags</filename>). 21.1795 - </para> 21.1796 - </listitem> 21.1797 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1798 - ID of the changeset to be tagged. 21.1799 - </para> 21.1800 - </listitem> 21.1801 - <listitem><para><literal>tag</literal>: A string. The name of 21.1802 - the tag to be created. 21.1803 - </para> 21.1804 - </listitem></itemizedlist> 21.1805 - 21.1806 - <para>If the tag to be created is revision-controlled, the 21.1807 - <literal role="hook">precommit</literal> and <literal 21.1808 - role="hook">pretxncommit</literal> hooks (sections <xref 21.1809 - linkend="sec:hook:commit"/> and <xref 21.1810 - linkend="sec:hook:pretxncommit"/>) will also be run. 21.1811 - </para> 21.1812 - 21.1813 - <para>See also: <literal role="hook">tag</literal> (section 21.1814 - <xref linkend="sec:hook:tag"/>) 21.1815 - </para> 21.1816 - </sect2> 21.1817 - <sect2 id="sec:hook:pretxnchangegroup"> 21.1818 - <title><literal 21.1819 - role="hook">pretxnchangegroup</literal>&emdash;before 21.1820 - completing addition of remote changesets</title> 21.1821 - 21.1822 - <para>This controlling hook is run before a 21.1823 - transaction&emdash;that manages the addition of a group of new 21.1824 - changesets from outside the repository&emdash;completes. If 21.1825 - the hook succeeds, the transaction completes, and all of the 21.1826 - changesets become permanent within this repository. If the 21.1827 - hook fails, the transaction is rolled back, and the data for 21.1828 - the changesets is erased. 21.1829 - </para> 21.1830 - 21.1831 - <para>This hook can access the metadata associated with the 21.1832 - almost-added changesets, but it should not do anything 21.1833 - permanent with this data. It must also not modify the working 21.1834 - directory. 21.1835 - </para> 21.1836 - 21.1837 - <para>While this hook is running, if other Mercurial processes 21.1838 - access this repository, they will be able to see the 21.1839 - almost-added changesets as if they are permanent. This may 21.1840 - lead to race conditions if you do not take steps to avoid 21.1841 - them. 21.1842 - </para> 21.1843 - 21.1844 - <para>This hook can be used to automatically vet a group of 21.1845 - changesets. If the hook fails, all of the changesets are 21.1846 - <quote>rejected</quote> when the transaction rolls back. 21.1847 - </para> 21.1848 - 21.1849 - <para>Parameters to this hook: 21.1850 - </para> 21.1851 - <itemizedlist> 21.1852 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1853 - changeset ID of the first changeset in the group that was 21.1854 - added. All changesets between this and 21.1855 - <literal role="tag">tip</literal>, 21.1856 - inclusive, were added by a single <command 21.1857 - role="hg-cmd">hg pull</command>, <command 21.1858 - role="hg-cmd">hg push</command> or <command 21.1859 - role="hg-cmd">hg unbundle</command>. 21.1860 - </para> 21.1861 - </listitem> 21.1862 - <listitem><para><literal>source</literal>: A string. The 21.1863 - source of these changes. See section <xref 21.1864 - linkend="sec:hook:sources"/> for details. 21.1865 - </para> 21.1866 - </listitem> 21.1867 - <listitem><para><literal>url</literal>: A URL. The location 21.1868 - of the remote repository, if known. See section <xref 21.1869 - linkend="sec:hook:url"/> for more 21.1870 - information. 21.1871 - </para> 21.1872 - </listitem></itemizedlist> 21.1873 - 21.1874 - <para>See also: <literal role="hook">changegroup</literal> 21.1875 - (section <xref linkend="sec:hook:changegroup"/>), <literal 21.1876 - role="hook">incoming</literal> (section <xref 21.1877 - linkend="sec:hook:incoming"/>), <literal 21.1878 - role="hook">prechangegroup</literal> (section <xref 21.1879 - linkend="sec:hook:prechangegroup"/>) 21.1880 - </para> 21.1881 - 21.1882 - </sect2> 21.1883 - <sect2 id="sec:hook:pretxncommit"> 21.1884 - <title><literal role="hook">pretxncommit</literal>&emdash;before 21.1885 - completing commit of new changeset</title> 21.1886 - 21.1887 - <para>This controlling hook is run before a 21.1888 - transaction&emdash;that manages a new commit&emdash;completes. 21.1889 - If the hook succeeds, the transaction completes and the 21.1890 - changeset becomes permanent within this repository. If the 21.1891 - hook fails, the transaction is rolled back, and the commit 21.1892 - data is erased. 21.1893 - </para> 21.1894 - 21.1895 - <para>This hook can access the metadata associated with the 21.1896 - almost-new changeset, but it should not do anything permanent 21.1897 - with this data. It must also not modify the working 21.1898 - directory. 21.1899 - </para> 21.1900 - 21.1901 - <para>While this hook is running, if other Mercurial processes 21.1902 - access this repository, they will be able to see the 21.1903 - almost-new changeset as if it is permanent. This may lead to 21.1904 - race conditions if you do not take steps to avoid them. 21.1905 - </para> 21.1906 - 21.1907 - <para>Parameters to this hook: 21.1908 - </para> 21.1909 - <itemizedlist> 21.1910 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1911 - changeset ID of the newly committed changeset. 21.1912 - </para> 21.1913 - </listitem> 21.1914 - <listitem><para><literal>parent1</literal>: A changeset ID. 21.1915 - The changeset ID of the first parent of the newly 21.1916 - committed changeset. 21.1917 - </para> 21.1918 - </listitem> 21.1919 - <listitem><para><literal>parent2</literal>: A changeset ID. 21.1920 - The changeset ID of the second parent of the newly 21.1921 - committed changeset. 21.1922 - </para> 21.1923 - </listitem></itemizedlist> 21.1924 - 21.1925 - <para>See also: <literal role="hook">precommit</literal> 21.1926 - (section <xref linkend="sec:hook:precommit"/>) 21.1927 - </para> 21.1928 - 21.1929 - </sect2> 21.1930 - <sect2 id="sec:hook:preupdate"> 21.1931 - <title><literal role="hook">preupdate</literal>&emdash;before 21.1932 - updating or merging working directory</title> 21.1933 - 21.1934 - <para>This controlling hook is run before an update or merge of 21.1935 - the working directory begins. It is run only if Mercurial's 21.1936 - normal pre-update checks determine that the update or merge 21.1937 - can proceed. If the hook succeeds, the update or merge may 21.1938 - proceed; if it fails, the update or merge does not start. 21.1939 - </para> 21.1940 - 21.1941 - <para>Parameters to this hook: 21.1942 - </para> 21.1943 - <itemizedlist> 21.1944 - <listitem><para><literal>parent1</literal>: A changeset ID. 21.1945 - The ID of the parent that the working directory is to be 21.1946 - updated to. If the working directory is being merged, it 21.1947 - will not change this parent. 21.1948 - </para> 21.1949 - </listitem> 21.1950 - <listitem><para><literal>parent2</literal>: A changeset ID. 21.1951 - Only set if the working directory is being merged. The ID 21.1952 - of the revision that the working directory is being merged 21.1953 - with. 21.1954 - </para> 21.1955 - </listitem></itemizedlist> 21.1956 - 21.1957 - <para>See also: <literal role="hook">update</literal> (section 21.1958 - <xref linkend="sec:hook:update"/>) 21.1959 - </para> 21.1960 - 21.1961 - </sect2> 21.1962 - <sect2 id="sec:hook:tag"> 21.1963 - <title><literal role="hook">tag</literal>&emdash;after tagging a 21.1964 - changeset</title> 21.1965 - 21.1966 - <para>This hook is run after a tag has been created. 21.1967 - </para> 21.1968 - 21.1969 - <para>Parameters to this hook: 21.1970 - </para> 21.1971 - <itemizedlist> 21.1972 - <listitem><para><literal>local</literal>: A boolean. Whether 21.1973 - the new tag is local to this repository instance (i.e. 21.1974 - stored in <filename 21.1975 - role="special">.hg/localtags</filename>) or managed by 21.1976 - Mercurial (stored in <filename 21.1977 - role="special">.hgtags</filename>). 21.1978 - </para> 21.1979 - </listitem> 21.1980 - <listitem><para><literal>node</literal>: A changeset ID. The 21.1981 - ID of the changeset that was tagged. 21.1982 - </para> 21.1983 - </listitem> 21.1984 - <listitem><para><literal>tag</literal>: A string. The name of 21.1985 - the tag that was created. 21.1986 - </para> 21.1987 - </listitem></itemizedlist> 21.1988 - 21.1989 - <para>If the created tag is revision-controlled, the <literal 21.1990 - role="hook">commit</literal> hook (section <xref 21.1991 - linkend="sec:hook:commit"/>) is run before this hook. 21.1992 - </para> 21.1993 - 21.1994 - <para>See also: <literal role="hook">pretag</literal> (section 21.1995 - <xref linkend="sec:hook:pretag"/>) 21.1996 - </para> 21.1997 - 21.1998 - </sect2> 21.1999 - <sect2 id="sec:hook:update"> 21.2000 - <title><literal role="hook">update</literal>&emdash;after 21.2001 - updating or merging working directory</title> 21.2002 - 21.2003 - <para>This hook is run after an update or merge of the working 21.2004 - directory completes. Since a merge can fail (if the external 21.2005 - <command>hgmerge</command> command fails to resolve conflicts 21.2006 - in a file), this hook communicates whether the update or merge 21.2007 - completed cleanly. 21.2008 - </para> 21.2009 - 21.2010 - <itemizedlist> 21.2011 - <listitem><para><literal>error</literal>: A boolean. 21.2012 - Indicates whether the update or merge completed 21.2013 - successfully. 21.2014 - </para> 21.2015 - </listitem> 21.2016 - <listitem><para><literal>parent1</literal>: A changeset ID. 21.2017 - The ID of the parent that the working directory was 21.2018 - updated to. If the working directory was merged, it will 21.2019 - not have changed this parent. 21.2020 - </para> 21.2021 - </listitem> 21.2022 - <listitem><para><literal>parent2</literal>: A changeset ID. 21.2023 - Only set if the working directory was merged. The ID of 21.2024 - the revision that the working directory was merged with. 21.2025 - </para> 21.2026 - </listitem></itemizedlist> 21.2027 - 21.2028 - <para>See also: <literal role="hook">preupdate</literal> 21.2029 - (section <xref linkend="sec:hook:preupdate"/>) 21.2030 - </para> 21.2031 - 21.2032 - </sect2> 21.2033 - </sect1> 21.2034 -</chapter> 21.2035 - 21.2036 -<!-- 21.2037 -local variables: 21.2038 -sgml-parent-document: ("00book.xml" "book" "chapter") 21.2039 -end: 21.2040 --->
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/en/ch10-template.xml Thu Mar 19 20:54:12 2009 -0700 22.3 @@ -0,0 +1,675 @@ 22.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 22.5 + 22.6 +<chapter id="chap:template"> 22.7 + <?dbhtml filename="customizing-the-output-of-mercurial.html"?> 22.8 + <title>Customising the output of Mercurial</title> 22.9 + 22.10 + <para>Mercurial provides a powerful mechanism to let you control how 22.11 + it displays information. The mechanism is based on templates. 22.12 + You can use templates to generate specific output for a single 22.13 + command, or to customise the entire appearance of the built-in web 22.14 + interface.</para> 22.15 + 22.16 + <sect1 id="sec:style"> 22.17 + <title>Using precanned output styles</title> 22.18 + 22.19 + <para>Packaged with Mercurial are some output styles that you can 22.20 + use immediately. A style is simply a precanned template that 22.21 + someone wrote and installed somewhere that Mercurial can 22.22 + find.</para> 22.23 + 22.24 + <para>Before we take a look at Mercurial's bundled styles, let's 22.25 + review its normal output.</para> 22.26 + 22.27 + &interaction.template.simple.normal; 22.28 + 22.29 + <para>This is somewhat informative, but it takes up a lot of 22.30 + space&emdash;five lines of output per changeset. The 22.31 + <literal>compact</literal> style reduces this to three lines, 22.32 + presented in a sparse manner.</para> 22.33 + 22.34 + &interaction.template.simple.compact; 22.35 + 22.36 + <para>The <literal>changelog</literal> style hints at the 22.37 + expressive power of Mercurial's templating engine. This style 22.38 + attempts to follow the GNU Project's changelog 22.39 + guidelines<citation>web:changelog</citation>.</para> 22.40 + 22.41 + &interaction.template.simple.changelog; 22.42 + 22.43 + <para>You will not be shocked to learn that Mercurial's default 22.44 + output style is named <literal>default</literal>.</para> 22.45 + 22.46 + <sect2> 22.47 + <title>Setting a default style</title> 22.48 + 22.49 + <para>You can modify the output style that Mercurial will use 22.50 + for every command by editing your <filename 22.51 + role="special">~/.hgrc</filename> file, naming the style 22.52 + you would prefer to use.</para> 22.53 + 22.54 + <programlisting>[ui] 22.55 +style = compact</programlisting> 22.56 + 22.57 + <para>If you write a style of your own, you can use it by either 22.58 + providing the path to your style file, or copying your style 22.59 + file into a location where Mercurial can find it (typically 22.60 + the <literal>templates</literal> subdirectory of your 22.61 + Mercurial install directory).</para> 22.62 + 22.63 + </sect2> 22.64 + </sect1> 22.65 + <sect1> 22.66 + <title>Commands that support styles and templates</title> 22.67 + 22.68 + <para>All of Mercurial's 22.69 + <quote><literal>log</literal>-like</quote> commands let you use 22.70 + styles and templates: <command role="hg-cmd">hg 22.71 + incoming</command>, <command role="hg-cmd">hg log</command>, 22.72 + <command role="hg-cmd">hg outgoing</command>, and <command 22.73 + role="hg-cmd">hg tip</command>.</para> 22.74 + 22.75 + <para>As I write this manual, these are so far the only commands 22.76 + that support styles and templates. Since these are the most 22.77 + important commands that need customisable output, there has been 22.78 + little pressure from the Mercurial user community to add style 22.79 + and template support to other commands.</para> 22.80 + 22.81 + </sect1> 22.82 + <sect1> 22.83 + <title>The basics of templating</title> 22.84 + 22.85 + <para>At its simplest, a Mercurial template is a piece of text. 22.86 + Some of the text never changes, while other parts are 22.87 + <emphasis>expanded</emphasis>, or replaced with new text, when 22.88 + necessary.</para> 22.89 + 22.90 + <para>Before we continue, let's look again at a simple example of 22.91 + Mercurial's normal output.</para> 22.92 + 22.93 + &interaction.template.simple.normal; 22.94 + 22.95 + <para>Now, let's run the same command, but using a template to 22.96 + change its output.</para> 22.97 + 22.98 + &interaction.template.simple.simplest; 22.99 + 22.100 + <para>The example above illustrates the simplest possible 22.101 + template; it's just a piece of static text, printed once for 22.102 + each changeset. The <option 22.103 + role="hg-opt-log">--template</option> option to the <command 22.104 + role="hg-cmd">hg log</command> command tells Mercurial to use 22.105 + the given text as the template when printing each 22.106 + changeset.</para> 22.107 + 22.108 + <para>Notice that the template string above ends with the text 22.109 + <quote><literal>\n</literal></quote>. This is an 22.110 + <emphasis>escape sequence</emphasis>, telling Mercurial to print 22.111 + a newline at the end of each template item. If you omit this 22.112 + newline, Mercurial will run each piece of output together. See 22.113 + section <xref linkend="sec:template:escape"/> for more details 22.114 + of escape sequences.</para> 22.115 + 22.116 + <para>A template that prints a fixed string of text all the time 22.117 + isn't very useful; let's try something a bit more 22.118 + complex.</para> 22.119 + 22.120 + &interaction.template.simple.simplesub; 22.121 + 22.122 + <para>As you can see, the string 22.123 + <quote><literal>{desc}</literal></quote> in the template has 22.124 + been replaced in the output with the description of each 22.125 + changeset. Every time Mercurial finds text enclosed in curly 22.126 + braces (<quote><literal>{</literal></quote> and 22.127 + <quote><literal>}</literal></quote>), it will try to replace the braces 22.128 + and text with the expansion of whatever is inside. To print a 22.129 + literal curly brace, you must escape it, as described in section 22.130 + <xref 22.131 + linkend="sec:template:escape"/>.</para> 22.132 + 22.133 + </sect1> 22.134 + <sect1 id="sec:template:keyword"> 22.135 + <title>Common template keywords</title> 22.136 + 22.137 + <para>You can start writing simple templates immediately using the 22.138 + keywords below.</para> 22.139 + 22.140 + <itemizedlist> 22.141 + <listitem><para><literal 22.142 + role="template-keyword">author</literal>: String. The 22.143 + unmodified author of the changeset.</para> 22.144 + </listitem> 22.145 + <listitem><para><literal 22.146 + role="template-keyword">branches</literal>: String. The 22.147 + name of the branch on which the changeset was committed. 22.148 + Will be empty if the branch name was 22.149 + <literal>default</literal>.</para> 22.150 + </listitem> 22.151 + <listitem><para><literal role="template-keyword">date</literal>: 22.152 + Date information. The date when the changeset was 22.153 + committed. This is <emphasis>not</emphasis> human-readable; 22.154 + you must pass it through a filter that will render it 22.155 + appropriately. See section <xref 22.156 + linkend="sec:template:filter"/> for more information 22.157 + on filters. The date is expressed as a pair of numbers. The 22.158 + first number is a Unix UTC timestamp (seconds since January 22.159 + 1, 1970); the second is the offset of the committer's 22.160 + timezone from UTC, in seconds.</para> 22.161 + </listitem> 22.162 + <listitem><para><literal role="template-keyword">desc</literal>: 22.163 + String. The text of the changeset description.</para> 22.164 + </listitem> 22.165 + <listitem><para><literal 22.166 + role="template-keyword">files</literal>: List of strings. 22.167 + All files modified, added, or removed by this 22.168 + changeset.</para> 22.169 + </listitem> 22.170 + <listitem><para><literal 22.171 + role="template-keyword">file_adds</literal>: List of 22.172 + strings. Files added by this changeset.</para> 22.173 + </listitem> 22.174 + <listitem><para><literal 22.175 + role="template-keyword">file_dels</literal>: List of 22.176 + strings. Files removed by this changeset.</para> 22.177 + </listitem> 22.178 + <listitem><para><literal role="template-keyword">node</literal>: 22.179 + String. The changeset identification hash, as a 22.180 + 40-character hexadecimal string.</para> 22.181 + </listitem> 22.182 + <listitem><para><literal 22.183 + role="template-keyword">parents</literal>: List of 22.184 + strings. The parents of the changeset.</para> 22.185 + </listitem> 22.186 + <listitem><para><literal role="template-keyword">rev</literal>: 22.187 + Integer. The repository-local changeset revision 22.188 + number.</para> 22.189 + </listitem> 22.190 + <listitem><para><literal role="template-keyword">tags</literal>: 22.191 + List of strings. Any tags associated with the 22.192 + changeset.</para> 22.193 + </listitem></itemizedlist> 22.194 + 22.195 + <para>A few simple experiments will show us what to expect when we 22.196 + use these keywords; you can see the results below.</para> 22.197 + 22.198 +&interaction.template.simple.keywords; 22.199 + 22.200 + <para>As we noted above, the date keyword does not produce 22.201 + human-readable output, so we must treat it specially. This 22.202 + involves using a <emphasis>filter</emphasis>, about which more 22.203 + in section <xref 22.204 + linkend="sec:template:filter"/>.</para> 22.205 + 22.206 + &interaction.template.simple.datekeyword; 22.207 + 22.208 + </sect1> 22.209 + <sect1 id="sec:template:escape"> 22.210 + <title>Escape sequences</title> 22.211 + 22.212 + <para>Mercurial's templating engine recognises the most commonly 22.213 + used escape sequences in strings. When it sees a backslash 22.214 + (<quote><literal>\</literal></quote>) character, it looks at the 22.215 + following character and substitutes the two characters with a 22.216 + single replacement, as described below.</para> 22.217 + 22.218 + <itemizedlist> 22.219 + <listitem><para><literal>\</literal>: 22.220 + Backslash, <quote><literal>\</literal></quote>, ASCII 22.221 + 134.</para> 22.222 + </listitem> 22.223 + <listitem><para><literal>\n</literal>: Newline, 22.224 + ASCII 12.</para> 22.225 + </listitem> 22.226 + <listitem><para><literal>\r</literal>: Carriage 22.227 + return, ASCII 15.</para> 22.228 + </listitem> 22.229 + <listitem><para><literal>\t</literal>: Tab, ASCII 22.230 + 11.</para> 22.231 + </listitem> 22.232 + <listitem><para><literal>\v</literal>: Vertical 22.233 + tab, ASCII 13.</para> 22.234 + </listitem> 22.235 + <listitem><para><literal>{</literal>: Open curly 22.236 + brace, <quote><literal>{</literal></quote>, ASCII 22.237 + 173.</para> 22.238 + </listitem> 22.239 + <listitem><para><literal>}</literal>: Close curly 22.240 + brace, <quote><literal>}</literal></quote>, ASCII 22.241 + 175.</para> 22.242 + </listitem></itemizedlist> 22.243 + 22.244 + <para>As indicated above, if you want the expansion of a template 22.245 + to contain a literal <quote><literal>\</literal></quote>, 22.246 + <quote><literal>{</literal></quote>, or 22.247 + <quote><literal>{</literal></quote> character, you must escape 22.248 + it.</para> 22.249 + 22.250 + </sect1> 22.251 + <sect1 id="sec:template:filter"> 22.252 + <title>Filtering keywords to change their results</title> 22.253 + 22.254 + <para>Some of the results of template expansion are not 22.255 + immediately easy to use. Mercurial lets you specify an optional 22.256 + chain of <emphasis>filters</emphasis> to modify the result of 22.257 + expanding a keyword. You have already seen a common filter, 22.258 + <literal role="template-kw-filt-date">isodate</literal>, in 22.259 + action above, to make a date readable.</para> 22.260 + 22.261 + <para>Below is a list of the most commonly used filters that 22.262 + Mercurial supports. While some filters can be applied to any 22.263 + text, others can only be used in specific circumstances. The 22.264 + name of each filter is followed first by an indication of where 22.265 + it can be used, then a description of its effect.</para> 22.266 + 22.267 + <itemizedlist> 22.268 + <listitem><para><literal 22.269 + role="template-filter">addbreaks</literal>: Any text. Add 22.270 + an XHTML <quote><literal><br/></literal></quote> tag 22.271 + before the end of every line except the last. For example, 22.272 + <quote><literal>foo\nbar</literal></quote> becomes 22.273 + <quote><literal>foo<br/>\nbar</literal></quote>.</para> 22.274 + </listitem> 22.275 + <listitem><para><literal 22.276 + role="template-kw-filt-date">age</literal>: <literal 22.277 + role="template-keyword">date</literal> keyword. Render 22.278 + the age of the date, relative to the current time. Yields a 22.279 + string like <quote><literal>10 22.280 + minutes</literal></quote>.</para> 22.281 + </listitem> 22.282 + <listitem><para><literal 22.283 + role="template-filter">basename</literal>: Any text, but 22.284 + most useful for the <literal 22.285 + role="template-keyword">files</literal> keyword and its 22.286 + relatives. Treat the text as a path, and return the 22.287 + basename. For example, 22.288 + <quote><literal>foo/bar/baz</literal></quote> becomes 22.289 + <quote><literal>baz</literal></quote>.</para> 22.290 + </listitem> 22.291 + <listitem><para><literal 22.292 + role="template-kw-filt-date">date</literal>: <literal 22.293 + role="template-keyword">date</literal> keyword. Render a 22.294 + date in a similar format to the Unix <literal 22.295 + role="template-keyword">date</literal> command, but with 22.296 + timezone included. Yields a string like <quote><literal>Mon 22.297 + Sep 04 15:13:13 2006 -0700</literal></quote>.</para> 22.298 + </listitem> 22.299 + <listitem><para><literal 22.300 + role="template-kw-filt-author">domain</literal>: Any text, 22.301 + but most useful for the <literal 22.302 + role="template-keyword">author</literal> keyword. Finds 22.303 + the first string that looks like an email address, and 22.304 + extract just the domain component. For example, 22.305 + <quote><literal>Bryan O'Sullivan 22.306 + <bos@serpentine.com></literal></quote> becomes 22.307 + <quote><literal>serpentine.com</literal></quote>.</para> 22.308 + </listitem> 22.309 + <listitem><para><literal 22.310 + role="template-kw-filt-author">email</literal>: Any text, 22.311 + but most useful for the <literal 22.312 + role="template-keyword">author</literal> keyword. Extract 22.313 + the first string that looks like an email address. For 22.314 + example, <quote><literal>Bryan O'Sullivan 22.315 + <bos@serpentine.com></literal></quote> becomes 22.316 + <quote><literal>bos@serpentine.com</literal></quote>.</para> 22.317 + </listitem> 22.318 + <listitem><para><literal 22.319 + role="template-filter">escape</literal>: Any text. 22.320 + Replace the special XML/XHTML characters 22.321 + <quote><literal>&</literal></quote>, 22.322 + <quote><literal><</literal></quote> and 22.323 + <quote><literal>></literal></quote> with XML 22.324 + entities.</para> 22.325 + </listitem> 22.326 + <listitem><para><literal 22.327 + role="template-filter">fill68</literal>: Any text. Wrap 22.328 + the text to fit in 68 columns. This is useful before you 22.329 + pass text through the <literal 22.330 + role="template-filter">tabindent</literal> filter, and 22.331 + still want it to fit in an 80-column fixed-font 22.332 + window.</para> 22.333 + </listitem> 22.334 + <listitem><para><literal 22.335 + role="template-filter">fill76</literal>: Any text. Wrap 22.336 + the text to fit in 76 columns.</para> 22.337 + </listitem> 22.338 + <listitem><para><literal 22.339 + role="template-filter">firstline</literal>: Any text. 22.340 + Yield the first line of text, without any trailing 22.341 + newlines.</para> 22.342 + </listitem> 22.343 + <listitem><para><literal 22.344 + role="template-kw-filt-date">hgdate</literal>: <literal 22.345 + role="template-keyword">date</literal> keyword. Render 22.346 + the date as a pair of readable numbers. Yields a string 22.347 + like <quote><literal>1157407993 22.348 + 25200</literal></quote>.</para> 22.349 + </listitem> 22.350 + <listitem><para><literal 22.351 + role="template-kw-filt-date">isodate</literal>: <literal 22.352 + role="template-keyword">date</literal> keyword. Render 22.353 + the date as a text string in ISO 8601 format. Yields a 22.354 + string like <quote><literal>2006-09-04 15:13:13 22.355 + -0700</literal></quote>.</para> 22.356 + </listitem> 22.357 + <listitem><para><literal 22.358 + role="template-filter">obfuscate</literal>: Any text, but 22.359 + most useful for the <literal 22.360 + role="template-keyword">author</literal> keyword. Yield 22.361 + the input text rendered as a sequence of XML entities. This 22.362 + helps to defeat some particularly stupid screen-scraping 22.363 + email harvesting spambots.</para> 22.364 + </listitem> 22.365 + <listitem><para><literal 22.366 + role="template-kw-filt-author">person</literal>: Any text, 22.367 + but most useful for the <literal 22.368 + role="template-keyword">author</literal> keyword. Yield 22.369 + the text before an email address. For example, 22.370 + <quote><literal>Bryan O'Sullivan 22.371 + <bos@serpentine.com></literal></quote> becomes 22.372 + <quote><literal>Bryan O'Sullivan</literal></quote>.</para> 22.373 + </listitem> 22.374 + <listitem><para><literal 22.375 + role="template-kw-filt-date">rfc822date</literal>: 22.376 + <literal role="template-keyword">date</literal> keyword. 22.377 + Render a date using the same format used in email headers. 22.378 + Yields a string like <quote><literal>Mon, 04 Sep 2006 22.379 + 15:13:13 -0700</literal></quote>.</para> 22.380 + </listitem> 22.381 + <listitem><para><literal 22.382 + role="template-kw-filt-node">short</literal>: Changeset 22.383 + hash. Yield the short form of a changeset hash, i.e. a 22.384 + 12-character hexadecimal string.</para> 22.385 + </listitem> 22.386 + <listitem><para><literal 22.387 + role="template-kw-filt-date">shortdate</literal>: <literal 22.388 + role="template-keyword">date</literal> keyword. Render 22.389 + the year, month, and day of the date. Yields a string like 22.390 + <quote><literal>2006-09-04</literal></quote>.</para> 22.391 + </listitem> 22.392 + <listitem><para><literal role="template-filter">strip</literal>: 22.393 + Any text. Strip all leading and trailing whitespace from 22.394 + the string.</para> 22.395 + </listitem> 22.396 + <listitem><para><literal 22.397 + role="template-filter">tabindent</literal>: Any text. 22.398 + Yield the text, with every line except the first starting 22.399 + with a tab character.</para> 22.400 + </listitem> 22.401 + <listitem><para><literal 22.402 + role="template-filter">urlescape</literal>: Any text. 22.403 + Escape all characters that are considered 22.404 + <quote>special</quote> by URL parsers. For example, 22.405 + <literal>foo bar</literal> becomes 22.406 + <literal>foo%20bar</literal>.</para> 22.407 + </listitem> 22.408 + <listitem><para><literal 22.409 + role="template-kw-filt-author">user</literal>: Any text, 22.410 + but most useful for the <literal 22.411 + role="template-keyword">author</literal> keyword. Return 22.412 + the <quote>user</quote> portion of an email address. For 22.413 + example, <quote><literal>Bryan O'Sullivan 22.414 + <bos@serpentine.com></literal></quote> becomes 22.415 + <quote><literal>bos</literal></quote>.</para> 22.416 + </listitem></itemizedlist> 22.417 + 22.418 +&interaction.template.simple.manyfilters; 22.419 + 22.420 + <note> 22.421 + <para> If you try to apply a filter to a piece of data that it 22.422 + cannot process, Mercurial will fail and print a Python 22.423 + exception. For example, trying to run the output of the 22.424 + <literal role="template-keyword">desc</literal> keyword into 22.425 + the <literal role="template-kw-filt-date">isodate</literal> 22.426 + filter is not a good idea.</para> 22.427 + </note> 22.428 + 22.429 + <sect2> 22.430 + <title>Combining filters</title> 22.431 + 22.432 + <para>It is easy to combine filters to yield output in the form 22.433 + you would like. The following chain of filters tidies up a 22.434 + description, then makes sure that it fits cleanly into 68 22.435 + columns, then indents it by a further 8 characters (at least 22.436 + on Unix-like systems, where a tab is conventionally 8 22.437 + characters wide).</para> 22.438 + 22.439 + &interaction.template.simple.combine; 22.440 + 22.441 + <para>Note the use of <quote><literal>\t</literal></quote> (a 22.442 + tab character) in the template to force the first line to be 22.443 + indented; this is necessary since <literal 22.444 + role="template-keyword">tabindent</literal> indents all 22.445 + lines <emphasis>except</emphasis> the first.</para> 22.446 + 22.447 + <para>Keep in mind that the order of filters in a chain is 22.448 + significant. The first filter is applied to the result of the 22.449 + keyword; the second to the result of the first filter; and so 22.450 + on. For example, using <literal>fill68|tabindent</literal> 22.451 + gives very different results from 22.452 + <literal>tabindent|fill68</literal>.</para> 22.453 + 22.454 + 22.455 + </sect2> 22.456 + </sect1> 22.457 + <sect1> 22.458 + <title>From templates to styles</title> 22.459 + 22.460 + <para>A command line template provides a quick and simple way to 22.461 + format some output. Templates can become verbose, though, and 22.462 + it's useful to be able to give a template a name. A style file 22.463 + is a template with a name, stored in a file.</para> 22.464 + 22.465 + <para>More than that, using a style file unlocks the power of 22.466 + Mercurial's templating engine in ways that are not possible 22.467 + using the command line <option 22.468 + role="hg-opt-log">--template</option> option.</para> 22.469 + 22.470 + <sect2> 22.471 + <title>The simplest of style files</title> 22.472 + 22.473 + <para>Our simple style file contains just one line:</para> 22.474 + 22.475 + &interaction.template.simple.rev; 22.476 + 22.477 + <para>This tells Mercurial, <quote>if you're printing a 22.478 + changeset, use the text on the right as the 22.479 + template</quote>.</para> 22.480 + 22.481 + </sect2> 22.482 + <sect2> 22.483 + <title>Style file syntax</title> 22.484 + 22.485 + <para>The syntax rules for a style file are simple.</para> 22.486 + 22.487 + <itemizedlist> 22.488 + <listitem><para>The file is processed one line at a 22.489 + time.</para> 22.490 + </listitem> 22.491 + <listitem><para>Leading and trailing white space are 22.492 + ignored.</para> 22.493 + </listitem> 22.494 + <listitem><para>Empty lines are skipped.</para> 22.495 + </listitem> 22.496 + <listitem><para>If a line starts with either of the characters 22.497 + <quote><literal>#</literal></quote> or 22.498 + <quote><literal>;</literal></quote>, the entire line is 22.499 + treated as a comment, and skipped as if empty.</para> 22.500 + </listitem> 22.501 + <listitem><para>A line starts with a keyword. This must start 22.502 + with an alphabetic character or underscore, and can 22.503 + subsequently contain any alphanumeric character or 22.504 + underscore. (In regexp notation, a keyword must match 22.505 + <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para> 22.506 + </listitem> 22.507 + <listitem><para>The next element must be an 22.508 + <quote><literal>=</literal></quote> character, which can 22.509 + be preceded or followed by an arbitrary amount of white 22.510 + space.</para> 22.511 + </listitem> 22.512 + <listitem><para>If the rest of the line starts and ends with 22.513 + matching quote characters (either single or double quote), 22.514 + it is treated as a template body.</para> 22.515 + </listitem> 22.516 + <listitem><para>If the rest of the line <emphasis>does 22.517 + not</emphasis> start with a quote character, it is 22.518 + treated as the name of a file; the contents of this file 22.519 + will be read and used as a template body.</para> 22.520 + </listitem></itemizedlist> 22.521 + 22.522 + </sect2> 22.523 + </sect1> 22.524 + <sect1> 22.525 + <title>Style files by example</title> 22.526 + 22.527 + <para>To illustrate how to write a style file, we will construct a 22.528 + few by example. Rather than provide a complete style file and 22.529 + walk through it, we'll mirror the usual process of developing a 22.530 + style file by starting with something very simple, and walking 22.531 + through a series of successively more complete examples.</para> 22.532 + 22.533 + <sect2> 22.534 + <title>Identifying mistakes in style files</title> 22.535 + 22.536 + <para>If Mercurial encounters a problem in a style file you are 22.537 + working on, it prints a terse error message that, once you 22.538 + figure out what it means, is actually quite useful.</para> 22.539 + 22.540 +&interaction.template.svnstyle.syntax.input; 22.541 + 22.542 + <para>Notice that <filename>broken.style</filename> attempts to 22.543 + define a <literal>changeset</literal> keyword, but forgets to 22.544 + give any content for it. When instructed to use this style 22.545 + file, Mercurial promptly complains.</para> 22.546 + 22.547 + &interaction.template.svnstyle.syntax.error; 22.548 + 22.549 + <para>This error message looks intimidating, but it is not too 22.550 + hard to follow.</para> 22.551 + 22.552 + <itemizedlist> 22.553 + <listitem><para>The first component is simply Mercurial's way 22.554 + of saying <quote>I am giving up</quote>.</para> 22.555 + <programlisting>___abort___: broken.style:1: parse error</programlisting> 22.556 + </listitem> 22.557 + <listitem><para>Next comes the name of the style file that 22.558 + contains the error.</para> 22.559 + <programlisting>abort: ___broken.style___:1: parse error</programlisting> 22.560 + </listitem> 22.561 + <listitem><para>Following the file name is the line number 22.562 + where the error was encountered.</para> 22.563 + <programlisting>abort: broken.style:___1___: parse error</programlisting> 22.564 + </listitem> 22.565 + <listitem><para>Finally, a description of what went 22.566 + wrong.</para> 22.567 + <programlisting>abort: broken.style:1: ___parse error___</programlisting> 22.568 + </listitem> 22.569 + <listitem><para>The description of the problem is not always 22.570 + clear (as in this case), but even when it is cryptic, it 22.571 + is almost always trivial to visually inspect the offending 22.572 + line in the style file and see what is wrong.</para> 22.573 + </listitem></itemizedlist> 22.574 + 22.575 + </sect2> 22.576 + <sect2> 22.577 + <title>Uniquely identifying a repository</title> 22.578 + 22.579 + <para>If you would like to be able to identify a Mercurial 22.580 + repository <quote>fairly uniquely</quote> using a short string 22.581 + as an identifier, you can use the first revision in the 22.582 + repository.</para> 22.583 + 22.584 + &interaction.template.svnstyle.id; 22.585 + 22.586 + <para>This is not guaranteed to be unique, but it is 22.587 + nevertheless useful in many cases.</para> 22.588 + <itemizedlist> 22.589 + <listitem><para>It will not work in a completely empty 22.590 + repository, because such a repository does not have a 22.591 + revision zero.</para> 22.592 + </listitem> 22.593 + <listitem><para>Neither will it work in the (extremely rare) 22.594 + case where a repository is a merge of two or more formerly 22.595 + independent repositories, and you still have those 22.596 + repositories around.</para> 22.597 + </listitem></itemizedlist> 22.598 + <para>Here are some uses to which you could put this 22.599 + identifier:</para> 22.600 + <itemizedlist> 22.601 + <listitem><para>As a key into a table for a database that 22.602 + manages repositories on a server.</para> 22.603 + </listitem> 22.604 + <listitem><para>As half of a {<emphasis>repository 22.605 + ID</emphasis>, <emphasis>revision ID</emphasis>} tuple. 22.606 + Save this information away when you run an automated build 22.607 + or other activity, so that you can <quote>replay</quote> 22.608 + the build later if necessary.</para> 22.609 + </listitem></itemizedlist> 22.610 + 22.611 + </sect2> 22.612 + <sect2> 22.613 + <title>Mimicking Subversion's output</title> 22.614 + 22.615 + <para>Let's try to emulate the default output format used by 22.616 + another revision control tool, Subversion.</para> 22.617 + 22.618 + &interaction.template.svnstyle.short; 22.619 + 22.620 + <para>Since Subversion's output style is fairly simple, it is 22.621 + easy to copy-and-paste a hunk of its output into a file, and 22.622 + replace the text produced above by Subversion with the 22.623 + template values we'd like to see expanded.</para> 22.624 + 22.625 + &interaction.template.svnstyle.template; 22.626 + 22.627 + <para>There are a few small ways in which this template deviates 22.628 + from the output produced by Subversion.</para> 22.629 + <itemizedlist> 22.630 + <listitem><para>Subversion prints a <quote>readable</quote> 22.631 + date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the 22.632 + example output above) in parentheses. Mercurial's 22.633 + templating engine does not provide a way to display a date 22.634 + in this format without also printing the time and time 22.635 + zone.</para> 22.636 + </listitem> 22.637 + <listitem><para>We emulate Subversion's printing of 22.638 + <quote>separator</quote> lines full of 22.639 + <quote><literal>-</literal></quote> characters by ending 22.640 + the template with such a line. We use the templating 22.641 + engine's <literal role="template-keyword">header</literal> 22.642 + keyword to print a separator line as the first line of 22.643 + output (see below), thus achieving similar output to 22.644 + Subversion.</para> 22.645 + </listitem> 22.646 + <listitem><para>Subversion's output includes a count in the 22.647 + header of the number of lines in the commit message. We 22.648 + cannot replicate this in Mercurial; the templating engine 22.649 + does not currently provide a filter that counts the number 22.650 + of lines the template generates.</para> 22.651 + </listitem></itemizedlist> 22.652 + <para>It took me no more than a minute or two of work to replace 22.653 + literal text from an example of Subversion's output with some 22.654 + keywords and filters to give the template above. The style 22.655 + file simply refers to the template.</para> 22.656 + 22.657 + &interaction.template.svnstyle.style; 22.658 + 22.659 + <para>We could have included the text of the template file 22.660 + directly in the style file by enclosing it in quotes and 22.661 + replacing the newlines with 22.662 + <quote><literal>\n</literal></quote> sequences, but it would 22.663 + have made the style file too difficult to read. Readability 22.664 + is a good guide when you're trying to decide whether some text 22.665 + belongs in a style file, or in a template file that the style 22.666 + file points to. If the style file will look too big or 22.667 + cluttered if you insert a literal piece of text, drop it into 22.668 + a template instead.</para> 22.669 + 22.670 + </sect2> 22.671 + </sect1> 22.672 +</chapter> 22.673 + 22.674 +<!-- 22.675 +local variables: 22.676 +sgml-parent-document: ("00book.xml" "book" "chapter") 22.677 +end: 22.678 +-->
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/en/ch11-mq.xml Thu Mar 19 20:54:12 2009 -0700 23.3 @@ -0,0 +1,1322 @@ 23.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 23.5 + 23.6 +<chapter id="chap:mq"> 23.7 + <?dbhtml filename="managing-change-with-mercurial-queues.html"?> 23.8 + <title>Managing change with Mercurial Queues</title> 23.9 + 23.10 + <sect1 id="sec:mq:patch-mgmt"> 23.11 + <title>The patch management problem</title> 23.12 + 23.13 + <para>Here is a common scenario: you need to install a software 23.14 + package from source, but you find a bug that you must fix in the 23.15 + source before you can start using the package. You make your 23.16 + changes, forget about the package for a while, and a few months 23.17 + later you need to upgrade to a newer version of the package. If 23.18 + the newer version of the package still has the bug, you must 23.19 + extract your fix from the older source tree and apply it against 23.20 + the newer version. This is a tedious task, and it's easy to 23.21 + make mistakes.</para> 23.22 + 23.23 + <para>This is a simple case of the <quote>patch management</quote> 23.24 + problem. You have an <quote>upstream</quote> source tree that 23.25 + you can't change; you need to make some local changes on top of 23.26 + the upstream tree; and you'd like to be able to keep those 23.27 + changes separate, so that you can apply them to newer versions 23.28 + of the upstream source.</para> 23.29 + 23.30 + <para>The patch management problem arises in many situations. 23.31 + Probably the most visible is that a user of an open source 23.32 + software project will contribute a bug fix or new feature to the 23.33 + project's maintainers in the form of a patch.</para> 23.34 + 23.35 + <para>Distributors of operating systems that include open source 23.36 + software often need to make changes to the packages they 23.37 + distribute so that they will build properly in their 23.38 + environments.</para> 23.39 + 23.40 + <para>When you have few changes to maintain, it is easy to manage 23.41 + a single patch using the standard <command>diff</command> and 23.42 + <command>patch</command> programs (see section <xref 23.43 + linkend="sec:mq:patch"/> for a discussion of these 23.44 + tools). Once the number of changes grows, it starts to make 23.45 + sense to maintain patches as discrete <quote>chunks of 23.46 + work,</quote> so that for example a single patch will contain 23.47 + only one bug fix (the patch might modify several files, but it's 23.48 + doing <quote>only one thing</quote>), and you may have a number 23.49 + of such patches for different bugs you need fixed and local 23.50 + changes you require. In this situation, if you submit a bug fix 23.51 + patch to the upstream maintainers of a package and they include 23.52 + your fix in a subsequent release, you can simply drop that 23.53 + single patch when you're updating to the newer release.</para> 23.54 + 23.55 + <para>Maintaining a single patch against an upstream tree is a 23.56 + little tedious and error-prone, but not difficult. However, the 23.57 + complexity of the problem grows rapidly as the number of patches 23.58 + you have to maintain increases. With more than a tiny number of 23.59 + patches in hand, understanding which ones you have applied and 23.60 + maintaining them moves from messy to overwhelming.</para> 23.61 + 23.62 + <para>Fortunately, Mercurial includes a powerful extension, 23.63 + Mercurial Queues (or simply <quote>MQ</quote>), that massively 23.64 + simplifies the patch management problem.</para> 23.65 + 23.66 + </sect1> 23.67 + <sect1 id="sec:mq:history"> 23.68 + <title>The prehistory of Mercurial Queues</title> 23.69 + 23.70 + <para>During the late 1990s, several Linux kernel developers 23.71 + started to maintain <quote>patch series</quote> that modified 23.72 + the behaviour of the Linux kernel. Some of these series were 23.73 + focused on stability, some on feature coverage, and others were 23.74 + more speculative.</para> 23.75 + 23.76 + <para>The sizes of these patch series grew rapidly. In 2002, 23.77 + Andrew Morton published some shell scripts he had been using to 23.78 + automate the task of managing his patch queues. Andrew was 23.79 + successfully using these scripts to manage hundreds (sometimes 23.80 + thousands) of patches on top of the Linux kernel.</para> 23.81 + 23.82 + <sect2 id="sec:mq:quilt"> 23.83 + <title>A patchwork quilt</title> 23.84 + 23.85 + <para>In early 2003, Andreas Gruenbacher and Martin Quinson 23.86 + borrowed the approach of Andrew's scripts and published a tool 23.87 + called <quote>patchwork quilt</quote> 23.88 + <citation>web:quilt</citation>, or simply <quote>quilt</quote> 23.89 + (see <citation>gruenbacher:2005</citation> for a paper 23.90 + describing it). Because quilt substantially automated patch 23.91 + management, it rapidly gained a large following among open 23.92 + source software developers.</para> 23.93 + 23.94 + <para>Quilt manages a <emphasis>stack of patches</emphasis> on 23.95 + top of a directory tree. To begin, you tell quilt to manage a 23.96 + directory tree, and tell it which files you want to manage; it 23.97 + stores away the names and contents of those files. To fix a 23.98 + bug, you create a new patch (using a single command), edit the 23.99 + files you need to fix, then <quote>refresh</quote> the 23.100 + patch.</para> 23.101 + 23.102 + <para>The refresh step causes quilt to scan the directory tree; 23.103 + it updates the patch with all of the changes you have made. 23.104 + You can create another patch on top of the first, which will 23.105 + track the changes required to modify the tree from <quote>tree 23.106 + with one patch applied</quote> to <quote>tree with two 23.107 + patches applied</quote>.</para> 23.108 + 23.109 + <para>You can <emphasis>change</emphasis> which patches are 23.110 + applied to the tree. If you <quote>pop</quote> a patch, the 23.111 + changes made by that patch will vanish from the directory 23.112 + tree. Quilt remembers which patches you have popped, though, 23.113 + so you can <quote>push</quote> a popped patch again, and the 23.114 + directory tree will be restored to contain the modifications 23.115 + in the patch. Most importantly, you can run the 23.116 + <quote>refresh</quote> command at any time, and the topmost 23.117 + applied patch will be updated. This means that you can, at 23.118 + any time, change both which patches are applied and what 23.119 + modifications those patches make.</para> 23.120 + 23.121 + <para>Quilt knows nothing about revision control tools, so it 23.122 + works equally well on top of an unpacked tarball or a 23.123 + Subversion working copy.</para> 23.124 + 23.125 + </sect2> 23.126 + <sect2 id="sec:mq:quilt-mq"> 23.127 + <title>From patchwork quilt to Mercurial Queues</title> 23.128 + 23.129 + <para>In mid-2005, Chris Mason took the features of quilt and 23.130 + wrote an extension that he called Mercurial Queues, which 23.131 + added quilt-like behaviour to Mercurial.</para> 23.132 + 23.133 + <para>The key difference between quilt and MQ is that quilt 23.134 + knows nothing about revision control systems, while MQ is 23.135 + <emphasis>integrated</emphasis> into Mercurial. Each patch 23.136 + that you push is represented as a Mercurial changeset. Pop a 23.137 + patch, and the changeset goes away.</para> 23.138 + 23.139 + <para>Because quilt does not care about revision control tools, 23.140 + it is still a tremendously useful piece of software to know 23.141 + about for situations where you cannot use Mercurial and 23.142 + MQ.</para> 23.143 + 23.144 + </sect2> 23.145 + </sect1> 23.146 + <sect1> 23.147 + <title>The huge advantage of MQ</title> 23.148 + 23.149 + <para>I cannot overstate the value that MQ offers through the 23.150 + unification of patches and revision control.</para> 23.151 + 23.152 + <para>A major reason that patches have persisted in the free 23.153 + software and open source world&emdash;in spite of the 23.154 + availability of increasingly capable revision control tools over 23.155 + the years&emdash;is the <emphasis>agility</emphasis> they 23.156 + offer.</para> 23.157 + 23.158 + <para>Traditional revision control tools make a permanent, 23.159 + irreversible record of everything that you do. While this has 23.160 + great value, it's also somewhat stifling. If you want to 23.161 + perform a wild-eyed experiment, you have to be careful in how 23.162 + you go about it, or you risk leaving unneeded&emdash;or worse, 23.163 + misleading or destabilising&emdash;traces of your missteps and 23.164 + errors in the permanent revision record.</para> 23.165 + 23.166 + <para>By contrast, MQ's marriage of distributed revision control 23.167 + with patches makes it much easier to isolate your work. Your 23.168 + patches live on top of normal revision history, and you can make 23.169 + them disappear or reappear at will. If you don't like a patch, 23.170 + you can drop it. If a patch isn't quite as you want it to be, 23.171 + simply fix it&emdash;as many times as you need to, until you 23.172 + have refined it into the form you desire.</para> 23.173 + 23.174 + <para>As an example, the integration of patches with revision 23.175 + control makes understanding patches and debugging their 23.176 + effects&emdash;and their interplay with the code they're based 23.177 + on&emdash;<emphasis>enormously</emphasis> easier. Since every 23.178 + applied patch has an associated changeset, you can give <command 23.179 + role="hg-cmd">hg log</command> a file name to see which 23.180 + changesets and patches affected the file. You can use the 23.181 + <command role="hg-cmd">hg bisect</command> command to 23.182 + binary-search through all changesets and applied patches to see 23.183 + where a bug got introduced or fixed. You can use the <command 23.184 + role="hg-cmd">hg annotate</command> command to see which 23.185 + changeset or patch modified a particular line of a source file. 23.186 + And so on.</para> 23.187 + 23.188 + </sect1> 23.189 + <sect1 id="sec:mq:patch"> 23.190 + <title>Understanding patches</title> 23.191 + 23.192 + <para>Because MQ doesn't hide its patch-oriented nature, it is 23.193 + helpful to understand what patches are, and a little about the 23.194 + tools that work with them.</para> 23.195 + 23.196 + <para>The traditional Unix <command>diff</command> command 23.197 + compares two files, and prints a list of differences between 23.198 + them. The <command>patch</command> command understands these 23.199 + differences as <emphasis>modifications</emphasis> to make to a 23.200 + file. Take a look below for a simple example of these commands 23.201 + in action.</para> 23.202 + 23.203 +&interaction.mq.dodiff.diff; 23.204 + 23.205 + <para>The type of file that <command>diff</command> generates (and 23.206 + <command>patch</command> takes as input) is called a 23.207 + <quote>patch</quote> or a <quote>diff</quote>; there is no 23.208 + difference between a patch and a diff. (We'll use the term 23.209 + <quote>patch</quote>, since it's more commonly used.)</para> 23.210 + 23.211 + <para>A patch file can start with arbitrary text; the 23.212 + <command>patch</command> command ignores this text, but MQ uses 23.213 + it as the commit message when creating changesets. To find the 23.214 + beginning of the patch content, <command>patch</command> 23.215 + searches for the first line that starts with the string 23.216 + <quote><literal>diff -</literal></quote>.</para> 23.217 + 23.218 + <para>MQ works with <emphasis>unified</emphasis> diffs 23.219 + (<command>patch</command> can accept several other diff formats, 23.220 + but MQ doesn't). A unified diff contains two kinds of header. 23.221 + The <emphasis>file header</emphasis> describes the file being 23.222 + modified; it contains the name of the file to modify. When 23.223 + <command>patch</command> sees a new file header, it looks for a 23.224 + file with that name to start modifying.</para> 23.225 + 23.226 + <para>After the file header comes a series of 23.227 + <emphasis>hunks</emphasis>. Each hunk starts with a header; 23.228 + this identifies the range of line numbers within the file that 23.229 + the hunk should modify. Following the header, a hunk starts and 23.230 + ends with a few (usually three) lines of text from the 23.231 + unmodified file; these are called the 23.232 + <emphasis>context</emphasis> for the hunk. If there's only a 23.233 + small amount of context between successive hunks, 23.234 + <command>diff</command> doesn't print a new hunk header; it just 23.235 + runs the hunks together, with a few lines of context between 23.236 + modifications.</para> 23.237 + 23.238 + <para>Each line of context begins with a space character. Within 23.239 + the hunk, a line that begins with 23.240 + <quote><literal>-</literal></quote> means <quote>remove this 23.241 + line,</quote> while a line that begins with 23.242 + <quote><literal>+</literal></quote> means <quote>insert this 23.243 + line.</quote> For example, a line that is modified is 23.244 + represented by one deletion and one insertion.</para> 23.245 + 23.246 + <para>We will return to some of the more subtle aspects of patches 23.247 + later (in section <xref linkend="sec:mq:adv-patch"/>), but you 23.248 + should have 23.249 + enough information now to use MQ.</para> 23.250 + 23.251 + </sect1> 23.252 + <sect1 id="sec:mq:start"> 23.253 + <title>Getting started with Mercurial Queues</title> 23.254 + 23.255 + <para>Because MQ is implemented as an extension, you must 23.256 + explicitly enable before you can use it. (You don't need to 23.257 + download anything; MQ ships with the standard Mercurial 23.258 + distribution.) To enable MQ, edit your <filename 23.259 + role="home">~/.hgrc</filename> file, and add the lines 23.260 + below.</para> 23.261 + 23.262 + <programlisting>[extensions] 23.263 +hgext.mq =</programlisting> 23.264 + 23.265 + <para>Once the extension is enabled, it will make a number of new 23.266 + commands available. To verify that the extension is working, 23.267 + you can use <command role="hg-cmd">hg help</command> to see if 23.268 + the <command role="hg-ext-mq">qinit</command> command is now 23.269 + available.</para> 23.270 + 23.271 +&interaction.mq.qinit-help.help; 23.272 + 23.273 + <para>You can use MQ with <emphasis>any</emphasis> Mercurial 23.274 + repository, and its commands only operate within that 23.275 + repository. To get started, simply prepare the repository using 23.276 + the <command role="hg-ext-mq">qinit</command> command.</para> 23.277 + 23.278 +&interaction.mq.tutorial.qinit; 23.279 + 23.280 + <para>This command creates an empty directory called <filename 23.281 + role="special" class="directory">.hg/patches</filename>, where 23.282 + MQ will keep its metadata. As with many Mercurial commands, the 23.283 + <command role="hg-ext-mq">qinit</command> command prints nothing 23.284 + if it succeeds.</para> 23.285 + 23.286 + <sect2> 23.287 + <title>Creating a new patch</title> 23.288 + 23.289 + <para>To begin work on a new patch, use the <command 23.290 + role="hg-ext-mq">qnew</command> command. This command takes 23.291 + one argument, the name of the patch to create.</para> 23.292 + 23.293 + <para>MQ will use this as the name of an actual file in the 23.294 + <filename role="special" 23.295 + class="directory">.hg/patches</filename> directory, as you 23.296 + can see below.</para> 23.297 + 23.298 +&interaction.mq.tutorial.qnew; 23.299 + 23.300 + <para>Also newly present in the <filename role="special" 23.301 + class="directory">.hg/patches</filename> directory are two 23.302 + other files, <filename role="special">series</filename> and 23.303 + <filename role="special">status</filename>. The <filename 23.304 + role="special">series</filename> file lists all of the 23.305 + patches that MQ knows about for this repository, with one 23.306 + patch per line. Mercurial uses the <filename 23.307 + role="special">status</filename> file for internal 23.308 + book-keeping; it tracks all of the patches that MQ has 23.309 + <emphasis>applied</emphasis> in this repository.</para> 23.310 + 23.311 + <note> 23.312 + <para> You may sometimes want to edit the <filename 23.313 + role="special">series</filename> file by hand; for 23.314 + example, to change the sequence in which some patches are 23.315 + applied. However, manually editing the <filename 23.316 + role="special">status</filename> file is almost always a 23.317 + bad idea, as it's easy to corrupt MQ's idea of what is 23.318 + happening.</para> 23.319 + </note> 23.320 + 23.321 + <para>Once you have created your new patch, you can edit files 23.322 + in the working directory as you usually would. All of the 23.323 + normal Mercurial commands, such as <command role="hg-cmd">hg 23.324 + diff</command> and <command role="hg-cmd">hg 23.325 + annotate</command>, work exactly as they did before.</para> 23.326 + 23.327 + </sect2> 23.328 + <sect2> 23.329 + <title>Refreshing a patch</title> 23.330 + 23.331 + <para>When you reach a point where you want to save your work, 23.332 + use the <command role="hg-ext-mq">qrefresh</command> command 23.333 + to update the patch you are working on.</para> 23.334 + 23.335 +&interaction.mq.tutorial.qrefresh; 23.336 + 23.337 + <para>This command folds the changes you have made in the 23.338 + working directory into your patch, and updates its 23.339 + corresponding changeset to contain those changes.</para> 23.340 + 23.341 + <para>You can run <command role="hg-ext-mq">qrefresh</command> 23.342 + as often as you like, so it's a good way to 23.343 + <quote>checkpoint</quote> your work. Refresh your patch at an 23.344 + opportune time; try an experiment; and if the experiment 23.345 + doesn't work out, <command role="hg-cmd">hg revert</command> 23.346 + your modifications back to the last time you refreshed.</para> 23.347 + 23.348 +&interaction.mq.tutorial.qrefresh2; 23.349 + 23.350 + </sect2> 23.351 + <sect2> 23.352 + <title>Stacking and tracking patches</title> 23.353 + 23.354 + <para>Once you have finished working on a patch, or need to work 23.355 + on another, you can use the <command 23.356 + role="hg-ext-mq">qnew</command> command again to create a 23.357 + new patch. Mercurial will apply this patch on top of your 23.358 + existing patch.</para> 23.359 + 23.360 +&interaction.mq.tutorial.qnew2; 23.361 + <para>Notice that the patch contains the changes in our prior 23.362 + patch as part of its context (you can see this more clearly in 23.363 + the output of <command role="hg-cmd">hg 23.364 + annotate</command>).</para> 23.365 + 23.366 + <para>So far, with the exception of <command 23.367 + role="hg-ext-mq">qnew</command> and <command 23.368 + role="hg-ext-mq">qrefresh</command>, we've been careful to 23.369 + only use regular Mercurial commands. However, MQ provides 23.370 + many commands that are easier to use when you are thinking 23.371 + about patches, as illustrated below.</para> 23.372 + 23.373 +&interaction.mq.tutorial.qseries; 23.374 + 23.375 + <itemizedlist> 23.376 + <listitem><para>The <command 23.377 + role="hg-ext-mq">qseries</command> command lists every 23.378 + patch that MQ knows about in this repository, from oldest 23.379 + to newest (most recently 23.380 + <emphasis>created</emphasis>).</para> 23.381 + </listitem> 23.382 + <listitem><para>The <command 23.383 + role="hg-ext-mq">qapplied</command> command lists every 23.384 + patch that MQ has <emphasis>applied</emphasis> in this 23.385 + repository, again from oldest to newest (most recently 23.386 + applied).</para> 23.387 + </listitem></itemizedlist> 23.388 + 23.389 + </sect2> 23.390 + <sect2> 23.391 + <title>Manipulating the patch stack</title> 23.392 + 23.393 + <para>The previous discussion implied that there must be a 23.394 + difference between <quote>known</quote> and 23.395 + <quote>applied</quote> patches, and there is. MQ can manage a 23.396 + patch without it being applied in the repository.</para> 23.397 + 23.398 + <para>An <emphasis>applied</emphasis> patch has a corresponding 23.399 + changeset in the repository, and the effects of the patch and 23.400 + changeset are visible in the working directory. You can undo 23.401 + the application of a patch using the <command 23.402 + role="hg-ext-mq">qpop</command> command. MQ still 23.403 + <emphasis>knows about</emphasis>, or manages, a popped patch, 23.404 + but the patch no longer has a corresponding changeset in the 23.405 + repository, and the working directory does not contain the 23.406 + changes made by the patch. Figure <xref 23.407 + linkend="fig:mq:stack"/> illustrates 23.408 + the difference between applied and tracked patches.</para> 23.409 + 23.410 + <informalfigure id="fig:mq:stack"> 23.411 + <mediaobject><imageobject><imagedata 23.412 + fileref="mq-stack"/></imageobject><textobject><phrase>XXX 23.413 + add text</phrase></textobject><caption><para>Applied and 23.414 + unapplied patches in the MQ patch 23.415 + stack</para></caption></mediaobject> 23.416 + </informalfigure> 23.417 + 23.418 + <para>You can reapply an unapplied, or popped, patch using the 23.419 + <command role="hg-ext-mq">qpush</command> command. This 23.420 + creates a new changeset to correspond to the patch, and the 23.421 + patch's changes once again become present in the working 23.422 + directory. See below for examples of <command 23.423 + role="hg-ext-mq">qpop</command> and <command 23.424 + role="hg-ext-mq">qpush</command> in action.</para> 23.425 +&interaction.mq.tutorial.qpop; 23.426 + 23.427 + <para>Notice that once we have popped a patch or two patches, 23.428 + the output of <command role="hg-ext-mq">qseries</command> 23.429 + remains the same, while that of <command 23.430 + role="hg-ext-mq">qapplied</command> has changed.</para> 23.431 + 23.432 + 23.433 + </sect2> 23.434 + <sect2> 23.435 + <title>Pushing and popping many patches</title> 23.436 + 23.437 + <para>While <command role="hg-ext-mq">qpush</command> and 23.438 + <command role="hg-ext-mq">qpop</command> each operate on a 23.439 + single patch at a time by default, you can push and pop many 23.440 + patches in one go. The <option 23.441 + role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to 23.442 + <command role="hg-ext-mq">qpush</command> causes it to push 23.443 + all unapplied patches, while the <option 23.444 + role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command 23.445 + role="hg-ext-mq">qpop</command> causes it to pop all applied 23.446 + patches. (For some more ways to push and pop many patches, 23.447 + see section <xref linkend="sec:mq:perf"/> 23.448 + below.)</para> 23.449 + 23.450 +&interaction.mq.tutorial.qpush-a; 23.451 + 23.452 + </sect2> 23.453 + <sect2> 23.454 + <title>Safety checks, and overriding them</title> 23.455 + 23.456 + <para>Several MQ commands check the working directory before 23.457 + they do anything, and fail if they find any modifications. 23.458 + They do this to ensure that you won't lose any changes that 23.459 + you have made, but not yet incorporated into a patch. The 23.460 + example below illustrates this; the <command 23.461 + role="hg-ext-mq">qnew</command> command will not create a 23.462 + new patch if there are outstanding changes, caused in this 23.463 + case by the <command role="hg-cmd">hg add</command> of 23.464 + <filename>file3</filename>.</para> 23.465 + 23.466 +&interaction.mq.tutorial.add; 23.467 + 23.468 + <para>Commands that check the working directory all take an 23.469 + <quote>I know what I'm doing</quote> option, which is always 23.470 + named <option>-f</option>. The exact meaning of 23.471 + <option>-f</option> depends on the command. For example, 23.472 + <command role="hg-cmd">hg qnew <option 23.473 + role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command> 23.474 + will incorporate any outstanding changes into the new patch it 23.475 + creates, but <command role="hg-cmd">hg qpop <option 23.476 + role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command> 23.477 + will revert modifications to any files affected by the patch 23.478 + that it is popping. Be sure to read the documentation for a 23.479 + command's <option>-f</option> option before you use it!</para> 23.480 + 23.481 + </sect2> 23.482 + <sect2> 23.483 + <title>Working on several patches at once</title> 23.484 + 23.485 + <para>The <command role="hg-ext-mq">qrefresh</command> command 23.486 + always refreshes the <emphasis>topmost</emphasis> applied 23.487 + patch. This means that you can suspend work on one patch (by 23.488 + refreshing it), pop or push to make a different patch the top, 23.489 + and work on <emphasis>that</emphasis> patch for a 23.490 + while.</para> 23.491 + 23.492 + <para>Here's an example that illustrates how you can use this 23.493 + ability. Let's say you're developing a new feature as two 23.494 + patches. The first is a change to the core of your software, 23.495 + and the second&emdash;layered on top of the 23.496 + first&emdash;changes the user interface to use the code you 23.497 + just added to the core. If you notice a bug in the core while 23.498 + you're working on the UI patch, it's easy to fix the core. 23.499 + Simply <command role="hg-ext-mq">qrefresh</command> the UI 23.500 + patch to save your in-progress changes, and <command 23.501 + role="hg-ext-mq">qpop</command> down to the core patch. Fix 23.502 + the core bug, <command role="hg-ext-mq">qrefresh</command> the 23.503 + core patch, and <command role="hg-ext-mq">qpush</command> back 23.504 + to the UI patch to continue where you left off.</para> 23.505 + 23.506 + </sect2> 23.507 + </sect1> 23.508 + <sect1 id="sec:mq:adv-patch"> 23.509 + <title>More about patches</title> 23.510 + 23.511 + <para>MQ uses the GNU <command>patch</command> command to apply 23.512 + patches, so it's helpful to know a few more detailed aspects of 23.513 + how <command>patch</command> works, and about patches 23.514 + themselves.</para> 23.515 + 23.516 + <sect2> 23.517 + <title>The strip count</title> 23.518 + 23.519 + <para>If you look at the file headers in a patch, you will 23.520 + notice that the pathnames usually have an extra component on 23.521 + the front that isn't present in the actual path name. This is 23.522 + a holdover from the way that people used to generate patches 23.523 + (people still do this, but it's somewhat rare with modern 23.524 + revision control tools).</para> 23.525 + 23.526 + <para>Alice would unpack a tarball, edit her files, then decide 23.527 + that she wanted to create a patch. So she'd rename her 23.528 + working directory, unpack the tarball again (hence the need 23.529 + for the rename), and use the <option 23.530 + role="cmd-opt-diff">-r</option> and <option 23.531 + role="cmd-opt-diff">-N</option> options to 23.532 + <command>diff</command> to recursively generate a patch 23.533 + between the unmodified directory and the modified one. The 23.534 + result would be that the name of the unmodified directory 23.535 + would be at the front of the left-hand path in every file 23.536 + header, and the name of the modified directory would be at the 23.537 + front of the right-hand path.</para> 23.538 + 23.539 + <para>Since someone receiving a patch from the Alices of the net 23.540 + would be unlikely to have unmodified and modified directories 23.541 + with exactly the same names, the <command>patch</command> 23.542 + command has a <option role="cmd-opt-patch">-p</option> option 23.543 + that indicates the number of leading path name components to 23.544 + strip when trying to apply a patch. This number is called the 23.545 + <emphasis>strip count</emphasis>.</para> 23.546 + 23.547 + <para>An option of <quote><literal>-p1</literal></quote> means 23.548 + <quote>use a strip count of one</quote>. If 23.549 + <command>patch</command> sees a file name 23.550 + <filename>foo/bar/baz</filename> in a file header, it will 23.551 + strip <filename>foo</filename> and try to patch a file named 23.552 + <filename>bar/baz</filename>. (Strictly speaking, the strip 23.553 + count refers to the number of <emphasis>path 23.554 + separators</emphasis> (and the components that go with them 23.555 + ) to strip. A strip count of one will turn 23.556 + <filename>foo/bar</filename> into <filename>bar</filename>, 23.557 + but <filename>/foo/bar</filename> (notice the extra leading 23.558 + slash) into <filename>foo/bar</filename>.)</para> 23.559 + 23.560 + <para>The <quote>standard</quote> strip count for patches is 23.561 + one; almost all patches contain one leading path name 23.562 + component that needs to be stripped. Mercurial's <command 23.563 + role="hg-cmd">hg diff</command> command generates path names 23.564 + in this form, and the <command role="hg-cmd">hg 23.565 + import</command> command and MQ expect patches to have a 23.566 + strip count of one.</para> 23.567 + 23.568 + <para>If you receive a patch from someone that you want to add 23.569 + to your patch queue, and the patch needs a strip count other 23.570 + than one, you cannot just <command 23.571 + role="hg-ext-mq">qimport</command> the patch, because 23.572 + <command role="hg-ext-mq">qimport</command> does not yet have 23.573 + a <literal>-p</literal> option (see <ulink role="hg-bug" 23.574 + url="http://www.selenic.com/mercurial/bts/issue311">issue 23.575 + 311</ulink>). Your best bet is to <command 23.576 + role="hg-ext-mq">qnew</command> a patch of your own, then 23.577 + use <command>patch -pN</command> to apply their patch, 23.578 + followed by <command role="hg-cmd">hg addremove</command> to 23.579 + pick up any files added or removed by the patch, followed by 23.580 + <command role="hg-ext-mq">hg qrefresh</command>. This 23.581 + complexity may become unnecessary; see <ulink role="hg-bug" 23.582 + url="http://www.selenic.com/mercurial/bts/issue311">issue 23.583 + 311</ulink> for details. 23.584 + </para> 23.585 + </sect2> 23.586 + <sect2> 23.587 + <title>Strategies for applying a patch</title> 23.588 + 23.589 + <para>When <command>patch</command> applies a hunk, it tries a 23.590 + handful of successively less accurate strategies to try to 23.591 + make the hunk apply. This falling-back technique often makes 23.592 + it possible to take a patch that was generated against an old 23.593 + version of a file, and apply it against a newer version of 23.594 + that file.</para> 23.595 + 23.596 + <para>First, <command>patch</command> tries an exact match, 23.597 + where the line numbers, the context, and the text to be 23.598 + modified must apply exactly. If it cannot make an exact 23.599 + match, it tries to find an exact match for the context, 23.600 + without honouring the line numbering information. If this 23.601 + succeeds, it prints a line of output saying that the hunk was 23.602 + applied, but at some <emphasis>offset</emphasis> from the 23.603 + original line number.</para> 23.604 + 23.605 + <para>If a context-only match fails, <command>patch</command> 23.606 + removes the first and last lines of the context, and tries a 23.607 + <emphasis>reduced</emphasis> context-only match. If the hunk 23.608 + with reduced context succeeds, it prints a message saying that 23.609 + it applied the hunk with a <emphasis>fuzz factor</emphasis> 23.610 + (the number after the fuzz factor indicates how many lines of 23.611 + context <command>patch</command> had to trim before the patch 23.612 + applied).</para> 23.613 + 23.614 + <para>When neither of these techniques works, 23.615 + <command>patch</command> prints a message saying that the hunk 23.616 + in question was rejected. It saves rejected hunks (also 23.617 + simply called <quote>rejects</quote>) to a file with the same 23.618 + name, and an added <filename role="special">.rej</filename> 23.619 + extension. It also saves an unmodified copy of the file with 23.620 + a <filename role="special">.orig</filename> extension; the 23.621 + copy of the file without any extensions will contain any 23.622 + changes made by hunks that <emphasis>did</emphasis> apply 23.623 + cleanly. If you have a patch that modifies 23.624 + <filename>foo</filename> with six hunks, and one of them fails 23.625 + to apply, you will have: an unmodified 23.626 + <filename>foo.orig</filename>, a <filename>foo.rej</filename> 23.627 + containing one hunk, and <filename>foo</filename>, containing 23.628 + the changes made by the five successful hunks.</para> 23.629 + 23.630 + </sect2> 23.631 + <sect2> 23.632 + <title>Some quirks of patch representation</title> 23.633 + 23.634 + <para>There are a few useful things to know about how 23.635 + <command>patch</command> works with files.</para> 23.636 + <itemizedlist> 23.637 + <listitem><para>This should already be obvious, but 23.638 + <command>patch</command> cannot handle binary 23.639 + files.</para> 23.640 + </listitem> 23.641 + <listitem><para>Neither does it care about the executable bit; 23.642 + it creates new files as readable, but not 23.643 + executable.</para> 23.644 + </listitem> 23.645 + <listitem><para><command>patch</command> treats the removal of 23.646 + a file as a diff between the file to be removed and the 23.647 + empty file. So your idea of <quote>I deleted this 23.648 + file</quote> looks like <quote>every line of this file 23.649 + was deleted</quote> in a patch.</para> 23.650 + </listitem> 23.651 + <listitem><para>It treats the addition of a file as a diff 23.652 + between the empty file and the file to be added. So in a 23.653 + patch, your idea of <quote>I added this file</quote> looks 23.654 + like <quote>every line of this file was 23.655 + added</quote>.</para> 23.656 + </listitem> 23.657 + <listitem><para>It treats a renamed file as the removal of the 23.658 + old name, and the addition of the new name. This means 23.659 + that renamed files have a big footprint in patches. (Note 23.660 + also that Mercurial does not currently try to infer when 23.661 + files have been renamed or copied in a patch.)</para> 23.662 + </listitem> 23.663 + <listitem><para><command>patch</command> cannot represent 23.664 + empty files, so you cannot use a patch to represent the 23.665 + notion <quote>I added this empty file to the 23.666 + tree</quote>.</para> 23.667 + </listitem></itemizedlist> 23.668 + </sect2> 23.669 + <sect2> 23.670 + <title>Beware the fuzz</title> 23.671 + 23.672 + <para>While applying a hunk at an offset, or with a fuzz factor, 23.673 + will often be completely successful, these inexact techniques 23.674 + naturally leave open the possibility of corrupting the patched 23.675 + file. The most common cases typically involve applying a 23.676 + patch twice, or at an incorrect location in the file. If 23.677 + <command>patch</command> or <command 23.678 + role="hg-ext-mq">qpush</command> ever mentions an offset or 23.679 + fuzz factor, you should make sure that the modified files are 23.680 + correct afterwards.</para> 23.681 + 23.682 + <para>It's often a good idea to refresh a patch that has applied 23.683 + with an offset or fuzz factor; refreshing the patch generates 23.684 + new context information that will make it apply cleanly. I 23.685 + say <quote>often,</quote> not <quote>always,</quote> because 23.686 + sometimes refreshing a patch will make it fail to apply 23.687 + against a different revision of the underlying files. In some 23.688 + cases, such as when you're maintaining a patch that must sit 23.689 + on top of multiple versions of a source tree, it's acceptable 23.690 + to have a patch apply with some fuzz, provided you've verified 23.691 + the results of the patching process in such cases.</para> 23.692 + 23.693 + </sect2> 23.694 + <sect2> 23.695 + <title>Handling rejection</title> 23.696 + 23.697 + <para>If <command role="hg-ext-mq">qpush</command> fails to 23.698 + apply a patch, it will print an error message and exit. If it 23.699 + has left <filename role="special">.rej</filename> files 23.700 + behind, it is usually best to fix up the rejected hunks before 23.701 + you push more patches or do any further work.</para> 23.702 + 23.703 + <para>If your patch <emphasis>used to</emphasis> apply cleanly, 23.704 + and no longer does because you've changed the underlying code 23.705 + that your patches are based on, Mercurial Queues can help; see 23.706 + section <xref 23.707 + linkend="sec:mq:merge"/> for details.</para> 23.708 + 23.709 + <para>Unfortunately, there aren't any great techniques for 23.710 + dealing with rejected hunks. Most often, you'll need to view 23.711 + the <filename role="special">.rej</filename> file and edit the 23.712 + target file, applying the rejected hunks by hand.</para> 23.713 + 23.714 + <para>If you're feeling adventurous, Neil Brown, a Linux kernel 23.715 + hacker, wrote a tool called <command>wiggle</command> 23.716 + <citation>web:wiggle</citation>, which is more vigorous than 23.717 + <command>patch</command> in its attempts to make a patch 23.718 + apply.</para> 23.719 + 23.720 + <para>Another Linux kernel hacker, Chris Mason (the author of 23.721 + Mercurial Queues), wrote a similar tool called 23.722 + <command>mpatch</command> <citation>web:mpatch</citation>, 23.723 + which takes a simple approach to automating the application of 23.724 + hunks rejected by <command>patch</command>. The 23.725 + <command>mpatch</command> command can help with four common 23.726 + reasons that a hunk may be rejected:</para> 23.727 + 23.728 + <itemizedlist> 23.729 + <listitem><para>The context in the middle of a hunk has 23.730 + changed.</para> 23.731 + </listitem> 23.732 + <listitem><para>A hunk is missing some context at the 23.733 + beginning or end.</para> 23.734 + </listitem> 23.735 + <listitem><para>A large hunk might apply better&emdash;either 23.736 + entirely or in part&emdash;if it was broken up into 23.737 + smaller hunks.</para> 23.738 + </listitem> 23.739 + <listitem><para>A hunk removes lines with slightly different 23.740 + content than those currently present in the file.</para> 23.741 + </listitem></itemizedlist> 23.742 + 23.743 + <para>If you use <command>wiggle</command> or 23.744 + <command>mpatch</command>, you should be doubly careful to 23.745 + check your results when you're done. In fact, 23.746 + <command>mpatch</command> enforces this method of 23.747 + double-checking the tool's output, by automatically dropping 23.748 + you into a merge program when it has done its job, so that you 23.749 + can verify its work and finish off any remaining 23.750 + merges.</para> 23.751 + 23.752 + </sect2> 23.753 + </sect1> 23.754 + <sect1 id="sec:mq:perf"> 23.755 + <title>Getting the best performance out of MQ</title> 23.756 + 23.757 + <para>MQ is very efficient at handling a large number of patches. 23.758 + I ran some performance experiments in mid-2006 for a talk that I 23.759 + gave at the 2006 EuroPython conference 23.760 + <citation>web:europython</citation>. I used as my data set the 23.761 + Linux 2.6.17-mm1 patch series, which consists of 1,738 patches. 23.762 + I applied these on top of a Linux kernel repository containing 23.763 + all 27,472 revisions between Linux 2.6.12-rc2 and Linux 23.764 + 2.6.17.</para> 23.765 + 23.766 + <para>On my old, slow laptop, I was able to <command 23.767 + role="hg-cmd">hg qpush <option 23.768 + role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all 23.769 + 1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop 23.770 + <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> 23.771 + them all in 30 seconds. (On a newer laptop, the time to push 23.772 + all patches dropped to two minutes.) I could <command 23.773 + role="hg-ext-mq">qrefresh</command> one of the biggest patches 23.774 + (which made 22,779 lines of changes to 287 files) in 6.6 23.775 + seconds.</para> 23.776 + 23.777 + <para>Clearly, MQ is well suited to working in large trees, but 23.778 + there are a few tricks you can use to get the best performance 23.779 + of it.</para> 23.780 + 23.781 + <para>First of all, try to <quote>batch</quote> operations 23.782 + together. Every time you run <command 23.783 + role="hg-ext-mq">qpush</command> or <command 23.784 + role="hg-ext-mq">qpop</command>, these commands scan the 23.785 + working directory once to make sure you haven't made some 23.786 + changes and then forgotten to run <command 23.787 + role="hg-ext-mq">qrefresh</command>. On a small tree, the 23.788 + time that this scan takes is unnoticeable. However, on a 23.789 + medium-sized tree (containing tens of thousands of files), it 23.790 + can take a second or more.</para> 23.791 + 23.792 + <para>The <command role="hg-ext-mq">qpush</command> and <command 23.793 + role="hg-ext-mq">qpop</command> commands allow you to push and 23.794 + pop multiple patches at a time. You can identify the 23.795 + <quote>destination patch</quote> that you want to end up at. 23.796 + When you <command role="hg-ext-mq">qpush</command> with a 23.797 + destination specified, it will push patches until that patch is 23.798 + at the top of the applied stack. When you <command 23.799 + role="hg-ext-mq">qpop</command> to a destination, MQ will pop 23.800 + patches until the destination patch is at the top.</para> 23.801 + 23.802 + <para>You can identify a destination patch using either the name 23.803 + of the patch, or by number. If you use numeric addressing, 23.804 + patches are counted from zero; this means that the first patch 23.805 + is zero, the second is one, and so on.</para> 23.806 + 23.807 + </sect1> 23.808 + <sect1 id="sec:mq:merge"> 23.809 + <title>Updating your patches when the underlying code 23.810 + changes</title> 23.811 + 23.812 + <para>It's common to have a stack of patches on top of an 23.813 + underlying repository that you don't modify directly. If you're 23.814 + working on changes to third-party code, or on a feature that is 23.815 + taking longer to develop than the rate of change of the code 23.816 + beneath, you will often need to sync up with the underlying 23.817 + code, and fix up any hunks in your patches that no longer apply. 23.818 + This is called <emphasis>rebasing</emphasis> your patch 23.819 + series.</para> 23.820 + 23.821 + <para>The simplest way to do this is to <command role="hg-cmd">hg 23.822 + qpop <option role="hg-ext-mq-cmd-qpop-opt">hg 23.823 + -a</option></command> your patches, then <command 23.824 + role="hg-cmd">hg pull</command> changes into the underlying 23.825 + repository, and finally <command role="hg-cmd">hg qpush <option 23.826 + role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your 23.827 + patches again. MQ will stop pushing any time it runs across a 23.828 + patch that fails to apply during conflicts, allowing you to fix 23.829 + your conflicts, <command role="hg-ext-mq">qrefresh</command> the 23.830 + affected patch, and continue pushing until you have fixed your 23.831 + entire stack.</para> 23.832 + 23.833 + <para>This approach is easy to use and works well if you don't 23.834 + expect changes to the underlying code to affect how well your 23.835 + patches apply. If your patch stack touches code that is modified 23.836 + frequently or invasively in the underlying repository, however, 23.837 + fixing up rejected hunks by hand quickly becomes 23.838 + tiresome.</para> 23.839 + 23.840 + <para>It's possible to partially automate the rebasing process. 23.841 + If your patches apply cleanly against some revision of the 23.842 + underlying repo, MQ can use this information to help you to 23.843 + resolve conflicts between your patches and a different 23.844 + revision.</para> 23.845 + 23.846 + <para>The process is a little involved.</para> 23.847 + <orderedlist> 23.848 + <listitem><para>To begin, <command role="hg-cmd">hg qpush 23.849 + -a</command> all of your patches on top of the revision 23.850 + where you know that they apply cleanly.</para> 23.851 + </listitem> 23.852 + <listitem><para>Save a backup copy of your patch directory using 23.853 + <command role="hg-cmd">hg qsave <option 23.854 + role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option 23.855 + role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>. 23.856 + This prints the name of the directory that it has saved the 23.857 + patches in. It will save the patches to a directory called 23.858 + <filename role="special" 23.859 + class="directory">.hg/patches.N</filename>, where 23.860 + <literal>N</literal> is a small integer. It also commits a 23.861 + <quote>save changeset</quote> on top of your applied 23.862 + patches; this is for internal book-keeping, and records the 23.863 + states of the <filename role="special">series</filename> and 23.864 + <filename role="special">status</filename> files.</para> 23.865 + </listitem> 23.866 + <listitem><para>Use <command role="hg-cmd">hg pull</command> to 23.867 + bring new changes into the underlying repository. (Don't 23.868 + run <command role="hg-cmd">hg pull -u</command>; see below 23.869 + for why.)</para> 23.870 + </listitem> 23.871 + <listitem><para>Update to the new tip revision, using <command 23.872 + role="hg-cmd">hg update <option 23.873 + role="hg-opt-update">-C</option></command> to override 23.874 + the patches you have pushed.</para> 23.875 + </listitem> 23.876 + <listitem><para>Merge all patches using <command>hg qpush -m 23.877 + -a</command>. The <option 23.878 + role="hg-ext-mq-cmd-qpush-opt">-m</option> option to 23.879 + <command role="hg-ext-mq">qpush</command> tells MQ to 23.880 + perform a three-way merge if the patch fails to 23.881 + apply.</para> 23.882 + </listitem></orderedlist> 23.883 + 23.884 + <para>During the <command role="hg-cmd">hg qpush <option 23.885 + role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>, 23.886 + each patch in the <filename role="special">series</filename> 23.887 + file is applied normally. If a patch applies with fuzz or 23.888 + rejects, MQ looks at the queue you <command 23.889 + role="hg-ext-mq">qsave</command>d, and performs a three-way 23.890 + merge with the corresponding changeset. This merge uses 23.891 + Mercurial's normal merge machinery, so it may pop up a GUI merge 23.892 + tool to help you to resolve problems.</para> 23.893 + 23.894 + <para>When you finish resolving the effects of a patch, MQ 23.895 + refreshes your patch based on the result of the merge.</para> 23.896 + 23.897 + <para>At the end of this process, your repository will have one 23.898 + extra head from the old patch queue, and a copy of the old patch 23.899 + queue will be in <filename role="special" 23.900 + class="directory">.hg/patches.N</filename>. You can remove the 23.901 + extra head using <command role="hg-cmd">hg qpop -a -n 23.902 + patches.N</command> or <command role="hg-cmd">hg 23.903 + strip</command>. You can delete <filename role="special" 23.904 + class="directory">.hg/patches.N</filename> once you are sure 23.905 + that you no longer need it as a backup.</para> 23.906 + 23.907 + </sect1> 23.908 + <sect1> 23.909 + <title>Identifying patches</title> 23.910 + 23.911 + <para>MQ commands that work with patches let you refer to a patch 23.912 + either by using its name or by a number. By name is obvious 23.913 + enough; pass the name <filename>foo.patch</filename> to <command 23.914 + role="hg-ext-mq">qpush</command>, for example, and it will 23.915 + push patches until <filename>foo.patch</filename> is 23.916 + applied.</para> 23.917 + 23.918 + <para>As a shortcut, you can refer to a patch using both a name 23.919 + and a numeric offset; <literal>foo.patch-2</literal> means 23.920 + <quote>two patches before <literal>foo.patch</literal></quote>, 23.921 + while <literal>bar.patch+4</literal> means <quote>four patches 23.922 + after <literal>bar.patch</literal></quote>.</para> 23.923 + 23.924 + <para>Referring to a patch by index isn't much different. The 23.925 + first patch printed in the output of <command 23.926 + role="hg-ext-mq">qseries</command> is patch zero (yes, it's 23.927 + one of those start-at-zero counting systems); the second is 23.928 + patch one; and so on.</para> 23.929 + 23.930 + <para>MQ also makes it easy to work with patches when you are 23.931 + using normal Mercurial commands. Every command that accepts a 23.932 + changeset ID will also accept the name of an applied patch. MQ 23.933 + augments the tags normally in the repository with an eponymous 23.934 + one for each applied patch. In addition, the special tags 23.935 + <literal role="tag">qbase</literal> and 23.936 + <literal role="tag">qtip</literal> identify 23.937 + the <quote>bottom-most</quote> and topmost applied patches, 23.938 + respectively.</para> 23.939 + 23.940 + <para>These additions to Mercurial's normal tagging capabilities 23.941 + make dealing with patches even more of a breeze.</para> 23.942 + <itemizedlist> 23.943 + <listitem><para>Want to patchbomb a mailing list with your 23.944 + latest series of changes?</para> 23.945 + <programlisting>hg email qbase:qtip</programlisting> 23.946 + <para> (Don't know what <quote>patchbombing</quote> is? See 23.947 + section <xref linkend="sec:hgext:patchbomb"/>.)</para> 23.948 + </listitem> 23.949 + <listitem><para>Need to see all of the patches since 23.950 + <literal>foo.patch</literal> that have touched files in a 23.951 + subdirectory of your tree?</para> 23.952 + <programlisting>hg log -r foo.patch:qtip subdir</programlisting> 23.953 + </listitem> 23.954 + </itemizedlist> 23.955 + 23.956 + <para>Because MQ makes the names of patches available to the rest 23.957 + of Mercurial through its normal internal tag machinery, you 23.958 + don't need to type in the entire name of a patch when you want 23.959 + to identify it by name.</para> 23.960 + 23.961 + <para>Another nice consequence of representing patch names as tags 23.962 + is that when you run the <command role="hg-cmd">hg log</command> 23.963 + command, it will display a patch's name as a tag, simply as part 23.964 + of its normal output. This makes it easy to visually 23.965 + distinguish applied patches from underlying 23.966 + <quote>normal</quote> revisions. The following example shows a 23.967 + few normal Mercurial commands in use with applied 23.968 + patches.</para> 23.969 + 23.970 +&interaction.mq.id.output; 23.971 + 23.972 + </sect1> 23.973 + <sect1> 23.974 + <title>Useful things to know about</title> 23.975 + 23.976 + <para>There are a number of aspects of MQ usage that don't fit 23.977 + tidily into sections of their own, but that are good to know. 23.978 + Here they are, in one place.</para> 23.979 + 23.980 + <itemizedlist> 23.981 + <listitem><para>Normally, when you <command 23.982 + role="hg-ext-mq">qpop</command> a patch and <command 23.983 + role="hg-ext-mq">qpush</command> it again, the changeset 23.984 + that represents the patch after the pop/push will have a 23.985 + <emphasis>different identity</emphasis> than the changeset 23.986 + that represented the hash beforehand. See section <xref 23.987 + linkend="sec:mqref:cmd:qpush"/> for 23.988 + information as to why this is.</para> 23.989 + </listitem> 23.990 + <listitem><para>It's not a good idea to <command 23.991 + role="hg-cmd">hg merge</command> changes from another 23.992 + branch with a patch changeset, at least if you want to 23.993 + maintain the <quote>patchiness</quote> of that changeset and 23.994 + changesets below it on the patch stack. If you try to do 23.995 + this, it will appear to succeed, but MQ will become 23.996 + confused.</para> 23.997 + </listitem></itemizedlist> 23.998 + 23.999 + </sect1> 23.1000 + <sect1 id="sec:mq:repo"> 23.1001 + <title>Managing patches in a repository</title> 23.1002 + 23.1003 + <para>Because MQ's <filename role="special" 23.1004 + class="directory">.hg/patches</filename> directory resides 23.1005 + outside a Mercurial repository's working directory, the 23.1006 + <quote>underlying</quote> Mercurial repository knows nothing 23.1007 + about the management or presence of patches.</para> 23.1008 + 23.1009 + <para>This presents the interesting possibility of managing the 23.1010 + contents of the patch directory as a Mercurial repository in its 23.1011 + own right. This can be a useful way to work. For example, you 23.1012 + can work on a patch for a while, <command 23.1013 + role="hg-ext-mq">qrefresh</command> it, then <command 23.1014 + role="hg-cmd">hg commit</command> the current state of the 23.1015 + patch. This lets you <quote>roll back</quote> to that version 23.1016 + of the patch later on.</para> 23.1017 + 23.1018 + <para>You can then share different versions of the same patch 23.1019 + stack among multiple underlying repositories. I use this when I 23.1020 + am developing a Linux kernel feature. I have a pristine copy of 23.1021 + my kernel sources for each of several CPU architectures, and a 23.1022 + cloned repository under each that contains the patches I am 23.1023 + working on. When I want to test a change on a different 23.1024 + architecture, I push my current patches to the patch repository 23.1025 + associated with that kernel tree, pop and push all of my 23.1026 + patches, and build and test that kernel.</para> 23.1027 + 23.1028 + <para>Managing patches in a repository makes it possible for 23.1029 + multiple developers to work on the same patch series without 23.1030 + colliding with each other, all on top of an underlying source 23.1031 + base that they may or may not control.</para> 23.1032 + 23.1033 + <sect2> 23.1034 + <title>MQ support for patch repositories</title> 23.1035 + 23.1036 + <para>MQ helps you to work with the <filename role="special" 23.1037 + class="directory">.hg/patches</filename> directory as a 23.1038 + repository; when you prepare a repository for working with 23.1039 + patches using <command role="hg-ext-mq">qinit</command>, you 23.1040 + can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg 23.1041 + -c</option> option to create the <filename role="special" 23.1042 + class="directory">.hg/patches</filename> directory as a 23.1043 + Mercurial repository.</para> 23.1044 + 23.1045 + <note> 23.1046 + <para> If you forget to use the <option 23.1047 + role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you 23.1048 + can simply go into the <filename role="special" 23.1049 + class="directory">.hg/patches</filename> directory at any 23.1050 + time and run <command role="hg-cmd">hg init</command>. 23.1051 + Don't forget to add an entry for the <filename 23.1052 + role="special">status</filename> file to the <filename 23.1053 + role="special">.hgignore</filename> file, though</para> 23.1054 + 23.1055 + <para> (<command role="hg-cmd">hg qinit <option 23.1056 + role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command> 23.1057 + does this for you automatically); you 23.1058 + <emphasis>really</emphasis> don't want to manage the 23.1059 + <filename role="special">status</filename> file.</para> 23.1060 + </note> 23.1061 + 23.1062 + <para>As a convenience, if MQ notices that the <filename 23.1063 + class="directory">.hg/patches</filename> directory is a 23.1064 + repository, it will automatically <command role="hg-cmd">hg 23.1065 + add</command> every patch that you create and import.</para> 23.1066 + 23.1067 + <para>MQ provides a shortcut command, <command 23.1068 + role="hg-ext-mq">qcommit</command>, that runs <command 23.1069 + role="hg-cmd">hg commit</command> in the <filename 23.1070 + role="special" class="directory">.hg/patches</filename> 23.1071 + directory. This saves some bothersome typing.</para> 23.1072 + 23.1073 + <para>Finally, as a convenience to manage the patch directory, 23.1074 + you can define the alias <command>mq</command> on Unix 23.1075 + systems. For example, on Linux systems using the 23.1076 + <command>bash</command> shell, you can include the following 23.1077 + snippet in your <filename 23.1078 + role="home">~/.bashrc</filename>.</para> 23.1079 + 23.1080 + <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting> 23.1081 + 23.1082 + <para>You can then issue commands of the form <command>mq 23.1083 + pull</command> from the main repository.</para> 23.1084 + 23.1085 + </sect2> 23.1086 + <sect2> 23.1087 + <title>A few things to watch out for</title> 23.1088 + 23.1089 + <para>MQ's support for working with a repository full of patches 23.1090 + is limited in a few small respects.</para> 23.1091 + 23.1092 + <para>MQ cannot automatically detect changes that you make to 23.1093 + the patch directory. If you <command role="hg-cmd">hg 23.1094 + pull</command>, manually edit, or <command role="hg-cmd">hg 23.1095 + update</command> changes to patches or the <filename 23.1096 + role="special">series</filename> file, you will have to 23.1097 + <command role="hg-cmd">hg qpop <option 23.1098 + role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and 23.1099 + then <command role="hg-cmd">hg qpush <option 23.1100 + role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in 23.1101 + the underlying repository to see those changes show up there. 23.1102 + If you forget to do this, you can confuse MQ's idea of which 23.1103 + patches are applied.</para> 23.1104 + 23.1105 + </sect2> 23.1106 + </sect1> 23.1107 + <sect1 id="sec:mq:tools"> 23.1108 + <title>Third party tools for working with patches</title> 23.1109 + 23.1110 + <para>Once you've been working with patches for a while, you'll 23.1111 + find yourself hungry for tools that will help you to understand 23.1112 + and manipulate the patches you're dealing with.</para> 23.1113 + 23.1114 + <para>The <command>diffstat</command> command 23.1115 + <citation>web:diffstat</citation> generates a histogram of the 23.1116 + modifications made to each file in a patch. It provides a good 23.1117 + way to <quote>get a sense of</quote> a patch&emdash;which files 23.1118 + it affects, and how much change it introduces to each file and 23.1119 + as a whole. (I find that it's a good idea to use 23.1120 + <command>diffstat</command>'s <option 23.1121 + role="cmd-opt-diffstat">-p</option> option as a matter of 23.1122 + course, as otherwise it will try to do clever things with 23.1123 + prefixes of file names that inevitably confuse at least 23.1124 + me.)</para> 23.1125 + 23.1126 +&interaction.mq.tools.tools; 23.1127 + 23.1128 + <para>The <literal role="package">patchutils</literal> package 23.1129 + <citation>web:patchutils</citation> is invaluable. It provides a 23.1130 + set of small utilities that follow the <quote>Unix 23.1131 + philosophy;</quote> each does one useful thing with a patch. 23.1132 + The <literal role="package">patchutils</literal> command I use 23.1133 + most is <command>filterdiff</command>, which extracts subsets 23.1134 + from a patch file. For example, given a patch that modifies 23.1135 + hundreds of files across dozens of directories, a single 23.1136 + invocation of <command>filterdiff</command> can generate a 23.1137 + smaller patch that only touches files whose names match a 23.1138 + particular glob pattern. See section <xref 23.1139 + linkend="mq-collab:tips:interdiff"/> for another 23.1140 + example.</para> 23.1141 + 23.1142 + </sect1> 23.1143 + <sect1> 23.1144 + <title>Good ways to work with patches</title> 23.1145 + 23.1146 + <para>Whether you are working on a patch series to submit to a 23.1147 + free software or open source project, or a series that you 23.1148 + intend to treat as a sequence of regular changesets when you're 23.1149 + done, you can use some simple techniques to keep your work well 23.1150 + organised.</para> 23.1151 + 23.1152 + <para>Give your patches descriptive names. A good name for a 23.1153 + patch might be <filename>rework-device-alloc.patch</filename>, 23.1154 + because it will immediately give you a hint what the purpose of 23.1155 + the patch is. Long names shouldn't be a problem; you won't be 23.1156 + typing the names often, but you <emphasis>will</emphasis> be 23.1157 + running commands like <command 23.1158 + role="hg-ext-mq">qapplied</command> and <command 23.1159 + role="hg-ext-mq">qtop</command> over and over. Good naming 23.1160 + becomes especially important when you have a number of patches 23.1161 + to work with, or if you are juggling a number of different tasks 23.1162 + and your patches only get a fraction of your attention.</para> 23.1163 + 23.1164 + <para>Be aware of what patch you're working on. Use the <command 23.1165 + role="hg-ext-mq">qtop</command> command and skim over the text 23.1166 + of your patches frequently&emdash;for example, using <command 23.1167 + role="hg-cmd">hg tip <option 23.1168 + role="hg-opt-tip">-p</option></command>)&emdash;to be sure 23.1169 + of where you stand. I have several times worked on and <command 23.1170 + role="hg-ext-mq">qrefresh</command>ed a patch other than the 23.1171 + one I intended, and it's often tricky to migrate changes into 23.1172 + the right patch after making them in the wrong one.</para> 23.1173 + 23.1174 + <para>For this reason, it is very much worth investing a little 23.1175 + time to learn how to use some of the third-party tools I 23.1176 + described in section <xref linkend="sec:mq:tools"/>, 23.1177 + particularly 23.1178 + <command>diffstat</command> and <command>filterdiff</command>. 23.1179 + The former will give you a quick idea of what changes your patch 23.1180 + is making, while the latter makes it easy to splice hunks 23.1181 + selectively out of one patch and into another.</para> 23.1182 + 23.1183 + </sect1> 23.1184 + <sect1> 23.1185 + <title>MQ cookbook</title> 23.1186 + 23.1187 + <sect2> 23.1188 + <title>Manage <quote>trivial</quote> patches</title> 23.1189 + 23.1190 + <para>Because the overhead of dropping files into a new 23.1191 + Mercurial repository is so low, it makes a lot of sense to 23.1192 + manage patches this way even if you simply want to make a few 23.1193 + changes to a source tarball that you downloaded.</para> 23.1194 + 23.1195 + <para>Begin by downloading and unpacking the source tarball, and 23.1196 + turning it into a Mercurial repository.</para> 23.1197 + 23.1198 + &interaction.mq.tarball.download; 23.1199 + 23.1200 + <para>Continue by creating a patch stack and making your 23.1201 + changes.</para> 23.1202 + 23.1203 + &interaction.mq.tarball.qinit; 23.1204 + 23.1205 + <para>Let's say a few weeks or months pass, and your package 23.1206 + author releases a new version. First, bring their changes 23.1207 + into the repository.</para> 23.1208 + 23.1209 + &interaction.mq.tarball.newsource; 23.1210 + 23.1211 + <para>The pipeline starting with <command role="hg-cmd">hg 23.1212 + locate</command> above deletes all files in the working 23.1213 + directory, so that <command role="hg-cmd">hg 23.1214 + commit</command>'s <option 23.1215 + role="hg-opt-commit">--addremove</option> option can 23.1216 + actually tell which files have really been removed in the 23.1217 + newer version of the source.</para> 23.1218 + 23.1219 + <para>Finally, you can apply your patches on top of the new 23.1220 + tree.</para> 23.1221 + 23.1222 + &interaction.mq.tarball.repush; 23.1223 + 23.1224 + </sect2> 23.1225 + <sect2 id="sec:mq:combine"> 23.1226 + <title>Combining entire patches</title> 23.1227 + 23.1228 + <para>MQ provides a command, <command 23.1229 + role="hg-ext-mq">qfold</command> that lets you combine 23.1230 + entire patches. This <quote>folds</quote> the patches you 23.1231 + name, in the order you name them, into the topmost applied 23.1232 + patch, and concatenates their descriptions onto the end of its 23.1233 + description. The patches that you fold must be unapplied 23.1234 + before you fold them.</para> 23.1235 + 23.1236 + <para>The order in which you fold patches matters. If your 23.1237 + topmost applied patch is <literal>foo</literal>, and you 23.1238 + <command role="hg-ext-mq">qfold</command> 23.1239 + <literal>bar</literal> and <literal>quux</literal> into it, 23.1240 + you will end up with a patch that has the same effect as if 23.1241 + you applied first <literal>foo</literal>, then 23.1242 + <literal>bar</literal>, followed by 23.1243 + <literal>quux</literal>.</para> 23.1244 + 23.1245 + </sect2> 23.1246 + <sect2> 23.1247 + <title>Merging part of one patch into another</title> 23.1248 + 23.1249 + <para>Merging <emphasis>part</emphasis> of one patch into 23.1250 + another is more difficult than combining entire 23.1251 + patches.</para> 23.1252 + 23.1253 + <para>If you want to move changes to entire files, you can use 23.1254 + <command>filterdiff</command>'s <option 23.1255 + role="cmd-opt-filterdiff">-i</option> and <option 23.1256 + role="cmd-opt-filterdiff">-x</option> options to choose the 23.1257 + modifications to snip out of one patch, concatenating its 23.1258 + output onto the end of the patch you want to merge into. You 23.1259 + usually won't need to modify the patch you've merged the 23.1260 + changes from. Instead, MQ will report some rejected hunks 23.1261 + when you <command role="hg-ext-mq">qpush</command> it (from 23.1262 + the hunks you moved into the other patch), and you can simply 23.1263 + <command role="hg-ext-mq">qrefresh</command> the patch to drop 23.1264 + the duplicate hunks.</para> 23.1265 + 23.1266 + <para>If you have a patch that has multiple hunks modifying a 23.1267 + file, and you only want to move a few of those hunks, the job 23.1268 + becomes more messy, but you can still partly automate it. Use 23.1269 + <command>lsdiff -nvv</command> to print some metadata about 23.1270 + the patch.</para> 23.1271 + 23.1272 + &interaction.mq.tools.lsdiff; 23.1273 + 23.1274 + <para>This command prints three different kinds of 23.1275 + number:</para> 23.1276 + <itemizedlist> 23.1277 + <listitem><para>(in the first column) a <emphasis>file 23.1278 + number</emphasis> to identify each file modified in the 23.1279 + patch;</para> 23.1280 + </listitem> 23.1281 + <listitem><para>(on the next line, indented) the line number 23.1282 + within a modified file where a hunk starts; and</para> 23.1283 + </listitem> 23.1284 + <listitem><para>(on the same line) a <emphasis>hunk 23.1285 + number</emphasis> to identify that hunk.</para> 23.1286 + </listitem></itemizedlist> 23.1287 + 23.1288 + <para>You'll have to use some visual inspection, and reading of 23.1289 + the patch, to identify the file and hunk numbers you'll want, 23.1290 + but you can then pass them to to 23.1291 + <command>filterdiff</command>'s <option 23.1292 + role="cmd-opt-filterdiff">--files</option> and <option 23.1293 + role="cmd-opt-filterdiff">--hunks</option> options, to 23.1294 + select exactly the file and hunk you want to extract.</para> 23.1295 + 23.1296 + <para>Once you have this hunk, you can concatenate it onto the 23.1297 + end of your destination patch and continue with the remainder 23.1298 + of section <xref linkend="sec:mq:combine"/>.</para> 23.1299 + 23.1300 + </sect2> 23.1301 + </sect1> 23.1302 + <sect1> 23.1303 + <title>Differences between quilt and MQ</title> 23.1304 + 23.1305 + <para>If you are already familiar with quilt, MQ provides a 23.1306 + similar command set. There are a few differences in the way 23.1307 + that it works.</para> 23.1308 + 23.1309 + <para>You will already have noticed that most quilt commands have 23.1310 + MQ counterparts that simply begin with a 23.1311 + <quote><literal>q</literal></quote>. The exceptions are quilt's 23.1312 + <literal>add</literal> and <literal>remove</literal> commands, 23.1313 + the counterparts for which are the normal Mercurial <command 23.1314 + role="hg-cmd">hg add</command> and <command role="hg-cmd">hg 23.1315 + remove</command> commands. There is no MQ equivalent of the 23.1316 + quilt <literal>edit</literal> command.</para> 23.1317 + 23.1318 + </sect1> 23.1319 +</chapter> 23.1320 + 23.1321 +<!-- 23.1322 +local variables: 23.1323 +sgml-parent-document: ("00book.xml" "book" "chapter") 23.1324 +end: 23.1325 +-->
24.1 --- a/en/ch11-template.xml Wed Mar 18 00:08:22 2009 -0700 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,675 +0,0 @@ 24.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 24.5 - 24.6 -<chapter id="chap:template"> 24.7 - <?dbhtml filename="customizing-the-output-of-mercurial.html"?> 24.8 - <title>Customising the output of Mercurial</title> 24.9 - 24.10 - <para>Mercurial provides a powerful mechanism to let you control how 24.11 - it displays information. The mechanism is based on templates. 24.12 - You can use templates to generate specific output for a single 24.13 - command, or to customise the entire appearance of the built-in web 24.14 - interface.</para> 24.15 - 24.16 - <sect1 id="sec:style"> 24.17 - <title>Using precanned output styles</title> 24.18 - 24.19 - <para>Packaged with Mercurial are some output styles that you can 24.20 - use immediately. A style is simply a precanned template that 24.21 - someone wrote and installed somewhere that Mercurial can 24.22 - find.</para> 24.23 - 24.24 - <para>Before we take a look at Mercurial's bundled styles, let's 24.25 - review its normal output.</para> 24.26 - 24.27 - &interaction.template.simple.normal; 24.28 - 24.29 - <para>This is somewhat informative, but it takes up a lot of 24.30 - space&emdash;five lines of output per changeset. The 24.31 - <literal>compact</literal> style reduces this to three lines, 24.32 - presented in a sparse manner.</para> 24.33 - 24.34 - &interaction.template.simple.compact; 24.35 - 24.36 - <para>The <literal>changelog</literal> style hints at the 24.37 - expressive power of Mercurial's templating engine. This style 24.38 - attempts to follow the GNU Project's changelog 24.39 - guidelines<citation>web:changelog</citation>.</para> 24.40 - 24.41 - &interaction.template.simple.changelog; 24.42 - 24.43 - <para>You will not be shocked to learn that Mercurial's default 24.44 - output style is named <literal>default</literal>.</para> 24.45 - 24.46 - <sect2> 24.47 - <title>Setting a default style</title> 24.48 - 24.49 - <para>You can modify the output style that Mercurial will use 24.50 - for every command by editing your <filename 24.51 - role="special">~/.hgrc</filename> file, naming the style 24.52 - you would prefer to use.</para> 24.53 - 24.54 - <programlisting>[ui] 24.55 -style = compact</programlisting> 24.56 - 24.57 - <para>If you write a style of your own, you can use it by either 24.58 - providing the path to your style file, or copying your style 24.59 - file into a location where Mercurial can find it (typically 24.60 - the <literal>templates</literal> subdirectory of your 24.61 - Mercurial install directory).</para> 24.62 - 24.63 - </sect2> 24.64 - </sect1> 24.65 - <sect1> 24.66 - <title>Commands that support styles and templates</title> 24.67 - 24.68 - <para>All of Mercurial's 24.69 - <quote><literal>log</literal>-like</quote> commands let you use 24.70 - styles and templates: <command role="hg-cmd">hg 24.71 - incoming</command>, <command role="hg-cmd">hg log</command>, 24.72 - <command role="hg-cmd">hg outgoing</command>, and <command 24.73 - role="hg-cmd">hg tip</command>.</para> 24.74 - 24.75 - <para>As I write this manual, these are so far the only commands 24.76 - that support styles and templates. Since these are the most 24.77 - important commands that need customisable output, there has been 24.78 - little pressure from the Mercurial user community to add style 24.79 - and template support to other commands.</para> 24.80 - 24.81 - </sect1> 24.82 - <sect1> 24.83 - <title>The basics of templating</title> 24.84 - 24.85 - <para>At its simplest, a Mercurial template is a piece of text. 24.86 - Some of the text never changes, while other parts are 24.87 - <emphasis>expanded</emphasis>, or replaced with new text, when 24.88 - necessary.</para> 24.89 - 24.90 - <para>Before we continue, let's look again at a simple example of 24.91 - Mercurial's normal output.</para> 24.92 - 24.93 - &interaction.template.simple.normal; 24.94 - 24.95 - <para>Now, let's run the same command, but using a template to 24.96 - change its output.</para> 24.97 - 24.98 - &interaction.template.simple.simplest; 24.99 - 24.100 - <para>The example above illustrates the simplest possible 24.101 - template; it's just a piece of static text, printed once for 24.102 - each changeset. The <option 24.103 - role="hg-opt-log">--template</option> option to the <command 24.104 - role="hg-cmd">hg log</command> command tells Mercurial to use 24.105 - the given text as the template when printing each 24.106 - changeset.</para> 24.107 - 24.108 - <para>Notice that the template string above ends with the text 24.109 - <quote><literal>\n</literal></quote>. This is an 24.110 - <emphasis>escape sequence</emphasis>, telling Mercurial to print 24.111 - a newline at the end of each template item. If you omit this 24.112 - newline, Mercurial will run each piece of output together. See 24.113 - section <xref linkend="sec:template:escape"/> for more details 24.114 - of escape sequences.</para> 24.115 - 24.116 - <para>A template that prints a fixed string of text all the time 24.117 - isn't very useful; let's try something a bit more 24.118 - complex.</para> 24.119 - 24.120 - &interaction.template.simple.simplesub; 24.121 - 24.122 - <para>As you can see, the string 24.123 - <quote><literal>{desc}</literal></quote> in the template has 24.124 - been replaced in the output with the description of each 24.125 - changeset. Every time Mercurial finds text enclosed in curly 24.126 - braces (<quote><literal>{</literal></quote> and 24.127 - <quote><literal>}</literal></quote>), it will try to replace the braces 24.128 - and text with the expansion of whatever is inside. To print a 24.129 - literal curly brace, you must escape it, as described in section 24.130 - <xref 24.131 - linkend="sec:template:escape"/>.</para> 24.132 - 24.133 - </sect1> 24.134 - <sect1 id="sec:template:keyword"> 24.135 - <title>Common template keywords</title> 24.136 - 24.137 - <para>You can start writing simple templates immediately using the 24.138 - keywords below.</para> 24.139 - 24.140 - <itemizedlist> 24.141 - <listitem><para><literal 24.142 - role="template-keyword">author</literal>: String. The 24.143 - unmodified author of the changeset.</para> 24.144 - </listitem> 24.145 - <listitem><para><literal 24.146 - role="template-keyword">branches</literal>: String. The 24.147 - name of the branch on which the changeset was committed. 24.148 - Will be empty if the branch name was 24.149 - <literal>default</literal>.</para> 24.150 - </listitem> 24.151 - <listitem><para><literal role="template-keyword">date</literal>: 24.152 - Date information. The date when the changeset was 24.153 - committed. This is <emphasis>not</emphasis> human-readable; 24.154 - you must pass it through a filter that will render it 24.155 - appropriately. See section <xref 24.156 - linkend="sec:template:filter"/> for more information 24.157 - on filters. The date is expressed as a pair of numbers. The 24.158 - first number is a Unix UTC timestamp (seconds since January 24.159 - 1, 1970); the second is the offset of the committer's 24.160 - timezone from UTC, in seconds.</para> 24.161 - </listitem> 24.162 - <listitem><para><literal role="template-keyword">desc</literal>: 24.163 - String. The text of the changeset description.</para> 24.164 - </listitem> 24.165 - <listitem><para><literal 24.166 - role="template-keyword">files</literal>: List of strings. 24.167 - All files modified, added, or removed by this 24.168 - changeset.</para> 24.169 - </listitem> 24.170 - <listitem><para><literal 24.171 - role="template-keyword">file_adds</literal>: List of 24.172 - strings. Files added by this changeset.</para> 24.173 - </listitem> 24.174 - <listitem><para><literal 24.175 - role="template-keyword">file_dels</literal>: List of 24.176 - strings. Files removed by this changeset.</para> 24.177 - </listitem> 24.178 - <listitem><para><literal role="template-keyword">node</literal>: 24.179 - String. The changeset identification hash, as a 24.180 - 40-character hexadecimal string.</para> 24.181 - </listitem> 24.182 - <listitem><para><literal 24.183 - role="template-keyword">parents</literal>: List of 24.184 - strings. The parents of the changeset.</para> 24.185 - </listitem> 24.186 - <listitem><para><literal role="template-keyword">rev</literal>: 24.187 - Integer. The repository-local changeset revision 24.188 - number.</para> 24.189 - </listitem> 24.190 - <listitem><para><literal role="template-keyword">tags</literal>: 24.191 - List of strings. Any tags associated with the 24.192 - changeset.</para> 24.193 - </listitem></itemizedlist> 24.194 - 24.195 - <para>A few simple experiments will show us what to expect when we 24.196 - use these keywords; you can see the results below.</para> 24.197 - 24.198 -&interaction.template.simple.keywords; 24.199 - 24.200 - <para>As we noted above, the date keyword does not produce 24.201 - human-readable output, so we must treat it specially. This 24.202 - involves using a <emphasis>filter</emphasis>, about which more 24.203 - in section <xref 24.204 - linkend="sec:template:filter"/>.</para> 24.205 - 24.206 - &interaction.template.simple.datekeyword; 24.207 - 24.208 - </sect1> 24.209 - <sect1 id="sec:template:escape"> 24.210 - <title>Escape sequences</title> 24.211 - 24.212 - <para>Mercurial's templating engine recognises the most commonly 24.213 - used escape sequences in strings. When it sees a backslash 24.214 - (<quote><literal>\</literal></quote>) character, it looks at the 24.215 - following character and substitutes the two characters with a 24.216 - single replacement, as described below.</para> 24.217 - 24.218 - <itemizedlist> 24.219 - <listitem><para><literal>\</literal>: 24.220 - Backslash, <quote><literal>\</literal></quote>, ASCII 24.221 - 134.</para> 24.222 - </listitem> 24.223 - <listitem><para><literal>\n</literal>: Newline, 24.224 - ASCII 12.</para> 24.225 - </listitem> 24.226 - <listitem><para><literal>\r</literal>: Carriage 24.227 - return, ASCII 15.</para> 24.228 - </listitem> 24.229 - <listitem><para><literal>\t</literal>: Tab, ASCII 24.230 - 11.</para> 24.231 - </listitem> 24.232 - <listitem><para><literal>\v</literal>: Vertical 24.233 - tab, ASCII 13.</para> 24.234 - </listitem> 24.235 - <listitem><para><literal>{</literal>: Open curly 24.236 - brace, <quote><literal>{</literal></quote>, ASCII 24.237 - 173.</para> 24.238 - </listitem> 24.239 - <listitem><para><literal>}</literal>: Close curly 24.240 - brace, <quote><literal>}</literal></quote>, ASCII 24.241 - 175.</para> 24.242 - </listitem></itemizedlist> 24.243 - 24.244 - <para>As indicated above, if you want the expansion of a template 24.245 - to contain a literal <quote><literal>\</literal></quote>, 24.246 - <quote><literal>{</literal></quote>, or 24.247 - <quote><literal>{</literal></quote> character, you must escape 24.248 - it.</para> 24.249 - 24.250 - </sect1> 24.251 - <sect1 id="sec:template:filter"> 24.252 - <title>Filtering keywords to change their results</title> 24.253 - 24.254 - <para>Some of the results of template expansion are not 24.255 - immediately easy to use. Mercurial lets you specify an optional 24.256 - chain of <emphasis>filters</emphasis> to modify the result of 24.257 - expanding a keyword. You have already seen a common filter, 24.258 - <literal role="template-kw-filt-date">isodate</literal>, in 24.259 - action above, to make a date readable.</para> 24.260 - 24.261 - <para>Below is a list of the most commonly used filters that 24.262 - Mercurial supports. While some filters can be applied to any 24.263 - text, others can only be used in specific circumstances. The 24.264 - name of each filter is followed first by an indication of where 24.265 - it can be used, then a description of its effect.</para> 24.266 - 24.267 - <itemizedlist> 24.268 - <listitem><para><literal 24.269 - role="template-filter">addbreaks</literal>: Any text. Add 24.270 - an XHTML <quote><literal><br/></literal></quote> tag 24.271 - before the end of every line except the last. For example, 24.272 - <quote><literal>foo\nbar</literal></quote> becomes 24.273 - <quote><literal>foo<br/>\nbar</literal></quote>.</para> 24.274 - </listitem> 24.275 - <listitem><para><literal 24.276 - role="template-kw-filt-date">age</literal>: <literal 24.277 - role="template-keyword">date</literal> keyword. Render 24.278 - the age of the date, relative to the current time. Yields a 24.279 - string like <quote><literal>10 24.280 - minutes</literal></quote>.</para> 24.281 - </listitem> 24.282 - <listitem><para><literal 24.283 - role="template-filter">basename</literal>: Any text, but 24.284 - most useful for the <literal 24.285 - role="template-keyword">files</literal> keyword and its 24.286 - relatives. Treat the text as a path, and return the 24.287 - basename. For example, 24.288 - <quote><literal>foo/bar/baz</literal></quote> becomes 24.289 - <quote><literal>baz</literal></quote>.</para> 24.290 - </listitem> 24.291 - <listitem><para><literal 24.292 - role="template-kw-filt-date">date</literal>: <literal 24.293 - role="template-keyword">date</literal> keyword. Render a 24.294 - date in a similar format to the Unix <literal 24.295 - role="template-keyword">date</literal> command, but with 24.296 - timezone included. Yields a string like <quote><literal>Mon 24.297 - Sep 04 15:13:13 2006 -0700</literal></quote>.</para> 24.298 - </listitem> 24.299 - <listitem><para><literal 24.300 - role="template-kw-filt-author">domain</literal>: Any text, 24.301 - but most useful for the <literal 24.302 - role="template-keyword">author</literal> keyword. Finds 24.303 - the first string that looks like an email address, and 24.304 - extract just the domain component. For example, 24.305 - <quote><literal>Bryan O'Sullivan 24.306 - <bos@serpentine.com></literal></quote> becomes 24.307 - <quote><literal>serpentine.com</literal></quote>.</para> 24.308 - </listitem> 24.309 - <listitem><para><literal 24.310 - role="template-kw-filt-author">email</literal>: Any text, 24.311 - but most useful for the <literal 24.312 - role="template-keyword">author</literal> keyword. Extract 24.313 - the first string that looks like an email address. For 24.314 - example, <quote><literal>Bryan O'Sullivan 24.315 - <bos@serpentine.com></literal></quote> becomes 24.316 - <quote><literal>bos@serpentine.com</literal></quote>.</para> 24.317 - </listitem> 24.318 - <listitem><para><literal 24.319 - role="template-filter">escape</literal>: Any text. 24.320 - Replace the special XML/XHTML characters 24.321 - <quote><literal>&</literal></quote>, 24.322 - <quote><literal><</literal></quote> and 24.323 - <quote><literal>></literal></quote> with XML 24.324 - entities.</para> 24.325 - </listitem> 24.326 - <listitem><para><literal 24.327 - role="template-filter">fill68</literal>: Any text. Wrap 24.328 - the text to fit in 68 columns. This is useful before you 24.329 - pass text through the <literal 24.330 - role="template-filter">tabindent</literal> filter, and 24.331 - still want it to fit in an 80-column fixed-font 24.332 - window.</para> 24.333 - </listitem> 24.334 - <listitem><para><literal 24.335 - role="template-filter">fill76</literal>: Any text. Wrap 24.336 - the text to fit in 76 columns.</para> 24.337 - </listitem> 24.338 - <listitem><para><literal 24.339 - role="template-filter">firstline</literal>: Any text. 24.340 - Yield the first line of text, without any trailing 24.341 - newlines.</para> 24.342 - </listitem> 24.343 - <listitem><para><literal 24.344 - role="template-kw-filt-date">hgdate</literal>: <literal 24.345 - role="template-keyword">date</literal> keyword. Render 24.346 - the date as a pair of readable numbers. Yields a string 24.347 - like <quote><literal>1157407993 24.348 - 25200</literal></quote>.</para> 24.349 - </listitem> 24.350 - <listitem><para><literal 24.351 - role="template-kw-filt-date">isodate</literal>: <literal 24.352 - role="template-keyword">date</literal> keyword. Render 24.353 - the date as a text string in ISO 8601 format. Yields a 24.354 - string like <quote><literal>2006-09-04 15:13:13 24.355 - -0700</literal></quote>.</para> 24.356 - </listitem> 24.357 - <listitem><para><literal 24.358 - role="template-filter">obfuscate</literal>: Any text, but 24.359 - most useful for the <literal 24.360 - role="template-keyword">author</literal> keyword. Yield 24.361 - the input text rendered as a sequence of XML entities. This 24.362 - helps to defeat some particularly stupid screen-scraping 24.363 - email harvesting spambots.</para> 24.364 - </listitem> 24.365 - <listitem><para><literal 24.366 - role="template-kw-filt-author">person</literal>: Any text, 24.367 - but most useful for the <literal 24.368 - role="template-keyword">author</literal> keyword. Yield 24.369 - the text before an email address. For example, 24.370 - <quote><literal>Bryan O'Sullivan 24.371 - <bos@serpentine.com></literal></quote> becomes 24.372 - <quote><literal>Bryan O'Sullivan</literal></quote>.</para> 24.373 - </listitem> 24.374 - <listitem><para><literal 24.375 - role="template-kw-filt-date">rfc822date</literal>: 24.376 - <literal role="template-keyword">date</literal> keyword. 24.377 - Render a date using the same format used in email headers. 24.378 - Yields a string like <quote><literal>Mon, 04 Sep 2006 24.379 - 15:13:13 -0700</literal></quote>.</para> 24.380 - </listitem> 24.381 - <listitem><para><literal 24.382 - role="template-kw-filt-node">short</literal>: Changeset 24.383 - hash. Yield the short form of a changeset hash, i.e. a 24.384 - 12-character hexadecimal string.</para> 24.385 - </listitem> 24.386 - <listitem><para><literal 24.387 - role="template-kw-filt-date">shortdate</literal>: <literal 24.388 - role="template-keyword">date</literal> keyword. Render 24.389 - the year, month, and day of the date. Yields a string like 24.390 - <quote><literal>2006-09-04</literal></quote>.</para> 24.391 - </listitem> 24.392 - <listitem><para><literal role="template-filter">strip</literal>: 24.393 - Any text. Strip all leading and trailing whitespace from 24.394 - the string.</para> 24.395 - </listitem> 24.396 - <listitem><para><literal 24.397 - role="template-filter">tabindent</literal>: Any text. 24.398 - Yield the text, with every line except the first starting 24.399 - with a tab character.</para> 24.400 - </listitem> 24.401 - <listitem><para><literal 24.402 - role="template-filter">urlescape</literal>: Any text. 24.403 - Escape all characters that are considered 24.404 - <quote>special</quote> by URL parsers. For example, 24.405 - <literal>foo bar</literal> becomes 24.406 - <literal>foo%20bar</literal>.</para> 24.407 - </listitem> 24.408 - <listitem><para><literal 24.409 - role="template-kw-filt-author">user</literal>: Any text, 24.410 - but most useful for the <literal 24.411 - role="template-keyword">author</literal> keyword. Return 24.412 - the <quote>user</quote> portion of an email address. For 24.413 - example, <quote><literal>Bryan O'Sullivan 24.414 - <bos@serpentine.com></literal></quote> becomes 24.415 - <quote><literal>bos</literal></quote>.</para> 24.416 - </listitem></itemizedlist> 24.417 - 24.418 -&interaction.template.simple.manyfilters; 24.419 - 24.420 - <note> 24.421 - <para> If you try to apply a filter to a piece of data that it 24.422 - cannot process, Mercurial will fail and print a Python 24.423 - exception. For example, trying to run the output of the 24.424 - <literal role="template-keyword">desc</literal> keyword into 24.425 - the <literal role="template-kw-filt-date">isodate</literal> 24.426 - filter is not a good idea.</para> 24.427 - </note> 24.428 - 24.429 - <sect2> 24.430 - <title>Combining filters</title> 24.431 - 24.432 - <para>It is easy to combine filters to yield output in the form 24.433 - you would like. The following chain of filters tidies up a 24.434 - description, then makes sure that it fits cleanly into 68 24.435 - columns, then indents it by a further 8 characters (at least 24.436 - on Unix-like systems, where a tab is conventionally 8 24.437 - characters wide).</para> 24.438 - 24.439 - &interaction.template.simple.combine; 24.440 - 24.441 - <para>Note the use of <quote><literal>\t</literal></quote> (a 24.442 - tab character) in the template to force the first line to be 24.443 - indented; this is necessary since <literal 24.444 - role="template-keyword">tabindent</literal> indents all 24.445 - lines <emphasis>except</emphasis> the first.</para> 24.446 - 24.447 - <para>Keep in mind that the order of filters in a chain is 24.448 - significant. The first filter is applied to the result of the 24.449 - keyword; the second to the result of the first filter; and so 24.450 - on. For example, using <literal>fill68|tabindent</literal> 24.451 - gives very different results from 24.452 - <literal>tabindent|fill68</literal>.</para> 24.453 - 24.454 - 24.455 - </sect2> 24.456 - </sect1> 24.457 - <sect1> 24.458 - <title>From templates to styles</title> 24.459 - 24.460 - <para>A command line template provides a quick and simple way to 24.461 - format some output. Templates can become verbose, though, and 24.462 - it's useful to be able to give a template a name. A style file 24.463 - is a template with a name, stored in a file.</para> 24.464 - 24.465 - <para>More than that, using a style file unlocks the power of 24.466 - Mercurial's templating engine in ways that are not possible 24.467 - using the command line <option 24.468 - role="hg-opt-log">--template</option> option.</para> 24.469 - 24.470 - <sect2> 24.471 - <title>The simplest of style files</title> 24.472 - 24.473 - <para>Our simple style file contains just one line:</para> 24.474 - 24.475 - &interaction.template.simple.rev; 24.476 - 24.477 - <para>This tells Mercurial, <quote>if you're printing a 24.478 - changeset, use the text on the right as the 24.479 - template</quote>.</para> 24.480 - 24.481 - </sect2> 24.482 - <sect2> 24.483 - <title>Style file syntax</title> 24.484 - 24.485 - <para>The syntax rules for a style file are simple.</para> 24.486 - 24.487 - <itemizedlist> 24.488 - <listitem><para>The file is processed one line at a 24.489 - time.</para> 24.490 - </listitem> 24.491 - <listitem><para>Leading and trailing white space are 24.492 - ignored.</para> 24.493 - </listitem> 24.494 - <listitem><para>Empty lines are skipped.</para> 24.495 - </listitem> 24.496 - <listitem><para>If a line starts with either of the characters 24.497 - <quote><literal>#</literal></quote> or 24.498 - <quote><literal>;</literal></quote>, the entire line is 24.499 - treated as a comment, and skipped as if empty.</para> 24.500 - </listitem> 24.501 - <listitem><para>A line starts with a keyword. This must start 24.502 - with an alphabetic character or underscore, and can 24.503 - subsequently contain any alphanumeric character or 24.504 - underscore. (In regexp notation, a keyword must match 24.505 - <literal>[A-Za-z_][A-Za-z0-9_]*</literal>.)</para> 24.506 - </listitem> 24.507 - <listitem><para>The next element must be an 24.508 - <quote><literal>=</literal></quote> character, which can 24.509 - be preceded or followed by an arbitrary amount of white 24.510 - space.</para> 24.511 - </listitem> 24.512 - <listitem><para>If the rest of the line starts and ends with 24.513 - matching quote characters (either single or double quote), 24.514 - it is treated as a template body.</para> 24.515 - </listitem> 24.516 - <listitem><para>If the rest of the line <emphasis>does 24.517 - not</emphasis> start with a quote character, it is 24.518 - treated as the name of a file; the contents of this file 24.519 - will be read and used as a template body.</para> 24.520 - </listitem></itemizedlist> 24.521 - 24.522 - </sect2> 24.523 - </sect1> 24.524 - <sect1> 24.525 - <title>Style files by example</title> 24.526 - 24.527 - <para>To illustrate how to write a style file, we will construct a 24.528 - few by example. Rather than provide a complete style file and 24.529 - walk through it, we'll mirror the usual process of developing a 24.530 - style file by starting with something very simple, and walking 24.531 - through a series of successively more complete examples.</para> 24.532 - 24.533 - <sect2> 24.534 - <title>Identifying mistakes in style files</title> 24.535 - 24.536 - <para>If Mercurial encounters a problem in a style file you are 24.537 - working on, it prints a terse error message that, once you 24.538 - figure out what it means, is actually quite useful.</para> 24.539 - 24.540 -&interaction.template.svnstyle.syntax.input; 24.541 - 24.542 - <para>Notice that <filename>broken.style</filename> attempts to 24.543 - define a <literal>changeset</literal> keyword, but forgets to 24.544 - give any content for it. When instructed to use this style 24.545 - file, Mercurial promptly complains.</para> 24.546 - 24.547 - &interaction.template.svnstyle.syntax.error; 24.548 - 24.549 - <para>This error message looks intimidating, but it is not too 24.550 - hard to follow.</para> 24.551 - 24.552 - <itemizedlist> 24.553 - <listitem><para>The first component is simply Mercurial's way 24.554 - of saying <quote>I am giving up</quote>.</para> 24.555 - <programlisting>___abort___: broken.style:1: parse error</programlisting> 24.556 - </listitem> 24.557 - <listitem><para>Next comes the name of the style file that 24.558 - contains the error.</para> 24.559 - <programlisting>abort: ___broken.style___:1: parse error</programlisting> 24.560 - </listitem> 24.561 - <listitem><para>Following the file name is the line number 24.562 - where the error was encountered.</para> 24.563 - <programlisting>abort: broken.style:___1___: parse error</programlisting> 24.564 - </listitem> 24.565 - <listitem><para>Finally, a description of what went 24.566 - wrong.</para> 24.567 - <programlisting>abort: broken.style:1: ___parse error___</programlisting> 24.568 - </listitem> 24.569 - <listitem><para>The description of the problem is not always 24.570 - clear (as in this case), but even when it is cryptic, it 24.571 - is almost always trivial to visually inspect the offending 24.572 - line in the style file and see what is wrong.</para> 24.573 - </listitem></itemizedlist> 24.574 - 24.575 - </sect2> 24.576 - <sect2> 24.577 - <title>Uniquely identifying a repository</title> 24.578 - 24.579 - <para>If you would like to be able to identify a Mercurial 24.580 - repository <quote>fairly uniquely</quote> using a short string 24.581 - as an identifier, you can use the first revision in the 24.582 - repository.</para> 24.583 - 24.584 - &interaction.template.svnstyle.id; 24.585 - 24.586 - <para>This is not guaranteed to be unique, but it is 24.587 - nevertheless useful in many cases.</para> 24.588 - <itemizedlist> 24.589 - <listitem><para>It will not work in a completely empty 24.590 - repository, because such a repository does not have a 24.591 - revision zero.</para> 24.592 - </listitem> 24.593 - <listitem><para>Neither will it work in the (extremely rare) 24.594 - case where a repository is a merge of two or more formerly 24.595 - independent repositories, and you still have those 24.596 - repositories around.</para> 24.597 - </listitem></itemizedlist> 24.598 - <para>Here are some uses to which you could put this 24.599 - identifier:</para> 24.600 - <itemizedlist> 24.601 - <listitem><para>As a key into a table for a database that 24.602 - manages repositories on a server.</para> 24.603 - </listitem> 24.604 - <listitem><para>As half of a {<emphasis>repository 24.605 - ID</emphasis>, <emphasis>revision ID</emphasis>} tuple. 24.606 - Save this information away when you run an automated build 24.607 - or other activity, so that you can <quote>replay</quote> 24.608 - the build later if necessary.</para> 24.609 - </listitem></itemizedlist> 24.610 - 24.611 - </sect2> 24.612 - <sect2> 24.613 - <title>Mimicking Subversion's output</title> 24.614 - 24.615 - <para>Let's try to emulate the default output format used by 24.616 - another revision control tool, Subversion.</para> 24.617 - 24.618 - &interaction.template.svnstyle.short; 24.619 - 24.620 - <para>Since Subversion's output style is fairly simple, it is 24.621 - easy to copy-and-paste a hunk of its output into a file, and 24.622 - replace the text produced above by Subversion with the 24.623 - template values we'd like to see expanded.</para> 24.624 - 24.625 - &interaction.template.svnstyle.template; 24.626 - 24.627 - <para>There are a few small ways in which this template deviates 24.628 - from the output produced by Subversion.</para> 24.629 - <itemizedlist> 24.630 - <listitem><para>Subversion prints a <quote>readable</quote> 24.631 - date (the <quote><literal>Wed, 27 Sep 2006</literal></quote> in the 24.632 - example output above) in parentheses. Mercurial's 24.633 - templating engine does not provide a way to display a date 24.634 - in this format without also printing the time and time 24.635 - zone.</para> 24.636 - </listitem> 24.637 - <listitem><para>We emulate Subversion's printing of 24.638 - <quote>separator</quote> lines full of 24.639 - <quote><literal>-</literal></quote> characters by ending 24.640 - the template with such a line. We use the templating 24.641 - engine's <literal role="template-keyword">header</literal> 24.642 - keyword to print a separator line as the first line of 24.643 - output (see below), thus achieving similar output to 24.644 - Subversion.</para> 24.645 - </listitem> 24.646 - <listitem><para>Subversion's output includes a count in the 24.647 - header of the number of lines in the commit message. We 24.648 - cannot replicate this in Mercurial; the templating engine 24.649 - does not currently provide a filter that counts the number 24.650 - of lines the template generates.</para> 24.651 - </listitem></itemizedlist> 24.652 - <para>It took me no more than a minute or two of work to replace 24.653 - literal text from an example of Subversion's output with some 24.654 - keywords and filters to give the template above. The style 24.655 - file simply refers to the template.</para> 24.656 - 24.657 - &interaction.template.svnstyle.style; 24.658 - 24.659 - <para>We could have included the text of the template file 24.660 - directly in the style file by enclosing it in quotes and 24.661 - replacing the newlines with 24.662 - <quote><literal>\n</literal></quote> sequences, but it would 24.663 - have made the style file too difficult to read. Readability 24.664 - is a good guide when you're trying to decide whether some text 24.665 - belongs in a style file, or in a template file that the style 24.666 - file points to. If the style file will look too big or 24.667 - cluttered if you insert a literal piece of text, drop it into 24.668 - a template instead.</para> 24.669 - 24.670 - </sect2> 24.671 - </sect1> 24.672 -</chapter> 24.673 - 24.674 -<!-- 24.675 -local variables: 24.676 -sgml-parent-document: ("00book.xml" "book" "chapter") 24.677 -end: 24.678 --->
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/en/ch12-mq-collab.xml Thu Mar 19 20:54:12 2009 -0700 25.3 @@ -0,0 +1,518 @@ 25.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 25.5 + 25.6 +<chapter id="chap:mq-collab"> 25.7 + <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?> 25.8 + <title>Advanced uses of Mercurial Queues</title> 25.9 + 25.10 + <para>While it's easy to pick up straightforward uses of Mercurial 25.11 + Queues, use of a little discipline and some of MQ's less 25.12 + frequently used capabilities makes it possible to work in 25.13 + complicated development environments.</para> 25.14 + 25.15 + <para>In this chapter, I will use as an example a technique I have 25.16 + used to manage the development of an Infiniband device driver for 25.17 + the Linux kernel. The driver in question is large (at least as 25.18 + drivers go), with 25,000 lines of code spread across 35 source 25.19 + files. It is maintained by a small team of developers.</para> 25.20 + 25.21 + <para>While much of the material in this chapter is specific to 25.22 + Linux, the same principles apply to any code base for which you're 25.23 + not the primary owner, and upon which you need to do a lot of 25.24 + development.</para> 25.25 + 25.26 + <sect1> 25.27 + <title>The problem of many targets</title> 25.28 + 25.29 + <para>The Linux kernel changes rapidly, and has never been 25.30 + internally stable; developers frequently make drastic changes 25.31 + between releases. This means that a version of the driver that 25.32 + works well with a particular released version of the kernel will 25.33 + not even <emphasis>compile</emphasis> correctly against, 25.34 + typically, any other version.</para> 25.35 + 25.36 + <para>To maintain a driver, we have to keep a number of distinct 25.37 + versions of Linux in mind.</para> 25.38 + <itemizedlist> 25.39 + <listitem><para>One target is the main Linux kernel development 25.40 + tree. Maintenance of the code is in this case partly shared 25.41 + by other developers in the kernel community, who make 25.42 + <quote>drive-by</quote> modifications to the driver as they 25.43 + develop and refine kernel subsystems.</para> 25.44 + </listitem> 25.45 + <listitem><para>We also maintain a number of 25.46 + <quote>backports</quote> to older versions of the Linux 25.47 + kernel, to support the needs of customers who are running 25.48 + older Linux distributions that do not incorporate our 25.49 + drivers. (To <emphasis>backport</emphasis> a piece of code 25.50 + is to modify it to work in an older version of its target 25.51 + environment than the version it was developed for.)</para> 25.52 + </listitem> 25.53 + <listitem><para>Finally, we make software releases on a schedule 25.54 + that is necessarily not aligned with those used by Linux 25.55 + distributors and kernel developers, so that we can deliver 25.56 + new features to customers without forcing them to upgrade 25.57 + their entire kernels or distributions.</para> 25.58 + </listitem></itemizedlist> 25.59 + 25.60 + <sect2> 25.61 + <title>Tempting approaches that don't work well</title> 25.62 + 25.63 + <para>There are two <quote>standard</quote> ways to maintain a 25.64 + piece of software that has to target many different 25.65 + environments.</para> 25.66 + 25.67 + <para>The first is to maintain a number of branches, each 25.68 + intended for a single target. The trouble with this approach 25.69 + is that you must maintain iron discipline in the flow of 25.70 + changes between repositories. A new feature or bug fix must 25.71 + start life in a <quote>pristine</quote> repository, then 25.72 + percolate out to every backport repository. Backport changes 25.73 + are more limited in the branches they should propagate to; a 25.74 + backport change that is applied to a branch where it doesn't 25.75 + belong will probably stop the driver from compiling.</para> 25.76 + 25.77 + <para>The second is to maintain a single source tree filled with 25.78 + conditional statements that turn chunks of code on or off 25.79 + depending on the intended target. Because these 25.80 + <quote>ifdefs</quote> are not allowed in the Linux kernel 25.81 + tree, a manual or automatic process must be followed to strip 25.82 + them out and yield a clean tree. A code base maintained in 25.83 + this fashion rapidly becomes a rat's nest of conditional 25.84 + blocks that are difficult to understand and maintain.</para> 25.85 + 25.86 + <para>Neither of these approaches is well suited to a situation 25.87 + where you don't <quote>own</quote> the canonical copy of a 25.88 + source tree. In the case of a Linux driver that is 25.89 + distributed with the standard kernel, Linus's tree contains 25.90 + the copy of the code that will be treated by the world as 25.91 + canonical. The upstream version of <quote>my</quote> driver 25.92 + can be modified by people I don't know, without me even 25.93 + finding out about it until after the changes show up in 25.94 + Linus's tree.</para> 25.95 + 25.96 + <para>These approaches have the added weakness of making it 25.97 + difficult to generate well-formed patches to submit 25.98 + upstream.</para> 25.99 + 25.100 + <para>In principle, Mercurial Queues seems like a good candidate 25.101 + to manage a development scenario such as the above. While 25.102 + this is indeed the case, MQ contains a few added features that 25.103 + make the job more pleasant.</para> 25.104 + 25.105 + </sect2> 25.106 + </sect1> 25.107 + <sect1> 25.108 + <title>Conditionally applying patches with guards</title> 25.109 + 25.110 + <para>Perhaps the best way to maintain sanity with so many targets 25.111 + is to be able to choose specific patches to apply for a given 25.112 + situation. MQ provides a feature called <quote>guards</quote> 25.113 + (which originates with quilt's <literal>guards</literal> 25.114 + command) that does just this. To start off, let's create a 25.115 + simple repository for experimenting in.</para> 25.116 + 25.117 + &interaction.mq.guards.init; 25.118 + 25.119 + <para>This gives us a tiny repository that contains two patches 25.120 + that don't have any dependencies on each other, because they 25.121 + touch different files.</para> 25.122 + 25.123 + <para>The idea behind conditional application is that you can 25.124 + <quote>tag</quote> a patch with a <emphasis>guard</emphasis>, 25.125 + which is simply a text string of your choosing, then tell MQ to 25.126 + select specific guards to use when applying patches. MQ will 25.127 + then either apply, or skip over, a guarded patch, depending on 25.128 + the guards that you have selected.</para> 25.129 + 25.130 + <para>A patch can have an arbitrary number of guards; each one is 25.131 + <emphasis>positive</emphasis> (<quote>apply this patch if this 25.132 + guard is selected</quote>) or <emphasis>negative</emphasis> 25.133 + (<quote>skip this patch if this guard is selected</quote>). A 25.134 + patch with no guards is always applied.</para> 25.135 + 25.136 + </sect1> 25.137 + <sect1> 25.138 + <title>Controlling the guards on a patch</title> 25.139 + 25.140 + <para>The <command role="hg-ext-mq">qguard</command> command lets 25.141 + you determine which guards should apply to a patch, or display 25.142 + the guards that are already in effect. Without any arguments, it 25.143 + displays the guards on the current topmost patch.</para> 25.144 + 25.145 + &interaction.mq.guards.qguard; 25.146 + 25.147 + <para>To set a positive guard on a patch, prefix the name of the 25.148 + guard with a <quote><literal>+</literal></quote>.</para> 25.149 + 25.150 + &interaction.mq.guards.qguard.pos; 25.151 + 25.152 + <para>To set a negative guard 25.153 + on a patch, prefix the name of the guard with a 25.154 + <quote><literal>-</literal></quote>.</para> 25.155 + 25.156 + &interaction.mq.guards.qguard.neg; 25.157 + 25.158 + <note> 25.159 + <para> The <command role="hg-ext-mq">qguard</command> command 25.160 + <emphasis>sets</emphasis> the guards on a patch; it doesn't 25.161 + <emphasis>modify</emphasis> them. What this means is that if 25.162 + you run <command role="hg-cmd">hg qguard +a +b</command> on a 25.163 + patch, then <command role="hg-cmd">hg qguard +c</command> on 25.164 + the same patch, the <emphasis>only</emphasis> guard that will 25.165 + be set on it afterwards is <literal>+c</literal>.</para> 25.166 + </note> 25.167 + 25.168 + <para>Mercurial stores guards in the <filename 25.169 + role="special">series</filename> file; the form in which they 25.170 + are stored is easy both to understand and to edit by hand. (In 25.171 + other words, you don't have to use the <command 25.172 + role="hg-ext-mq">qguard</command> command if you don't want 25.173 + to; it's okay to simply edit the <filename 25.174 + role="special">series</filename> file.)</para> 25.175 + 25.176 + &interaction.mq.guards.series; 25.177 + 25.178 + </sect1> 25.179 + <sect1> 25.180 + <title>Selecting the guards to use</title> 25.181 + 25.182 + <para>The <command role="hg-ext-mq">qselect</command> command 25.183 + determines which guards are active at a given time. The effect 25.184 + of this is to determine which patches MQ will apply the next 25.185 + time you run <command role="hg-ext-mq">qpush</command>. It has 25.186 + no other effect; in particular, it doesn't do anything to 25.187 + patches that are already applied.</para> 25.188 + 25.189 + <para>With no arguments, the <command 25.190 + role="hg-ext-mq">qselect</command> command lists the guards 25.191 + currently in effect, one per line of output. Each argument is 25.192 + treated as the name of a guard to apply.</para> 25.193 + 25.194 + &interaction.mq.guards.qselect.foo; 25.195 + 25.196 + <para>In case you're interested, the currently selected guards are 25.197 + stored in the <filename role="special">guards</filename> file.</para> 25.198 + 25.199 + &interaction.mq.guards.qselect.cat; 25.200 + 25.201 + <para>We can see the effect the selected guards have when we run 25.202 + <command role="hg-ext-mq">qpush</command>.</para> 25.203 + 25.204 + &interaction.mq.guards.qselect.qpush; 25.205 + 25.206 + <para>A guard cannot start with a 25.207 + <quote><literal>+</literal></quote> or 25.208 + <quote><literal>-</literal></quote> character. The name of a 25.209 + guard must not contain white space, but most other characters 25.210 + are acceptable. If you try to use a guard with an invalid name, 25.211 + MQ will complain:</para> 25.212 + 25.213 + &interaction.mq.guards.qselect.error; 25.214 + 25.215 + <para>Changing the selected guards changes the patches that are 25.216 + applied.</para> 25.217 + 25.218 + &interaction.mq.guards.qselect.quux; 25.219 + 25.220 + <para>You can see in the example below that negative guards take 25.221 + precedence over positive guards.</para> 25.222 + 25.223 + &interaction.mq.guards.qselect.foobar; 25.224 + 25.225 + </sect1> 25.226 + <sect1> 25.227 + <title>MQ's rules for applying patches</title> 25.228 + 25.229 + <para>The rules that MQ uses when deciding whether to apply a 25.230 + patch are as follows.</para> 25.231 + <itemizedlist> 25.232 + <listitem><para>A patch that has no guards is always 25.233 + applied.</para> 25.234 + </listitem> 25.235 + <listitem><para>If the patch has any negative guard that matches 25.236 + any currently selected guard, the patch is skipped.</para> 25.237 + </listitem> 25.238 + <listitem><para>If the patch has any positive guard that matches 25.239 + any currently selected guard, the patch is applied.</para> 25.240 + </listitem> 25.241 + <listitem><para>If the patch has positive or negative guards, 25.242 + but none matches any currently selected guard, the patch is 25.243 + skipped.</para> 25.244 + </listitem></itemizedlist> 25.245 + 25.246 + </sect1> 25.247 + <sect1> 25.248 + <title>Trimming the work environment</title> 25.249 + 25.250 + <para>In working on the device driver I mentioned earlier, I don't 25.251 + apply the patches to a normal Linux kernel tree. Instead, I use 25.252 + a repository that contains only a snapshot of the source files 25.253 + and headers that are relevant to Infiniband development. This 25.254 + repository is 1% the size of a kernel repository, so it's easier 25.255 + to work with.</para> 25.256 + 25.257 + <para>I then choose a <quote>base</quote> version on top of which 25.258 + the patches are applied. This is a snapshot of the Linux kernel 25.259 + tree as of a revision of my choosing. When I take the snapshot, 25.260 + I record the changeset ID from the kernel repository in the 25.261 + commit message. Since the snapshot preserves the 25.262 + <quote>shape</quote> and content of the relevant parts of the 25.263 + kernel tree, I can apply my patches on top of either my tiny 25.264 + repository or a normal kernel tree.</para> 25.265 + 25.266 + <para>Normally, the base tree atop which the patches apply should 25.267 + be a snapshot of a very recent upstream tree. This best 25.268 + facilitates the development of patches that can easily be 25.269 + submitted upstream with few or no modifications.</para> 25.270 + 25.271 + </sect1> 25.272 + <sect1> 25.273 + <title>Dividing up the <filename role="special">series</filename> 25.274 + file</title> 25.275 + 25.276 + <para>I categorise the patches in the <filename 25.277 + role="special">series</filename> file into a number of logical 25.278 + groups. Each section of like patches begins with a block of 25.279 + comments that describes the purpose of the patches that 25.280 + follow.</para> 25.281 + 25.282 + <para>The sequence of patch groups that I maintain follows. The 25.283 + ordering of these groups is important; I'll describe why after I 25.284 + introduce the groups.</para> 25.285 + <itemizedlist> 25.286 + <listitem><para>The <quote>accepted</quote> group. Patches that 25.287 + the development team has submitted to the maintainer of the 25.288 + Infiniband subsystem, and which he has accepted, but which 25.289 + are not present in the snapshot that the tiny repository is 25.290 + based on. These are <quote>read only</quote> patches, 25.291 + present only to transform the tree into a similar state as 25.292 + it is in the upstream maintainer's repository.</para> 25.293 + </listitem> 25.294 + <listitem><para>The <quote>rework</quote> group. Patches that I 25.295 + have submitted, but that the upstream maintainer has 25.296 + requested modifications to before he will accept 25.297 + them.</para> 25.298 + </listitem> 25.299 + <listitem><para>The <quote>pending</quote> group. Patches that 25.300 + I have not yet submitted to the upstream maintainer, but 25.301 + which we have finished working on. These will be <quote>read 25.302 + only</quote> for a while. If the upstream maintainer 25.303 + accepts them upon submission, I'll move them to the end of 25.304 + the <quote>accepted</quote> group. If he requests that I 25.305 + modify any, I'll move them to the beginning of the 25.306 + <quote>rework</quote> group.</para> 25.307 + </listitem> 25.308 + <listitem><para>The <quote>in progress</quote> group. Patches 25.309 + that are actively being developed, and should not be 25.310 + submitted anywhere yet.</para> 25.311 + </listitem> 25.312 + <listitem><para>The <quote>backport</quote> group. Patches that 25.313 + adapt the source tree to older versions of the kernel 25.314 + tree.</para> 25.315 + </listitem> 25.316 + <listitem><para>The <quote>do not ship</quote> group. Patches 25.317 + that for some reason should never be submitted upstream. 25.318 + For example, one such patch might change embedded driver 25.319 + identification strings to make it easier to distinguish, in 25.320 + the field, between an out-of-tree version of the driver and 25.321 + a version shipped by a distribution vendor.</para> 25.322 + </listitem></itemizedlist> 25.323 + 25.324 + <para>Now to return to the reasons for ordering groups of patches 25.325 + in this way. We would like the lowest patches in the stack to 25.326 + be as stable as possible, so that we will not need to rework 25.327 + higher patches due to changes in context. Putting patches that 25.328 + will never be changed first in the <filename 25.329 + role="special">series</filename> file serves this 25.330 + purpose.</para> 25.331 + 25.332 + <para>We would also like the patches that we know we'll need to 25.333 + modify to be applied on top of a source tree that resembles the 25.334 + upstream tree as closely as possible. This is why we keep 25.335 + accepted patches around for a while.</para> 25.336 + 25.337 + <para>The <quote>backport</quote> and <quote>do not ship</quote> 25.338 + patches float at the end of the <filename 25.339 + role="special">series</filename> file. The backport patches 25.340 + must be applied on top of all other patches, and the <quote>do 25.341 + not ship</quote> patches might as well stay out of harm's 25.342 + way.</para> 25.343 + 25.344 + </sect1> 25.345 + <sect1> 25.346 + <title>Maintaining the patch series</title> 25.347 + 25.348 + <para>In my work, I use a number of guards to control which 25.349 + patches are to be applied.</para> 25.350 + 25.351 + <itemizedlist> 25.352 + <listitem><para><quote>Accepted</quote> patches are guarded with 25.353 + <literal>accepted</literal>. I enable this guard most of 25.354 + the time. When I'm applying the patches on top of a tree 25.355 + where the patches are already present, I can turn this patch 25.356 + off, and the patches that follow it will apply 25.357 + cleanly.</para> 25.358 + </listitem> 25.359 + <listitem><para>Patches that are <quote>finished</quote>, but 25.360 + not yet submitted, have no guards. If I'm applying the 25.361 + patch stack to a copy of the upstream tree, I don't need to 25.362 + enable any guards in order to get a reasonably safe source 25.363 + tree.</para> 25.364 + </listitem> 25.365 + <listitem><para>Those patches that need reworking before being 25.366 + resubmitted are guarded with 25.367 + <literal>rework</literal>.</para> 25.368 + </listitem> 25.369 + <listitem><para>For those patches that are still under 25.370 + development, I use <literal>devel</literal>.</para> 25.371 + </listitem> 25.372 + <listitem><para>A backport patch may have several guards, one 25.373 + for each version of the kernel to which it applies. For 25.374 + example, a patch that backports a piece of code to 2.6.9 25.375 + will have a <literal>2.6.9</literal> guard.</para> 25.376 + </listitem></itemizedlist> 25.377 + <para>This variety of guards gives me considerable flexibility in 25.378 + determining what kind of source tree I want to end up with. For 25.379 + most situations, the selection of appropriate guards is 25.380 + automated during the build process, but I can manually tune the 25.381 + guards to use for less common circumstances.</para> 25.382 + 25.383 + <sect2> 25.384 + <title>The art of writing backport patches</title> 25.385 + 25.386 + <para>Using MQ, writing a backport patch is a simple process. 25.387 + All such a patch has to do is modify a piece of code that uses 25.388 + a kernel feature not present in the older version of the 25.389 + kernel, so that the driver continues to work correctly under 25.390 + that older version.</para> 25.391 + 25.392 + <para>A useful goal when writing a good backport patch is to 25.393 + make your code look as if it was written for the older version 25.394 + of the kernel you're targeting. The less obtrusive the patch, 25.395 + the easier it will be to understand and maintain. If you're 25.396 + writing a collection of backport patches to avoid the 25.397 + <quote>rat's nest</quote> effect of lots of 25.398 + <literal>#ifdef</literal>s (hunks of source code that are only 25.399 + used conditionally) in your code, don't introduce 25.400 + version-dependent <literal>#ifdef</literal>s into the patches. 25.401 + Instead, write several patches, each of which makes 25.402 + unconditional changes, and control their application using 25.403 + guards.</para> 25.404 + 25.405 + <para>There are two reasons to divide backport patches into a 25.406 + distinct group, away from the <quote>regular</quote> patches 25.407 + whose effects they modify. The first is that intermingling the 25.408 + two makes it more difficult to use a tool like the <literal 25.409 + role="hg-ext">patchbomb</literal> extension to automate the 25.410 + process of submitting the patches to an upstream maintainer. 25.411 + The second is that a backport patch could perturb the context 25.412 + in which a subsequent regular patch is applied, making it 25.413 + impossible to apply the regular patch cleanly 25.414 + <emphasis>without</emphasis> the earlier backport patch 25.415 + already being applied.</para> 25.416 + 25.417 + </sect2> 25.418 + </sect1> 25.419 + <sect1> 25.420 + <title>Useful tips for developing with MQ</title> 25.421 + 25.422 + <sect2> 25.423 + <title>Organising patches in directories</title> 25.424 + 25.425 + <para>If you're working on a substantial project with MQ, it's 25.426 + not difficult to accumulate a large number of patches. For 25.427 + example, I have one patch repository that contains over 250 25.428 + patches.</para> 25.429 + 25.430 + <para>If you can group these patches into separate logical 25.431 + categories, you can if you like store them in different 25.432 + directories; MQ has no problems with patch names that contain 25.433 + path separators.</para> 25.434 + 25.435 + </sect2> 25.436 + <sect2 id="mq-collab:tips:interdiff"> 25.437 + <title>Viewing the history of a patch</title> 25.438 + 25.439 + <para>If you're developing a set of patches over a long time, 25.440 + it's a good idea to maintain them in a repository, as 25.441 + discussed in section <xref linkend="sec:mq:repo"/>. If you do 25.442 + so, you'll quickly 25.443 + discover that using the <command role="hg-cmd">hg 25.444 + diff</command> command to look at the history of changes to 25.445 + a patch is unworkable. This is in part because you're looking 25.446 + at the second derivative of the real code (a diff of a diff), 25.447 + but also because MQ adds noise to the process by modifying 25.448 + time stamps and directory names when it updates a 25.449 + patch.</para> 25.450 + 25.451 + <para>However, you can use the <literal 25.452 + role="hg-ext">extdiff</literal> extension, which is bundled 25.453 + with Mercurial, to turn a diff of two versions of a patch into 25.454 + something readable. To do this, you will need a third-party 25.455 + package called <literal role="package">patchutils</literal> 25.456 + <citation>web:patchutils</citation>. This provides a command 25.457 + named <command>interdiff</command>, which shows the 25.458 + differences between two diffs as a diff. Used on two versions 25.459 + of the same diff, it generates a diff that represents the diff 25.460 + from the first to the second version.</para> 25.461 + 25.462 + <para>You can enable the <literal 25.463 + role="hg-ext">extdiff</literal> extension in the usual way, 25.464 + by adding a line to the <literal 25.465 + role="rc-extensions">extensions</literal> section of your 25.466 + <filename role="special">~/.hgrc</filename>.</para> 25.467 + <programlisting>[extensions] 25.468 +extdiff =</programlisting> 25.469 + <para>The <command>interdiff</command> command expects to be 25.470 + passed the names of two files, but the <literal 25.471 + role="hg-ext">extdiff</literal> extension passes the program 25.472 + it runs a pair of directories, each of which can contain an 25.473 + arbitrary number of files. We thus need a small program that 25.474 + will run <command>interdiff</command> on each pair of files in 25.475 + these two directories. This program is available as <filename 25.476 + role="special">hg-interdiff</filename> in the <filename 25.477 + class="directory">examples</filename> directory of the 25.478 + source code repository that accompanies this book. <!-- 25.479 + &example.hg-interdiff; --></para> 25.480 + 25.481 + <para>With the <filename role="special">hg-interdiff</filename> 25.482 + program in your shell's search path, you can run it as 25.483 + follows, from inside an MQ patch directory:</para> 25.484 + <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting> 25.485 + <para>Since you'll probably want to use this long-winded command 25.486 + a lot, you can get <literal role="hg-ext">hgext</literal> to 25.487 + make it available as a normal Mercurial command, again by 25.488 + editing your <filename 25.489 + role="special">~/.hgrc</filename>.</para> 25.490 + <programlisting>[extdiff] 25.491 +cmd.interdiff = hg-interdiff</programlisting> 25.492 + <para>This directs <literal role="hg-ext">hgext</literal> to 25.493 + make an <literal>interdiff</literal> command available, so you 25.494 + can now shorten the previous invocation of <command 25.495 + role="hg-ext-extdiff">extdiff</command> to something a 25.496 + little more wieldy.</para> 25.497 + <programlisting>hg interdiff -r A:B my-change.patch</programlisting> 25.498 + 25.499 + <note> 25.500 + <para> The <command>interdiff</command> command works well 25.501 + only if the underlying files against which versions of a 25.502 + patch are generated remain the same. If you create a patch, 25.503 + modify the underlying files, and then regenerate the patch, 25.504 + <command>interdiff</command> may not produce useful 25.505 + output.</para> 25.506 + </note> 25.507 + 25.508 + <para>The <literal role="hg-ext">extdiff</literal> extension is 25.509 + useful for more than merely improving the presentation of MQ 25.510 + patches. To read more about it, go to section <xref 25.511 + linkend="sec:hgext:extdiff"/>.</para> 25.512 + 25.513 + </sect2> 25.514 + </sect1> 25.515 +</chapter> 25.516 + 25.517 +<!-- 25.518 +local variables: 25.519 +sgml-parent-document: ("00book.xml" "book" "chapter") 25.520 +end: 25.521 +-->
26.1 --- a/en/ch12-mq.xml Wed Mar 18 00:08:22 2009 -0700 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,1322 +0,0 @@ 26.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 26.5 - 26.6 -<chapter id="chap:mq"> 26.7 - <?dbhtml filename="managing-change-with-mercurial-queues.html"?> 26.8 - <title>Managing change with Mercurial Queues</title> 26.9 - 26.10 - <sect1 id="sec:mq:patch-mgmt"> 26.11 - <title>The patch management problem</title> 26.12 - 26.13 - <para>Here is a common scenario: you need to install a software 26.14 - package from source, but you find a bug that you must fix in the 26.15 - source before you can start using the package. You make your 26.16 - changes, forget about the package for a while, and a few months 26.17 - later you need to upgrade to a newer version of the package. If 26.18 - the newer version of the package still has the bug, you must 26.19 - extract your fix from the older source tree and apply it against 26.20 - the newer version. This is a tedious task, and it's easy to 26.21 - make mistakes.</para> 26.22 - 26.23 - <para>This is a simple case of the <quote>patch management</quote> 26.24 - problem. You have an <quote>upstream</quote> source tree that 26.25 - you can't change; you need to make some local changes on top of 26.26 - the upstream tree; and you'd like to be able to keep those 26.27 - changes separate, so that you can apply them to newer versions 26.28 - of the upstream source.</para> 26.29 - 26.30 - <para>The patch management problem arises in many situations. 26.31 - Probably the most visible is that a user of an open source 26.32 - software project will contribute a bug fix or new feature to the 26.33 - project's maintainers in the form of a patch.</para> 26.34 - 26.35 - <para>Distributors of operating systems that include open source 26.36 - software often need to make changes to the packages they 26.37 - distribute so that they will build properly in their 26.38 - environments.</para> 26.39 - 26.40 - <para>When you have few changes to maintain, it is easy to manage 26.41 - a single patch using the standard <command>diff</command> and 26.42 - <command>patch</command> programs (see section <xref 26.43 - linkend="sec:mq:patch"/> for a discussion of these 26.44 - tools). Once the number of changes grows, it starts to make 26.45 - sense to maintain patches as discrete <quote>chunks of 26.46 - work,</quote> so that for example a single patch will contain 26.47 - only one bug fix (the patch might modify several files, but it's 26.48 - doing <quote>only one thing</quote>), and you may have a number 26.49 - of such patches for different bugs you need fixed and local 26.50 - changes you require. In this situation, if you submit a bug fix 26.51 - patch to the upstream maintainers of a package and they include 26.52 - your fix in a subsequent release, you can simply drop that 26.53 - single patch when you're updating to the newer release.</para> 26.54 - 26.55 - <para>Maintaining a single patch against an upstream tree is a 26.56 - little tedious and error-prone, but not difficult. However, the 26.57 - complexity of the problem grows rapidly as the number of patches 26.58 - you have to maintain increases. With more than a tiny number of 26.59 - patches in hand, understanding which ones you have applied and 26.60 - maintaining them moves from messy to overwhelming.</para> 26.61 - 26.62 - <para>Fortunately, Mercurial includes a powerful extension, 26.63 - Mercurial Queues (or simply <quote>MQ</quote>), that massively 26.64 - simplifies the patch management problem.</para> 26.65 - 26.66 - </sect1> 26.67 - <sect1 id="sec:mq:history"> 26.68 - <title>The prehistory of Mercurial Queues</title> 26.69 - 26.70 - <para>During the late 1990s, several Linux kernel developers 26.71 - started to maintain <quote>patch series</quote> that modified 26.72 - the behaviour of the Linux kernel. Some of these series were 26.73 - focused on stability, some on feature coverage, and others were 26.74 - more speculative.</para> 26.75 - 26.76 - <para>The sizes of these patch series grew rapidly. In 2002, 26.77 - Andrew Morton published some shell scripts he had been using to 26.78 - automate the task of managing his patch queues. Andrew was 26.79 - successfully using these scripts to manage hundreds (sometimes 26.80 - thousands) of patches on top of the Linux kernel.</para> 26.81 - 26.82 - <sect2 id="sec:mq:quilt"> 26.83 - <title>A patchwork quilt</title> 26.84 - 26.85 - <para>In early 2003, Andreas Gruenbacher and Martin Quinson 26.86 - borrowed the approach of Andrew's scripts and published a tool 26.87 - called <quote>patchwork quilt</quote> 26.88 - <citation>web:quilt</citation>, or simply <quote>quilt</quote> 26.89 - (see <citation>gruenbacher:2005</citation> for a paper 26.90 - describing it). Because quilt substantially automated patch 26.91 - management, it rapidly gained a large following among open 26.92 - source software developers.</para> 26.93 - 26.94 - <para>Quilt manages a <emphasis>stack of patches</emphasis> on 26.95 - top of a directory tree. To begin, you tell quilt to manage a 26.96 - directory tree, and tell it which files you want to manage; it 26.97 - stores away the names and contents of those files. To fix a 26.98 - bug, you create a new patch (using a single command), edit the 26.99 - files you need to fix, then <quote>refresh</quote> the 26.100 - patch.</para> 26.101 - 26.102 - <para>The refresh step causes quilt to scan the directory tree; 26.103 - it updates the patch with all of the changes you have made. 26.104 - You can create another patch on top of the first, which will 26.105 - track the changes required to modify the tree from <quote>tree 26.106 - with one patch applied</quote> to <quote>tree with two 26.107 - patches applied</quote>.</para> 26.108 - 26.109 - <para>You can <emphasis>change</emphasis> which patches are 26.110 - applied to the tree. If you <quote>pop</quote> a patch, the 26.111 - changes made by that patch will vanish from the directory 26.112 - tree. Quilt remembers which patches you have popped, though, 26.113 - so you can <quote>push</quote> a popped patch again, and the 26.114 - directory tree will be restored to contain the modifications 26.115 - in the patch. Most importantly, you can run the 26.116 - <quote>refresh</quote> command at any time, and the topmost 26.117 - applied patch will be updated. This means that you can, at 26.118 - any time, change both which patches are applied and what 26.119 - modifications those patches make.</para> 26.120 - 26.121 - <para>Quilt knows nothing about revision control tools, so it 26.122 - works equally well on top of an unpacked tarball or a 26.123 - Subversion working copy.</para> 26.124 - 26.125 - </sect2> 26.126 - <sect2 id="sec:mq:quilt-mq"> 26.127 - <title>From patchwork quilt to Mercurial Queues</title> 26.128 - 26.129 - <para>In mid-2005, Chris Mason took the features of quilt and 26.130 - wrote an extension that he called Mercurial Queues, which 26.131 - added quilt-like behaviour to Mercurial.</para> 26.132 - 26.133 - <para>The key difference between quilt and MQ is that quilt 26.134 - knows nothing about revision control systems, while MQ is 26.135 - <emphasis>integrated</emphasis> into Mercurial. Each patch 26.136 - that you push is represented as a Mercurial changeset. Pop a 26.137 - patch, and the changeset goes away.</para> 26.138 - 26.139 - <para>Because quilt does not care about revision control tools, 26.140 - it is still a tremendously useful piece of software to know 26.141 - about for situations where you cannot use Mercurial and 26.142 - MQ.</para> 26.143 - 26.144 - </sect2> 26.145 - </sect1> 26.146 - <sect1> 26.147 - <title>The huge advantage of MQ</title> 26.148 - 26.149 - <para>I cannot overstate the value that MQ offers through the 26.150 - unification of patches and revision control.</para> 26.151 - 26.152 - <para>A major reason that patches have persisted in the free 26.153 - software and open source world&emdash;in spite of the 26.154 - availability of increasingly capable revision control tools over 26.155 - the years&emdash;is the <emphasis>agility</emphasis> they 26.156 - offer.</para> 26.157 - 26.158 - <para>Traditional revision control tools make a permanent, 26.159 - irreversible record of everything that you do. While this has 26.160 - great value, it's also somewhat stifling. If you want to 26.161 - perform a wild-eyed experiment, you have to be careful in how 26.162 - you go about it, or you risk leaving unneeded&emdash;or worse, 26.163 - misleading or destabilising&emdash;traces of your missteps and 26.164 - errors in the permanent revision record.</para> 26.165 - 26.166 - <para>By contrast, MQ's marriage of distributed revision control 26.167 - with patches makes it much easier to isolate your work. Your 26.168 - patches live on top of normal revision history, and you can make 26.169 - them disappear or reappear at will. If you don't like a patch, 26.170 - you can drop it. If a patch isn't quite as you want it to be, 26.171 - simply fix it&emdash;as many times as you need to, until you 26.172 - have refined it into the form you desire.</para> 26.173 - 26.174 - <para>As an example, the integration of patches with revision 26.175 - control makes understanding patches and debugging their 26.176 - effects&emdash;and their interplay with the code they're based 26.177 - on&emdash;<emphasis>enormously</emphasis> easier. Since every 26.178 - applied patch has an associated changeset, you can give <command 26.179 - role="hg-cmd">hg log</command> a file name to see which 26.180 - changesets and patches affected the file. You can use the 26.181 - <command role="hg-cmd">hg bisect</command> command to 26.182 - binary-search through all changesets and applied patches to see 26.183 - where a bug got introduced or fixed. You can use the <command 26.184 - role="hg-cmd">hg annotate</command> command to see which 26.185 - changeset or patch modified a particular line of a source file. 26.186 - And so on.</para> 26.187 - 26.188 - </sect1> 26.189 - <sect1 id="sec:mq:patch"> 26.190 - <title>Understanding patches</title> 26.191 - 26.192 - <para>Because MQ doesn't hide its patch-oriented nature, it is 26.193 - helpful to understand what patches are, and a little about the 26.194 - tools that work with them.</para> 26.195 - 26.196 - <para>The traditional Unix <command>diff</command> command 26.197 - compares two files, and prints a list of differences between 26.198 - them. The <command>patch</command> command understands these 26.199 - differences as <emphasis>modifications</emphasis> to make to a 26.200 - file. Take a look below for a simple example of these commands 26.201 - in action.</para> 26.202 - 26.203 -&interaction.mq.dodiff.diff; 26.204 - 26.205 - <para>The type of file that <command>diff</command> generates (and 26.206 - <command>patch</command> takes as input) is called a 26.207 - <quote>patch</quote> or a <quote>diff</quote>; there is no 26.208 - difference between a patch and a diff. (We'll use the term 26.209 - <quote>patch</quote>, since it's more commonly used.)</para> 26.210 - 26.211 - <para>A patch file can start with arbitrary text; the 26.212 - <command>patch</command> command ignores this text, but MQ uses 26.213 - it as the commit message when creating changesets. To find the 26.214 - beginning of the patch content, <command>patch</command> 26.215 - searches for the first line that starts with the string 26.216 - <quote><literal>diff -</literal></quote>.</para> 26.217 - 26.218 - <para>MQ works with <emphasis>unified</emphasis> diffs 26.219 - (<command>patch</command> can accept several other diff formats, 26.220 - but MQ doesn't). A unified diff contains two kinds of header. 26.221 - The <emphasis>file header</emphasis> describes the file being 26.222 - modified; it contains the name of the file to modify. When 26.223 - <command>patch</command> sees a new file header, it looks for a 26.224 - file with that name to start modifying.</para> 26.225 - 26.226 - <para>After the file header comes a series of 26.227 - <emphasis>hunks</emphasis>. Each hunk starts with a header; 26.228 - this identifies the range of line numbers within the file that 26.229 - the hunk should modify. Following the header, a hunk starts and 26.230 - ends with a few (usually three) lines of text from the 26.231 - unmodified file; these are called the 26.232 - <emphasis>context</emphasis> for the hunk. If there's only a 26.233 - small amount of context between successive hunks, 26.234 - <command>diff</command> doesn't print a new hunk header; it just 26.235 - runs the hunks together, with a few lines of context between 26.236 - modifications.</para> 26.237 - 26.238 - <para>Each line of context begins with a space character. Within 26.239 - the hunk, a line that begins with 26.240 - <quote><literal>-</literal></quote> means <quote>remove this 26.241 - line,</quote> while a line that begins with 26.242 - <quote><literal>+</literal></quote> means <quote>insert this 26.243 - line.</quote> For example, a line that is modified is 26.244 - represented by one deletion and one insertion.</para> 26.245 - 26.246 - <para>We will return to some of the more subtle aspects of patches 26.247 - later (in section <xref linkend="sec:mq:adv-patch"/>), but you 26.248 - should have 26.249 - enough information now to use MQ.</para> 26.250 - 26.251 - </sect1> 26.252 - <sect1 id="sec:mq:start"> 26.253 - <title>Getting started with Mercurial Queues</title> 26.254 - 26.255 - <para>Because MQ is implemented as an extension, you must 26.256 - explicitly enable before you can use it. (You don't need to 26.257 - download anything; MQ ships with the standard Mercurial 26.258 - distribution.) To enable MQ, edit your <filename 26.259 - role="home">~/.hgrc</filename> file, and add the lines 26.260 - below.</para> 26.261 - 26.262 - <programlisting>[extensions] 26.263 -hgext.mq =</programlisting> 26.264 - 26.265 - <para>Once the extension is enabled, it will make a number of new 26.266 - commands available. To verify that the extension is working, 26.267 - you can use <command role="hg-cmd">hg help</command> to see if 26.268 - the <command role="hg-ext-mq">qinit</command> command is now 26.269 - available.</para> 26.270 - 26.271 -&interaction.mq.qinit-help.help; 26.272 - 26.273 - <para>You can use MQ with <emphasis>any</emphasis> Mercurial 26.274 - repository, and its commands only operate within that 26.275 - repository. To get started, simply prepare the repository using 26.276 - the <command role="hg-ext-mq">qinit</command> command.</para> 26.277 - 26.278 -&interaction.mq.tutorial.qinit; 26.279 - 26.280 - <para>This command creates an empty directory called <filename 26.281 - role="special" class="directory">.hg/patches</filename>, where 26.282 - MQ will keep its metadata. As with many Mercurial commands, the 26.283 - <command role="hg-ext-mq">qinit</command> command prints nothing 26.284 - if it succeeds.</para> 26.285 - 26.286 - <sect2> 26.287 - <title>Creating a new patch</title> 26.288 - 26.289 - <para>To begin work on a new patch, use the <command 26.290 - role="hg-ext-mq">qnew</command> command. This command takes 26.291 - one argument, the name of the patch to create.</para> 26.292 - 26.293 - <para>MQ will use this as the name of an actual file in the 26.294 - <filename role="special" 26.295 - class="directory">.hg/patches</filename> directory, as you 26.296 - can see below.</para> 26.297 - 26.298 -&interaction.mq.tutorial.qnew; 26.299 - 26.300 - <para>Also newly present in the <filename role="special" 26.301 - class="directory">.hg/patches</filename> directory are two 26.302 - other files, <filename role="special">series</filename> and 26.303 - <filename role="special">status</filename>. The <filename 26.304 - role="special">series</filename> file lists all of the 26.305 - patches that MQ knows about for this repository, with one 26.306 - patch per line. Mercurial uses the <filename 26.307 - role="special">status</filename> file for internal 26.308 - book-keeping; it tracks all of the patches that MQ has 26.309 - <emphasis>applied</emphasis> in this repository.</para> 26.310 - 26.311 - <note> 26.312 - <para> You may sometimes want to edit the <filename 26.313 - role="special">series</filename> file by hand; for 26.314 - example, to change the sequence in which some patches are 26.315 - applied. However, manually editing the <filename 26.316 - role="special">status</filename> file is almost always a 26.317 - bad idea, as it's easy to corrupt MQ's idea of what is 26.318 - happening.</para> 26.319 - </note> 26.320 - 26.321 - <para>Once you have created your new patch, you can edit files 26.322 - in the working directory as you usually would. All of the 26.323 - normal Mercurial commands, such as <command role="hg-cmd">hg 26.324 - diff</command> and <command role="hg-cmd">hg 26.325 - annotate</command>, work exactly as they did before.</para> 26.326 - 26.327 - </sect2> 26.328 - <sect2> 26.329 - <title>Refreshing a patch</title> 26.330 - 26.331 - <para>When you reach a point where you want to save your work, 26.332 - use the <command role="hg-ext-mq">qrefresh</command> command 26.333 - to update the patch you are working on.</para> 26.334 - 26.335 -&interaction.mq.tutorial.qrefresh; 26.336 - 26.337 - <para>This command folds the changes you have made in the 26.338 - working directory into your patch, and updates its 26.339 - corresponding changeset to contain those changes.</para> 26.340 - 26.341 - <para>You can run <command role="hg-ext-mq">qrefresh</command> 26.342 - as often as you like, so it's a good way to 26.343 - <quote>checkpoint</quote> your work. Refresh your patch at an 26.344 - opportune time; try an experiment; and if the experiment 26.345 - doesn't work out, <command role="hg-cmd">hg revert</command> 26.346 - your modifications back to the last time you refreshed.</para> 26.347 - 26.348 -&interaction.mq.tutorial.qrefresh2; 26.349 - 26.350 - </sect2> 26.351 - <sect2> 26.352 - <title>Stacking and tracking patches</title> 26.353 - 26.354 - <para>Once you have finished working on a patch, or need to work 26.355 - on another, you can use the <command 26.356 - role="hg-ext-mq">qnew</command> command again to create a 26.357 - new patch. Mercurial will apply this patch on top of your 26.358 - existing patch.</para> 26.359 - 26.360 -&interaction.mq.tutorial.qnew2; 26.361 - <para>Notice that the patch contains the changes in our prior 26.362 - patch as part of its context (you can see this more clearly in 26.363 - the output of <command role="hg-cmd">hg 26.364 - annotate</command>).</para> 26.365 - 26.366 - <para>So far, with the exception of <command 26.367 - role="hg-ext-mq">qnew</command> and <command 26.368 - role="hg-ext-mq">qrefresh</command>, we've been careful to 26.369 - only use regular Mercurial commands. However, MQ provides 26.370 - many commands that are easier to use when you are thinking 26.371 - about patches, as illustrated below.</para> 26.372 - 26.373 -&interaction.mq.tutorial.qseries; 26.374 - 26.375 - <itemizedlist> 26.376 - <listitem><para>The <command 26.377 - role="hg-ext-mq">qseries</command> command lists every 26.378 - patch that MQ knows about in this repository, from oldest 26.379 - to newest (most recently 26.380 - <emphasis>created</emphasis>).</para> 26.381 - </listitem> 26.382 - <listitem><para>The <command 26.383 - role="hg-ext-mq">qapplied</command> command lists every 26.384 - patch that MQ has <emphasis>applied</emphasis> in this 26.385 - repository, again from oldest to newest (most recently 26.386 - applied).</para> 26.387 - </listitem></itemizedlist> 26.388 - 26.389 - </sect2> 26.390 - <sect2> 26.391 - <title>Manipulating the patch stack</title> 26.392 - 26.393 - <para>The previous discussion implied that there must be a 26.394 - difference between <quote>known</quote> and 26.395 - <quote>applied</quote> patches, and there is. MQ can manage a 26.396 - patch without it being applied in the repository.</para> 26.397 - 26.398 - <para>An <emphasis>applied</emphasis> patch has a corresponding 26.399 - changeset in the repository, and the effects of the patch and 26.400 - changeset are visible in the working directory. You can undo 26.401 - the application of a patch using the <command 26.402 - role="hg-ext-mq">qpop</command> command. MQ still 26.403 - <emphasis>knows about</emphasis>, or manages, a popped patch, 26.404 - but the patch no longer has a corresponding changeset in the 26.405 - repository, and the working directory does not contain the 26.406 - changes made by the patch. Figure <xref 26.407 - linkend="fig:mq:stack"/> illustrates 26.408 - the difference between applied and tracked patches.</para> 26.409 - 26.410 - <informalfigure id="fig:mq:stack"> 26.411 - <mediaobject><imageobject><imagedata 26.412 - fileref="mq-stack"/></imageobject><textobject><phrase>XXX 26.413 - add text</phrase></textobject><caption><para>Applied and 26.414 - unapplied patches in the MQ patch 26.415 - stack</para></caption></mediaobject> 26.416 - </informalfigure> 26.417 - 26.418 - <para>You can reapply an unapplied, or popped, patch using the 26.419 - <command role="hg-ext-mq">qpush</command> command. This 26.420 - creates a new changeset to correspond to the patch, and the 26.421 - patch's changes once again become present in the working 26.422 - directory. See below for examples of <command 26.423 - role="hg-ext-mq">qpop</command> and <command 26.424 - role="hg-ext-mq">qpush</command> in action.</para> 26.425 -&interaction.mq.tutorial.qpop; 26.426 - 26.427 - <para>Notice that once we have popped a patch or two patches, 26.428 - the output of <command role="hg-ext-mq">qseries</command> 26.429 - remains the same, while that of <command 26.430 - role="hg-ext-mq">qapplied</command> has changed.</para> 26.431 - 26.432 - 26.433 - </sect2> 26.434 - <sect2> 26.435 - <title>Pushing and popping many patches</title> 26.436 - 26.437 - <para>While <command role="hg-ext-mq">qpush</command> and 26.438 - <command role="hg-ext-mq">qpop</command> each operate on a 26.439 - single patch at a time by default, you can push and pop many 26.440 - patches in one go. The <option 26.441 - role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to 26.442 - <command role="hg-ext-mq">qpush</command> causes it to push 26.443 - all unapplied patches, while the <option 26.444 - role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command 26.445 - role="hg-ext-mq">qpop</command> causes it to pop all applied 26.446 - patches. (For some more ways to push and pop many patches, 26.447 - see section <xref linkend="sec:mq:perf"/> 26.448 - below.)</para> 26.449 - 26.450 -&interaction.mq.tutorial.qpush-a; 26.451 - 26.452 - </sect2> 26.453 - <sect2> 26.454 - <title>Safety checks, and overriding them</title> 26.455 - 26.456 - <para>Several MQ commands check the working directory before 26.457 - they do anything, and fail if they find any modifications. 26.458 - They do this to ensure that you won't lose any changes that 26.459 - you have made, but not yet incorporated into a patch. The 26.460 - example below illustrates this; the <command 26.461 - role="hg-ext-mq">qnew</command> command will not create a 26.462 - new patch if there are outstanding changes, caused in this 26.463 - case by the <command role="hg-cmd">hg add</command> of 26.464 - <filename>file3</filename>.</para> 26.465 - 26.466 -&interaction.mq.tutorial.add; 26.467 - 26.468 - <para>Commands that check the working directory all take an 26.469 - <quote>I know what I'm doing</quote> option, which is always 26.470 - named <option>-f</option>. The exact meaning of 26.471 - <option>-f</option> depends on the command. For example, 26.472 - <command role="hg-cmd">hg qnew <option 26.473 - role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command> 26.474 - will incorporate any outstanding changes into the new patch it 26.475 - creates, but <command role="hg-cmd">hg qpop <option 26.476 - role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command> 26.477 - will revert modifications to any files affected by the patch 26.478 - that it is popping. Be sure to read the documentation for a 26.479 - command's <option>-f</option> option before you use it!</para> 26.480 - 26.481 - </sect2> 26.482 - <sect2> 26.483 - <title>Working on several patches at once</title> 26.484 - 26.485 - <para>The <command role="hg-ext-mq">qrefresh</command> command 26.486 - always refreshes the <emphasis>topmost</emphasis> applied 26.487 - patch. This means that you can suspend work on one patch (by 26.488 - refreshing it), pop or push to make a different patch the top, 26.489 - and work on <emphasis>that</emphasis> patch for a 26.490 - while.</para> 26.491 - 26.492 - <para>Here's an example that illustrates how you can use this 26.493 - ability. Let's say you're developing a new feature as two 26.494 - patches. The first is a change to the core of your software, 26.495 - and the second&emdash;layered on top of the 26.496 - first&emdash;changes the user interface to use the code you 26.497 - just added to the core. If you notice a bug in the core while 26.498 - you're working on the UI patch, it's easy to fix the core. 26.499 - Simply <command role="hg-ext-mq">qrefresh</command> the UI 26.500 - patch to save your in-progress changes, and <command 26.501 - role="hg-ext-mq">qpop</command> down to the core patch. Fix 26.502 - the core bug, <command role="hg-ext-mq">qrefresh</command> the 26.503 - core patch, and <command role="hg-ext-mq">qpush</command> back 26.504 - to the UI patch to continue where you left off.</para> 26.505 - 26.506 - </sect2> 26.507 - </sect1> 26.508 - <sect1 id="sec:mq:adv-patch"> 26.509 - <title>More about patches</title> 26.510 - 26.511 - <para>MQ uses the GNU <command>patch</command> command to apply 26.512 - patches, so it's helpful to know a few more detailed aspects of 26.513 - how <command>patch</command> works, and about patches 26.514 - themselves.</para> 26.515 - 26.516 - <sect2> 26.517 - <title>The strip count</title> 26.518 - 26.519 - <para>If you look at the file headers in a patch, you will 26.520 - notice that the pathnames usually have an extra component on 26.521 - the front that isn't present in the actual path name. This is 26.522 - a holdover from the way that people used to generate patches 26.523 - (people still do this, but it's somewhat rare with modern 26.524 - revision control tools).</para> 26.525 - 26.526 - <para>Alice would unpack a tarball, edit her files, then decide 26.527 - that she wanted to create a patch. So she'd rename her 26.528 - working directory, unpack the tarball again (hence the need 26.529 - for the rename), and use the <option 26.530 - role="cmd-opt-diff">-r</option> and <option 26.531 - role="cmd-opt-diff">-N</option> options to 26.532 - <command>diff</command> to recursively generate a patch 26.533 - between the unmodified directory and the modified one. The 26.534 - result would be that the name of the unmodified directory 26.535 - would be at the front of the left-hand path in every file 26.536 - header, and the name of the modified directory would be at the 26.537 - front of the right-hand path.</para> 26.538 - 26.539 - <para>Since someone receiving a patch from the Alices of the net 26.540 - would be unlikely to have unmodified and modified directories 26.541 - with exactly the same names, the <command>patch</command> 26.542 - command has a <option role="cmd-opt-patch">-p</option> option 26.543 - that indicates the number of leading path name components to 26.544 - strip when trying to apply a patch. This number is called the 26.545 - <emphasis>strip count</emphasis>.</para> 26.546 - 26.547 - <para>An option of <quote><literal>-p1</literal></quote> means 26.548 - <quote>use a strip count of one</quote>. If 26.549 - <command>patch</command> sees a file name 26.550 - <filename>foo/bar/baz</filename> in a file header, it will 26.551 - strip <filename>foo</filename> and try to patch a file named 26.552 - <filename>bar/baz</filename>. (Strictly speaking, the strip 26.553 - count refers to the number of <emphasis>path 26.554 - separators</emphasis> (and the components that go with them 26.555 - ) to strip. A strip count of one will turn 26.556 - <filename>foo/bar</filename> into <filename>bar</filename>, 26.557 - but <filename>/foo/bar</filename> (notice the extra leading 26.558 - slash) into <filename>foo/bar</filename>.)</para> 26.559 - 26.560 - <para>The <quote>standard</quote> strip count for patches is 26.561 - one; almost all patches contain one leading path name 26.562 - component that needs to be stripped. Mercurial's <command 26.563 - role="hg-cmd">hg diff</command> command generates path names 26.564 - in this form, and the <command role="hg-cmd">hg 26.565 - import</command> command and MQ expect patches to have a 26.566 - strip count of one.</para> 26.567 - 26.568 - <para>If you receive a patch from someone that you want to add 26.569 - to your patch queue, and the patch needs a strip count other 26.570 - than one, you cannot just <command 26.571 - role="hg-ext-mq">qimport</command> the patch, because 26.572 - <command role="hg-ext-mq">qimport</command> does not yet have 26.573 - a <literal>-p</literal> option (see <ulink role="hg-bug" 26.574 - url="http://www.selenic.com/mercurial/bts/issue311">issue 26.575 - 311</ulink>). Your best bet is to <command 26.576 - role="hg-ext-mq">qnew</command> a patch of your own, then 26.577 - use <command>patch -pN</command> to apply their patch, 26.578 - followed by <command role="hg-cmd">hg addremove</command> to 26.579 - pick up any files added or removed by the patch, followed by 26.580 - <command role="hg-ext-mq">hg qrefresh</command>. This 26.581 - complexity may become unnecessary; see <ulink role="hg-bug" 26.582 - url="http://www.selenic.com/mercurial/bts/issue311">issue 26.583 - 311</ulink> for details. 26.584 - </para> 26.585 - </sect2> 26.586 - <sect2> 26.587 - <title>Strategies for applying a patch</title> 26.588 - 26.589 - <para>When <command>patch</command> applies a hunk, it tries a 26.590 - handful of successively less accurate strategies to try to 26.591 - make the hunk apply. This falling-back technique often makes 26.592 - it possible to take a patch that was generated against an old 26.593 - version of a file, and apply it against a newer version of 26.594 - that file.</para> 26.595 - 26.596 - <para>First, <command>patch</command> tries an exact match, 26.597 - where the line numbers, the context, and the text to be 26.598 - modified must apply exactly. If it cannot make an exact 26.599 - match, it tries to find an exact match for the context, 26.600 - without honouring the line numbering information. If this 26.601 - succeeds, it prints a line of output saying that the hunk was 26.602 - applied, but at some <emphasis>offset</emphasis> from the 26.603 - original line number.</para> 26.604 - 26.605 - <para>If a context-only match fails, <command>patch</command> 26.606 - removes the first and last lines of the context, and tries a 26.607 - <emphasis>reduced</emphasis> context-only match. If the hunk 26.608 - with reduced context succeeds, it prints a message saying that 26.609 - it applied the hunk with a <emphasis>fuzz factor</emphasis> 26.610 - (the number after the fuzz factor indicates how many lines of 26.611 - context <command>patch</command> had to trim before the patch 26.612 - applied).</para> 26.613 - 26.614 - <para>When neither of these techniques works, 26.615 - <command>patch</command> prints a message saying that the hunk 26.616 - in question was rejected. It saves rejected hunks (also 26.617 - simply called <quote>rejects</quote>) to a file with the same 26.618 - name, and an added <filename role="special">.rej</filename> 26.619 - extension. It also saves an unmodified copy of the file with 26.620 - a <filename role="special">.orig</filename> extension; the 26.621 - copy of the file without any extensions will contain any 26.622 - changes made by hunks that <emphasis>did</emphasis> apply 26.623 - cleanly. If you have a patch that modifies 26.624 - <filename>foo</filename> with six hunks, and one of them fails 26.625 - to apply, you will have: an unmodified 26.626 - <filename>foo.orig</filename>, a <filename>foo.rej</filename> 26.627 - containing one hunk, and <filename>foo</filename>, containing 26.628 - the changes made by the five successful hunks.</para> 26.629 - 26.630 - </sect2> 26.631 - <sect2> 26.632 - <title>Some quirks of patch representation</title> 26.633 - 26.634 - <para>There are a few useful things to know about how 26.635 - <command>patch</command> works with files.</para> 26.636 - <itemizedlist> 26.637 - <listitem><para>This should already be obvious, but 26.638 - <command>patch</command> cannot handle binary 26.639 - files.</para> 26.640 - </listitem> 26.641 - <listitem><para>Neither does it care about the executable bit; 26.642 - it creates new files as readable, but not 26.643 - executable.</para> 26.644 - </listitem> 26.645 - <listitem><para><command>patch</command> treats the removal of 26.646 - a file as a diff between the file to be removed and the 26.647 - empty file. So your idea of <quote>I deleted this 26.648 - file</quote> looks like <quote>every line of this file 26.649 - was deleted</quote> in a patch.</para> 26.650 - </listitem> 26.651 - <listitem><para>It treats the addition of a file as a diff 26.652 - between the empty file and the file to be added. So in a 26.653 - patch, your idea of <quote>I added this file</quote> looks 26.654 - like <quote>every line of this file was 26.655 - added</quote>.</para> 26.656 - </listitem> 26.657 - <listitem><para>It treats a renamed file as the removal of the 26.658 - old name, and the addition of the new name. This means 26.659 - that renamed files have a big footprint in patches. (Note 26.660 - also that Mercurial does not currently try to infer when 26.661 - files have been renamed or copied in a patch.)</para> 26.662 - </listitem> 26.663 - <listitem><para><command>patch</command> cannot represent 26.664 - empty files, so you cannot use a patch to represent the 26.665 - notion <quote>I added this empty file to the 26.666 - tree</quote>.</para> 26.667 - </listitem></itemizedlist> 26.668 - </sect2> 26.669 - <sect2> 26.670 - <title>Beware the fuzz</title> 26.671 - 26.672 - <para>While applying a hunk at an offset, or with a fuzz factor, 26.673 - will often be completely successful, these inexact techniques 26.674 - naturally leave open the possibility of corrupting the patched 26.675 - file. The most common cases typically involve applying a 26.676 - patch twice, or at an incorrect location in the file. If 26.677 - <command>patch</command> or <command 26.678 - role="hg-ext-mq">qpush</command> ever mentions an offset or 26.679 - fuzz factor, you should make sure that the modified files are 26.680 - correct afterwards.</para> 26.681 - 26.682 - <para>It's often a good idea to refresh a patch that has applied 26.683 - with an offset or fuzz factor; refreshing the patch generates 26.684 - new context information that will make it apply cleanly. I 26.685 - say <quote>often,</quote> not <quote>always,</quote> because 26.686 - sometimes refreshing a patch will make it fail to apply 26.687 - against a different revision of the underlying files. In some 26.688 - cases, such as when you're maintaining a patch that must sit 26.689 - on top of multiple versions of a source tree, it's acceptable 26.690 - to have a patch apply with some fuzz, provided you've verified 26.691 - the results of the patching process in such cases.</para> 26.692 - 26.693 - </sect2> 26.694 - <sect2> 26.695 - <title>Handling rejection</title> 26.696 - 26.697 - <para>If <command role="hg-ext-mq">qpush</command> fails to 26.698 - apply a patch, it will print an error message and exit. If it 26.699 - has left <filename role="special">.rej</filename> files 26.700 - behind, it is usually best to fix up the rejected hunks before 26.701 - you push more patches or do any further work.</para> 26.702 - 26.703 - <para>If your patch <emphasis>used to</emphasis> apply cleanly, 26.704 - and no longer does because you've changed the underlying code 26.705 - that your patches are based on, Mercurial Queues can help; see 26.706 - section <xref 26.707 - linkend="sec:mq:merge"/> for details.</para> 26.708 - 26.709 - <para>Unfortunately, there aren't any great techniques for 26.710 - dealing with rejected hunks. Most often, you'll need to view 26.711 - the <filename role="special">.rej</filename> file and edit the 26.712 - target file, applying the rejected hunks by hand.</para> 26.713 - 26.714 - <para>If you're feeling adventurous, Neil Brown, a Linux kernel 26.715 - hacker, wrote a tool called <command>wiggle</command> 26.716 - <citation>web:wiggle</citation>, which is more vigorous than 26.717 - <command>patch</command> in its attempts to make a patch 26.718 - apply.</para> 26.719 - 26.720 - <para>Another Linux kernel hacker, Chris Mason (the author of 26.721 - Mercurial Queues), wrote a similar tool called 26.722 - <command>mpatch</command> <citation>web:mpatch</citation>, 26.723 - which takes a simple approach to automating the application of 26.724 - hunks rejected by <command>patch</command>. The 26.725 - <command>mpatch</command> command can help with four common 26.726 - reasons that a hunk may be rejected:</para> 26.727 - 26.728 - <itemizedlist> 26.729 - <listitem><para>The context in the middle of a hunk has 26.730 - changed.</para> 26.731 - </listitem> 26.732 - <listitem><para>A hunk is missing some context at the 26.733 - beginning or end.</para> 26.734 - </listitem> 26.735 - <listitem><para>A large hunk might apply better&emdash;either 26.736 - entirely or in part&emdash;if it was broken up into 26.737 - smaller hunks.</para> 26.738 - </listitem> 26.739 - <listitem><para>A hunk removes lines with slightly different 26.740 - content than those currently present in the file.</para> 26.741 - </listitem></itemizedlist> 26.742 - 26.743 - <para>If you use <command>wiggle</command> or 26.744 - <command>mpatch</command>, you should be doubly careful to 26.745 - check your results when you're done. In fact, 26.746 - <command>mpatch</command> enforces this method of 26.747 - double-checking the tool's output, by automatically dropping 26.748 - you into a merge program when it has done its job, so that you 26.749 - can verify its work and finish off any remaining 26.750 - merges.</para> 26.751 - 26.752 - </sect2> 26.753 - </sect1> 26.754 - <sect1 id="sec:mq:perf"> 26.755 - <title>Getting the best performance out of MQ</title> 26.756 - 26.757 - <para>MQ is very efficient at handling a large number of patches. 26.758 - I ran some performance experiments in mid-2006 for a talk that I 26.759 - gave at the 2006 EuroPython conference 26.760 - <citation>web:europython</citation>. I used as my data set the 26.761 - Linux 2.6.17-mm1 patch series, which consists of 1,738 patches. 26.762 - I applied these on top of a Linux kernel repository containing 26.763 - all 27,472 revisions between Linux 2.6.12-rc2 and Linux 26.764 - 2.6.17.</para> 26.765 - 26.766 - <para>On my old, slow laptop, I was able to <command 26.767 - role="hg-cmd">hg qpush <option 26.768 - role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all 26.769 - 1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop 26.770 - <option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> 26.771 - them all in 30 seconds. (On a newer laptop, the time to push 26.772 - all patches dropped to two minutes.) I could <command 26.773 - role="hg-ext-mq">qrefresh</command> one of the biggest patches 26.774 - (which made 22,779 lines of changes to 287 files) in 6.6 26.775 - seconds.</para> 26.776 - 26.777 - <para>Clearly, MQ is well suited to working in large trees, but 26.778 - there are a few tricks you can use to get the best performance 26.779 - of it.</para> 26.780 - 26.781 - <para>First of all, try to <quote>batch</quote> operations 26.782 - together. Every time you run <command 26.783 - role="hg-ext-mq">qpush</command> or <command 26.784 - role="hg-ext-mq">qpop</command>, these commands scan the 26.785 - working directory once to make sure you haven't made some 26.786 - changes and then forgotten to run <command 26.787 - role="hg-ext-mq">qrefresh</command>. On a small tree, the 26.788 - time that this scan takes is unnoticeable. However, on a 26.789 - medium-sized tree (containing tens of thousands of files), it 26.790 - can take a second or more.</para> 26.791 - 26.792 - <para>The <command role="hg-ext-mq">qpush</command> and <command 26.793 - role="hg-ext-mq">qpop</command> commands allow you to push and 26.794 - pop multiple patches at a time. You can identify the 26.795 - <quote>destination patch</quote> that you want to end up at. 26.796 - When you <command role="hg-ext-mq">qpush</command> with a 26.797 - destination specified, it will push patches until that patch is 26.798 - at the top of the applied stack. When you <command 26.799 - role="hg-ext-mq">qpop</command> to a destination, MQ will pop 26.800 - patches until the destination patch is at the top.</para> 26.801 - 26.802 - <para>You can identify a destination patch using either the name 26.803 - of the patch, or by number. If you use numeric addressing, 26.804 - patches are counted from zero; this means that the first patch 26.805 - is zero, the second is one, and so on.</para> 26.806 - 26.807 - </sect1> 26.808 - <sect1 id="sec:mq:merge"> 26.809 - <title>Updating your patches when the underlying code 26.810 - changes</title> 26.811 - 26.812 - <para>It's common to have a stack of patches on top of an 26.813 - underlying repository that you don't modify directly. If you're 26.814 - working on changes to third-party code, or on a feature that is 26.815 - taking longer to develop than the rate of change of the code 26.816 - beneath, you will often need to sync up with the underlying 26.817 - code, and fix up any hunks in your patches that no longer apply. 26.818 - This is called <emphasis>rebasing</emphasis> your patch 26.819 - series.</para> 26.820 - 26.821 - <para>The simplest way to do this is to <command role="hg-cmd">hg 26.822 - qpop <option role="hg-ext-mq-cmd-qpop-opt">hg 26.823 - -a</option></command> your patches, then <command 26.824 - role="hg-cmd">hg pull</command> changes into the underlying 26.825 - repository, and finally <command role="hg-cmd">hg qpush <option 26.826 - role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your 26.827 - patches again. MQ will stop pushing any time it runs across a 26.828 - patch that fails to apply during conflicts, allowing you to fix 26.829 - your conflicts, <command role="hg-ext-mq">qrefresh</command> the 26.830 - affected patch, and continue pushing until you have fixed your 26.831 - entire stack.</para> 26.832 - 26.833 - <para>This approach is easy to use and works well if you don't 26.834 - expect changes to the underlying code to affect how well your 26.835 - patches apply. If your patch stack touches code that is modified 26.836 - frequently or invasively in the underlying repository, however, 26.837 - fixing up rejected hunks by hand quickly becomes 26.838 - tiresome.</para> 26.839 - 26.840 - <para>It's possible to partially automate the rebasing process. 26.841 - If your patches apply cleanly against some revision of the 26.842 - underlying repo, MQ can use this information to help you to 26.843 - resolve conflicts between your patches and a different 26.844 - revision.</para> 26.845 - 26.846 - <para>The process is a little involved.</para> 26.847 - <orderedlist> 26.848 - <listitem><para>To begin, <command role="hg-cmd">hg qpush 26.849 - -a</command> all of your patches on top of the revision 26.850 - where you know that they apply cleanly.</para> 26.851 - </listitem> 26.852 - <listitem><para>Save a backup copy of your patch directory using 26.853 - <command role="hg-cmd">hg qsave <option 26.854 - role="hg-ext-mq-cmd-qsave-opt">hg -e</option> <option 26.855 - role="hg-ext-mq-cmd-qsave-opt">hg -c</option></command>. 26.856 - This prints the name of the directory that it has saved the 26.857 - patches in. It will save the patches to a directory called 26.858 - <filename role="special" 26.859 - class="directory">.hg/patches.N</filename>, where 26.860 - <literal>N</literal> is a small integer. It also commits a 26.861 - <quote>save changeset</quote> on top of your applied 26.862 - patches; this is for internal book-keeping, and records the 26.863 - states of the <filename role="special">series</filename> and 26.864 - <filename role="special">status</filename> files.</para> 26.865 - </listitem> 26.866 - <listitem><para>Use <command role="hg-cmd">hg pull</command> to 26.867 - bring new changes into the underlying repository. (Don't 26.868 - run <command role="hg-cmd">hg pull -u</command>; see below 26.869 - for why.)</para> 26.870 - </listitem> 26.871 - <listitem><para>Update to the new tip revision, using <command 26.872 - role="hg-cmd">hg update <option 26.873 - role="hg-opt-update">-C</option></command> to override 26.874 - the patches you have pushed.</para> 26.875 - </listitem> 26.876 - <listitem><para>Merge all patches using <command>hg qpush -m 26.877 - -a</command>. The <option 26.878 - role="hg-ext-mq-cmd-qpush-opt">-m</option> option to 26.879 - <command role="hg-ext-mq">qpush</command> tells MQ to 26.880 - perform a three-way merge if the patch fails to 26.881 - apply.</para> 26.882 - </listitem></orderedlist> 26.883 - 26.884 - <para>During the <command role="hg-cmd">hg qpush <option 26.885 - role="hg-ext-mq-cmd-qpush-opt">hg -m</option></command>, 26.886 - each patch in the <filename role="special">series</filename> 26.887 - file is applied normally. If a patch applies with fuzz or 26.888 - rejects, MQ looks at the queue you <command 26.889 - role="hg-ext-mq">qsave</command>d, and performs a three-way 26.890 - merge with the corresponding changeset. This merge uses 26.891 - Mercurial's normal merge machinery, so it may pop up a GUI merge 26.892 - tool to help you to resolve problems.</para> 26.893 - 26.894 - <para>When you finish resolving the effects of a patch, MQ 26.895 - refreshes your patch based on the result of the merge.</para> 26.896 - 26.897 - <para>At the end of this process, your repository will have one 26.898 - extra head from the old patch queue, and a copy of the old patch 26.899 - queue will be in <filename role="special" 26.900 - class="directory">.hg/patches.N</filename>. You can remove the 26.901 - extra head using <command role="hg-cmd">hg qpop -a -n 26.902 - patches.N</command> or <command role="hg-cmd">hg 26.903 - strip</command>. You can delete <filename role="special" 26.904 - class="directory">.hg/patches.N</filename> once you are sure 26.905 - that you no longer need it as a backup.</para> 26.906 - 26.907 - </sect1> 26.908 - <sect1> 26.909 - <title>Identifying patches</title> 26.910 - 26.911 - <para>MQ commands that work with patches let you refer to a patch 26.912 - either by using its name or by a number. By name is obvious 26.913 - enough; pass the name <filename>foo.patch</filename> to <command 26.914 - role="hg-ext-mq">qpush</command>, for example, and it will 26.915 - push patches until <filename>foo.patch</filename> is 26.916 - applied.</para> 26.917 - 26.918 - <para>As a shortcut, you can refer to a patch using both a name 26.919 - and a numeric offset; <literal>foo.patch-2</literal> means 26.920 - <quote>two patches before <literal>foo.patch</literal></quote>, 26.921 - while <literal>bar.patch+4</literal> means <quote>four patches 26.922 - after <literal>bar.patch</literal></quote>.</para> 26.923 - 26.924 - <para>Referring to a patch by index isn't much different. The 26.925 - first patch printed in the output of <command 26.926 - role="hg-ext-mq">qseries</command> is patch zero (yes, it's 26.927 - one of those start-at-zero counting systems); the second is 26.928 - patch one; and so on.</para> 26.929 - 26.930 - <para>MQ also makes it easy to work with patches when you are 26.931 - using normal Mercurial commands. Every command that accepts a 26.932 - changeset ID will also accept the name of an applied patch. MQ 26.933 - augments the tags normally in the repository with an eponymous 26.934 - one for each applied patch. In addition, the special tags 26.935 - <literal role="tag">qbase</literal> and 26.936 - <literal role="tag">qtip</literal> identify 26.937 - the <quote>bottom-most</quote> and topmost applied patches, 26.938 - respectively.</para> 26.939 - 26.940 - <para>These additions to Mercurial's normal tagging capabilities 26.941 - make dealing with patches even more of a breeze.</para> 26.942 - <itemizedlist> 26.943 - <listitem><para>Want to patchbomb a mailing list with your 26.944 - latest series of changes?</para> 26.945 - <programlisting>hg email qbase:qtip</programlisting> 26.946 - <para> (Don't know what <quote>patchbombing</quote> is? See 26.947 - section <xref linkend="sec:hgext:patchbomb"/>.)</para> 26.948 - </listitem> 26.949 - <listitem><para>Need to see all of the patches since 26.950 - <literal>foo.patch</literal> that have touched files in a 26.951 - subdirectory of your tree?</para> 26.952 - <programlisting>hg log -r foo.patch:qtip subdir</programlisting> 26.953 - </listitem> 26.954 - </itemizedlist> 26.955 - 26.956 - <para>Because MQ makes the names of patches available to the rest 26.957 - of Mercurial through its normal internal tag machinery, you 26.958 - don't need to type in the entire name of a patch when you want 26.959 - to identify it by name.</para> 26.960 - 26.961 - <para>Another nice consequence of representing patch names as tags 26.962 - is that when you run the <command role="hg-cmd">hg log</command> 26.963 - command, it will display a patch's name as a tag, simply as part 26.964 - of its normal output. This makes it easy to visually 26.965 - distinguish applied patches from underlying 26.966 - <quote>normal</quote> revisions. The following example shows a 26.967 - few normal Mercurial commands in use with applied 26.968 - patches.</para> 26.969 - 26.970 -&interaction.mq.id.output; 26.971 - 26.972 - </sect1> 26.973 - <sect1> 26.974 - <title>Useful things to know about</title> 26.975 - 26.976 - <para>There are a number of aspects of MQ usage that don't fit 26.977 - tidily into sections of their own, but that are good to know. 26.978 - Here they are, in one place.</para> 26.979 - 26.980 - <itemizedlist> 26.981 - <listitem><para>Normally, when you <command 26.982 - role="hg-ext-mq">qpop</command> a patch and <command 26.983 - role="hg-ext-mq">qpush</command> it again, the changeset 26.984 - that represents the patch after the pop/push will have a 26.985 - <emphasis>different identity</emphasis> than the changeset 26.986 - that represented the hash beforehand. See section <xref 26.987 - linkend="sec:mqref:cmd:qpush"/> for 26.988 - information as to why this is.</para> 26.989 - </listitem> 26.990 - <listitem><para>It's not a good idea to <command 26.991 - role="hg-cmd">hg merge</command> changes from another 26.992 - branch with a patch changeset, at least if you want to 26.993 - maintain the <quote>patchiness</quote> of that changeset and 26.994 - changesets below it on the patch stack. If you try to do 26.995 - this, it will appear to succeed, but MQ will become 26.996 - confused.</para> 26.997 - </listitem></itemizedlist> 26.998 - 26.999 - </sect1> 26.1000 - <sect1 id="sec:mq:repo"> 26.1001 - <title>Managing patches in a repository</title> 26.1002 - 26.1003 - <para>Because MQ's <filename role="special" 26.1004 - class="directory">.hg/patches</filename> directory resides 26.1005 - outside a Mercurial repository's working directory, the 26.1006 - <quote>underlying</quote> Mercurial repository knows nothing 26.1007 - about the management or presence of patches.</para> 26.1008 - 26.1009 - <para>This presents the interesting possibility of managing the 26.1010 - contents of the patch directory as a Mercurial repository in its 26.1011 - own right. This can be a useful way to work. For example, you 26.1012 - can work on a patch for a while, <command 26.1013 - role="hg-ext-mq">qrefresh</command> it, then <command 26.1014 - role="hg-cmd">hg commit</command> the current state of the 26.1015 - patch. This lets you <quote>roll back</quote> to that version 26.1016 - of the patch later on.</para> 26.1017 - 26.1018 - <para>You can then share different versions of the same patch 26.1019 - stack among multiple underlying repositories. I use this when I 26.1020 - am developing a Linux kernel feature. I have a pristine copy of 26.1021 - my kernel sources for each of several CPU architectures, and a 26.1022 - cloned repository under each that contains the patches I am 26.1023 - working on. When I want to test a change on a different 26.1024 - architecture, I push my current patches to the patch repository 26.1025 - associated with that kernel tree, pop and push all of my 26.1026 - patches, and build and test that kernel.</para> 26.1027 - 26.1028 - <para>Managing patches in a repository makes it possible for 26.1029 - multiple developers to work on the same patch series without 26.1030 - colliding with each other, all on top of an underlying source 26.1031 - base that they may or may not control.</para> 26.1032 - 26.1033 - <sect2> 26.1034 - <title>MQ support for patch repositories</title> 26.1035 - 26.1036 - <para>MQ helps you to work with the <filename role="special" 26.1037 - class="directory">.hg/patches</filename> directory as a 26.1038 - repository; when you prepare a repository for working with 26.1039 - patches using <command role="hg-ext-mq">qinit</command>, you 26.1040 - can pass the <option role="hg-ext-mq-cmd-qinit-opt">hg 26.1041 - -c</option> option to create the <filename role="special" 26.1042 - class="directory">.hg/patches</filename> directory as a 26.1043 - Mercurial repository.</para> 26.1044 - 26.1045 - <note> 26.1046 - <para> If you forget to use the <option 26.1047 - role="hg-ext-mq-cmd-qinit-opt">hg -c</option> option, you 26.1048 - can simply go into the <filename role="special" 26.1049 - class="directory">.hg/patches</filename> directory at any 26.1050 - time and run <command role="hg-cmd">hg init</command>. 26.1051 - Don't forget to add an entry for the <filename 26.1052 - role="special">status</filename> file to the <filename 26.1053 - role="special">.hgignore</filename> file, though</para> 26.1054 - 26.1055 - <para> (<command role="hg-cmd">hg qinit <option 26.1056 - role="hg-ext-mq-cmd-qinit-opt">hg -c</option></command> 26.1057 - does this for you automatically); you 26.1058 - <emphasis>really</emphasis> don't want to manage the 26.1059 - <filename role="special">status</filename> file.</para> 26.1060 - </note> 26.1061 - 26.1062 - <para>As a convenience, if MQ notices that the <filename 26.1063 - class="directory">.hg/patches</filename> directory is a 26.1064 - repository, it will automatically <command role="hg-cmd">hg 26.1065 - add</command> every patch that you create and import.</para> 26.1066 - 26.1067 - <para>MQ provides a shortcut command, <command 26.1068 - role="hg-ext-mq">qcommit</command>, that runs <command 26.1069 - role="hg-cmd">hg commit</command> in the <filename 26.1070 - role="special" class="directory">.hg/patches</filename> 26.1071 - directory. This saves some bothersome typing.</para> 26.1072 - 26.1073 - <para>Finally, as a convenience to manage the patch directory, 26.1074 - you can define the alias <command>mq</command> on Unix 26.1075 - systems. For example, on Linux systems using the 26.1076 - <command>bash</command> shell, you can include the following 26.1077 - snippet in your <filename 26.1078 - role="home">~/.bashrc</filename>.</para> 26.1079 - 26.1080 - <programlisting>alias mq=`hg -R $(hg root)/.hg/patches'</programlisting> 26.1081 - 26.1082 - <para>You can then issue commands of the form <command>mq 26.1083 - pull</command> from the main repository.</para> 26.1084 - 26.1085 - </sect2> 26.1086 - <sect2> 26.1087 - <title>A few things to watch out for</title> 26.1088 - 26.1089 - <para>MQ's support for working with a repository full of patches 26.1090 - is limited in a few small respects.</para> 26.1091 - 26.1092 - <para>MQ cannot automatically detect changes that you make to 26.1093 - the patch directory. If you <command role="hg-cmd">hg 26.1094 - pull</command>, manually edit, or <command role="hg-cmd">hg 26.1095 - update</command> changes to patches or the <filename 26.1096 - role="special">series</filename> file, you will have to 26.1097 - <command role="hg-cmd">hg qpop <option 26.1098 - role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and 26.1099 - then <command role="hg-cmd">hg qpush <option 26.1100 - role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in 26.1101 - the underlying repository to see those changes show up there. 26.1102 - If you forget to do this, you can confuse MQ's idea of which 26.1103 - patches are applied.</para> 26.1104 - 26.1105 - </sect2> 26.1106 - </sect1> 26.1107 - <sect1 id="sec:mq:tools"> 26.1108 - <title>Third party tools for working with patches</title> 26.1109 - 26.1110 - <para>Once you've been working with patches for a while, you'll 26.1111 - find yourself hungry for tools that will help you to understand 26.1112 - and manipulate the patches you're dealing with.</para> 26.1113 - 26.1114 - <para>The <command>diffstat</command> command 26.1115 - <citation>web:diffstat</citation> generates a histogram of the 26.1116 - modifications made to each file in a patch. It provides a good 26.1117 - way to <quote>get a sense of</quote> a patch&emdash;which files 26.1118 - it affects, and how much change it introduces to each file and 26.1119 - as a whole. (I find that it's a good idea to use 26.1120 - <command>diffstat</command>'s <option 26.1121 - role="cmd-opt-diffstat">-p</option> option as a matter of 26.1122 - course, as otherwise it will try to do clever things with 26.1123 - prefixes of file names that inevitably confuse at least 26.1124 - me.)</para> 26.1125 - 26.1126 -&interaction.mq.tools.tools; 26.1127 - 26.1128 - <para>The <literal role="package">patchutils</literal> package 26.1129 - <citation>web:patchutils</citation> is invaluable. It provides a 26.1130 - set of small utilities that follow the <quote>Unix 26.1131 - philosophy;</quote> each does one useful thing with a patch. 26.1132 - The <literal role="package">patchutils</literal> command I use 26.1133 - most is <command>filterdiff</command>, which extracts subsets 26.1134 - from a patch file. For example, given a patch that modifies 26.1135 - hundreds of files across dozens of directories, a single 26.1136 - invocation of <command>filterdiff</command> can generate a 26.1137 - smaller patch that only touches files whose names match a 26.1138 - particular glob pattern. See section <xref 26.1139 - linkend="mq-collab:tips:interdiff"/> for another 26.1140 - example.</para> 26.1141 - 26.1142 - </sect1> 26.1143 - <sect1> 26.1144 - <title>Good ways to work with patches</title> 26.1145 - 26.1146 - <para>Whether you are working on a patch series to submit to a 26.1147 - free software or open source project, or a series that you 26.1148 - intend to treat as a sequence of regular changesets when you're 26.1149 - done, you can use some simple techniques to keep your work well 26.1150 - organised.</para> 26.1151 - 26.1152 - <para>Give your patches descriptive names. A good name for a 26.1153 - patch might be <filename>rework-device-alloc.patch</filename>, 26.1154 - because it will immediately give you a hint what the purpose of 26.1155 - the patch is. Long names shouldn't be a problem; you won't be 26.1156 - typing the names often, but you <emphasis>will</emphasis> be 26.1157 - running commands like <command 26.1158 - role="hg-ext-mq">qapplied</command> and <command 26.1159 - role="hg-ext-mq">qtop</command> over and over. Good naming 26.1160 - becomes especially important when you have a number of patches 26.1161 - to work with, or if you are juggling a number of different tasks 26.1162 - and your patches only get a fraction of your attention.</para> 26.1163 - 26.1164 - <para>Be aware of what patch you're working on. Use the <command 26.1165 - role="hg-ext-mq">qtop</command> command and skim over the text 26.1166 - of your patches frequently&emdash;for example, using <command 26.1167 - role="hg-cmd">hg tip <option 26.1168 - role="hg-opt-tip">-p</option></command>)&emdash;to be sure 26.1169 - of where you stand. I have several times worked on and <command 26.1170 - role="hg-ext-mq">qrefresh</command>ed a patch other than the 26.1171 - one I intended, and it's often tricky to migrate changes into 26.1172 - the right patch after making them in the wrong one.</para> 26.1173 - 26.1174 - <para>For this reason, it is very much worth investing a little 26.1175 - time to learn how to use some of the third-party tools I 26.1176 - described in section <xref linkend="sec:mq:tools"/>, 26.1177 - particularly 26.1178 - <command>diffstat</command> and <command>filterdiff</command>. 26.1179 - The former will give you a quick idea of what changes your patch 26.1180 - is making, while the latter makes it easy to splice hunks 26.1181 - selectively out of one patch and into another.</para> 26.1182 - 26.1183 - </sect1> 26.1184 - <sect1> 26.1185 - <title>MQ cookbook</title> 26.1186 - 26.1187 - <sect2> 26.1188 - <title>Manage <quote>trivial</quote> patches</title> 26.1189 - 26.1190 - <para>Because the overhead of dropping files into a new 26.1191 - Mercurial repository is so low, it makes a lot of sense to 26.1192 - manage patches this way even if you simply want to make a few 26.1193 - changes to a source tarball that you downloaded.</para> 26.1194 - 26.1195 - <para>Begin by downloading and unpacking the source tarball, and 26.1196 - turning it into a Mercurial repository.</para> 26.1197 - 26.1198 - &interaction.mq.tarball.download; 26.1199 - 26.1200 - <para>Continue by creating a patch stack and making your 26.1201 - changes.</para> 26.1202 - 26.1203 - &interaction.mq.tarball.qinit; 26.1204 - 26.1205 - <para>Let's say a few weeks or months pass, and your package 26.1206 - author releases a new version. First, bring their changes 26.1207 - into the repository.</para> 26.1208 - 26.1209 - &interaction.mq.tarball.newsource; 26.1210 - 26.1211 - <para>The pipeline starting with <command role="hg-cmd">hg 26.1212 - locate</command> above deletes all files in the working 26.1213 - directory, so that <command role="hg-cmd">hg 26.1214 - commit</command>'s <option 26.1215 - role="hg-opt-commit">--addremove</option> option can 26.1216 - actually tell which files have really been removed in the 26.1217 - newer version of the source.</para> 26.1218 - 26.1219 - <para>Finally, you can apply your patches on top of the new 26.1220 - tree.</para> 26.1221 - 26.1222 - &interaction.mq.tarball.repush; 26.1223 - 26.1224 - </sect2> 26.1225 - <sect2 id="sec:mq:combine"> 26.1226 - <title>Combining entire patches</title> 26.1227 - 26.1228 - <para>MQ provides a command, <command 26.1229 - role="hg-ext-mq">qfold</command> that lets you combine 26.1230 - entire patches. This <quote>folds</quote> the patches you 26.1231 - name, in the order you name them, into the topmost applied 26.1232 - patch, and concatenates their descriptions onto the end of its 26.1233 - description. The patches that you fold must be unapplied 26.1234 - before you fold them.</para> 26.1235 - 26.1236 - <para>The order in which you fold patches matters. If your 26.1237 - topmost applied patch is <literal>foo</literal>, and you 26.1238 - <command role="hg-ext-mq">qfold</command> 26.1239 - <literal>bar</literal> and <literal>quux</literal> into it, 26.1240 - you will end up with a patch that has the same effect as if 26.1241 - you applied first <literal>foo</literal>, then 26.1242 - <literal>bar</literal>, followed by 26.1243 - <literal>quux</literal>.</para> 26.1244 - 26.1245 - </sect2> 26.1246 - <sect2> 26.1247 - <title>Merging part of one patch into another</title> 26.1248 - 26.1249 - <para>Merging <emphasis>part</emphasis> of one patch into 26.1250 - another is more difficult than combining entire 26.1251 - patches.</para> 26.1252 - 26.1253 - <para>If you want to move changes to entire files, you can use 26.1254 - <command>filterdiff</command>'s <option 26.1255 - role="cmd-opt-filterdiff">-i</option> and <option 26.1256 - role="cmd-opt-filterdiff">-x</option> options to choose the 26.1257 - modifications to snip out of one patch, concatenating its 26.1258 - output onto the end of the patch you want to merge into. You 26.1259 - usually won't need to modify the patch you've merged the 26.1260 - changes from. Instead, MQ will report some rejected hunks 26.1261 - when you <command role="hg-ext-mq">qpush</command> it (from 26.1262 - the hunks you moved into the other patch), and you can simply 26.1263 - <command role="hg-ext-mq">qrefresh</command> the patch to drop 26.1264 - the duplicate hunks.</para> 26.1265 - 26.1266 - <para>If you have a patch that has multiple hunks modifying a 26.1267 - file, and you only want to move a few of those hunks, the job 26.1268 - becomes more messy, but you can still partly automate it. Use 26.1269 - <command>lsdiff -nvv</command> to print some metadata about 26.1270 - the patch.</para> 26.1271 - 26.1272 - &interaction.mq.tools.lsdiff; 26.1273 - 26.1274 - <para>This command prints three different kinds of 26.1275 - number:</para> 26.1276 - <itemizedlist> 26.1277 - <listitem><para>(in the first column) a <emphasis>file 26.1278 - number</emphasis> to identify each file modified in the 26.1279 - patch;</para> 26.1280 - </listitem> 26.1281 - <listitem><para>(on the next line, indented) the line number 26.1282 - within a modified file where a hunk starts; and</para> 26.1283 - </listitem> 26.1284 - <listitem><para>(on the same line) a <emphasis>hunk 26.1285 - number</emphasis> to identify that hunk.</para> 26.1286 - </listitem></itemizedlist> 26.1287 - 26.1288 - <para>You'll have to use some visual inspection, and reading of 26.1289 - the patch, to identify the file and hunk numbers you'll want, 26.1290 - but you can then pass them to to 26.1291 - <command>filterdiff</command>'s <option 26.1292 - role="cmd-opt-filterdiff">--files</option> and <option 26.1293 - role="cmd-opt-filterdiff">--hunks</option> options, to 26.1294 - select exactly the file and hunk you want to extract.</para> 26.1295 - 26.1296 - <para>Once you have this hunk, you can concatenate it onto the 26.1297 - end of your destination patch and continue with the remainder 26.1298 - of section <xref linkend="sec:mq:combine"/>.</para> 26.1299 - 26.1300 - </sect2> 26.1301 - </sect1> 26.1302 - <sect1> 26.1303 - <title>Differences between quilt and MQ</title> 26.1304 - 26.1305 - <para>If you are already familiar with quilt, MQ provides a 26.1306 - similar command set. There are a few differences in the way 26.1307 - that it works.</para> 26.1308 - 26.1309 - <para>You will already have noticed that most quilt commands have 26.1310 - MQ counterparts that simply begin with a 26.1311 - <quote><literal>q</literal></quote>. The exceptions are quilt's 26.1312 - <literal>add</literal> and <literal>remove</literal> commands, 26.1313 - the counterparts for which are the normal Mercurial <command 26.1314 - role="hg-cmd">hg add</command> and <command role="hg-cmd">hg 26.1315 - remove</command> commands. There is no MQ equivalent of the 26.1316 - quilt <literal>edit</literal> command.</para> 26.1317 - 26.1318 - </sect1> 26.1319 -</chapter> 26.1320 - 26.1321 -<!-- 26.1322 -local variables: 26.1323 -sgml-parent-document: ("00book.xml" "book" "chapter") 26.1324 -end: 26.1325 --->
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/en/ch13-hgext.xml Thu Mar 19 20:54:12 2009 -0700 27.3 @@ -0,0 +1,554 @@ 27.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 27.5 + 27.6 +<chapter id="chap:hgext"> 27.7 + <?dbhtml filename="adding-functionality-with-extensions.html"?> 27.8 + <title>Adding functionality with extensions</title> 27.9 + 27.10 + <para>While the core of Mercurial is quite complete from a 27.11 + functionality standpoint, it's deliberately shorn of fancy 27.12 + features. This approach of preserving simplicity keeps the 27.13 + software easy to deal with for both maintainers and users.</para> 27.14 + 27.15 + <para>However, Mercurial doesn't box you in with an inflexible 27.16 + command set: you can add features to it as 27.17 + <emphasis>extensions</emphasis> (sometimes known as 27.18 + <emphasis>plugins</emphasis>). We've already discussed a few of 27.19 + these extensions in earlier chapters.</para> 27.20 + <itemizedlist> 27.21 + <listitem><para>Section <xref linkend="sec:tour-merge:fetch"/> 27.22 + covers the <literal role="hg-ext">fetch</literal> extension; 27.23 + this combines pulling new changes and merging them with local 27.24 + changes into a single command, <command 27.25 + role="hg-ext-fetch">fetch</command>.</para> 27.26 + </listitem> 27.27 + <listitem><para>In chapter <xref linkend="chap:hook"/>, we covered 27.28 + several extensions that are useful for hook-related 27.29 + functionality: <literal role="hg-ext">acl</literal> adds 27.30 + access control lists; <literal 27.31 + role="hg-ext">bugzilla</literal> adds integration with the 27.32 + Bugzilla bug tracking system; and <literal 27.33 + role="hg-ext">notify</literal> sends notification emails on 27.34 + new changes.</para> 27.35 + </listitem> 27.36 + <listitem><para>The Mercurial Queues patch management extension is 27.37 + so invaluable that it merits two chapters and an appendix all 27.38 + to itself. Chapter <xref linkend="chap:mq"/> covers the 27.39 + basics; chapter <xref 27.40 + linkend="chap:mq-collab"/> discusses advanced topics; 27.41 + and appendix <xref linkend="chap:mqref"/> goes into detail on 27.42 + each 27.43 + command.</para> 27.44 + </listitem></itemizedlist> 27.45 + 27.46 + <para>In this chapter, we'll cover some of the other extensions that 27.47 + are available for Mercurial, and briefly touch on some of the 27.48 + machinery you'll need to know about if you want to write an 27.49 + extension of your own.</para> 27.50 + <itemizedlist> 27.51 + <listitem><para>In section <xref linkend="sec:hgext:inotify"/>, 27.52 + we'll discuss the possibility of <emphasis>huge</emphasis> 27.53 + performance improvements using the <literal 27.54 + role="hg-ext">inotify</literal> extension.</para> 27.55 + </listitem></itemizedlist> 27.56 + 27.57 + <sect1 id="sec:hgext:inotify"> 27.58 + <title>Improve performance with the <literal 27.59 + role="hg-ext">inotify</literal> extension</title> 27.60 + 27.61 + <para>Are you interested in having some of the most common 27.62 + Mercurial operations run as much as a hundred times faster? 27.63 + Read on!</para> 27.64 + 27.65 + <para>Mercurial has great performance under normal circumstances. 27.66 + For example, when you run the <command role="hg-cmd">hg 27.67 + status</command> command, Mercurial has to scan almost every 27.68 + directory and file in your repository so that it can display 27.69 + file status. Many other Mercurial commands need to do the same 27.70 + work behind the scenes; for example, the <command 27.71 + role="hg-cmd">hg diff</command> command uses the status 27.72 + machinery to avoid doing an expensive comparison operation on 27.73 + files that obviously haven't changed.</para> 27.74 + 27.75 + <para>Because obtaining file status is crucial to good 27.76 + performance, the authors of Mercurial have optimised this code 27.77 + to within an inch of its life. However, there's no avoiding the 27.78 + fact that when you run <command role="hg-cmd">hg 27.79 + status</command>, Mercurial is going to have to perform at 27.80 + least one expensive system call for each managed file to 27.81 + determine whether it's changed since the last time Mercurial 27.82 + checked. For a sufficiently large repository, this can take a 27.83 + long time.</para> 27.84 + 27.85 + <para>To put a number on the magnitude of this effect, I created a 27.86 + repository containing 150,000 managed files. I timed <command 27.87 + role="hg-cmd">hg status</command> as taking ten seconds to 27.88 + run, even when <emphasis>none</emphasis> of those files had been 27.89 + modified.</para> 27.90 + 27.91 + <para>Many modern operating systems contain a file notification 27.92 + facility. If a program signs up to an appropriate service, the 27.93 + operating system will notify it every time a file of interest is 27.94 + created, modified, or deleted. On Linux systems, the kernel 27.95 + component that does this is called 27.96 + <literal>inotify</literal>.</para> 27.97 + 27.98 + <para>Mercurial's <literal role="hg-ext">inotify</literal> 27.99 + extension talks to the kernel's <literal>inotify</literal> 27.100 + component to optimise <command role="hg-cmd">hg status</command> 27.101 + commands. The extension has two components. A daemon sits in 27.102 + the background and receives notifications from the 27.103 + <literal>inotify</literal> subsystem. It also listens for 27.104 + connections from a regular Mercurial command. The extension 27.105 + modifies Mercurial's behaviour so that instead of scanning the 27.106 + filesystem, it queries the daemon. Since the daemon has perfect 27.107 + information about the state of the repository, it can respond 27.108 + with a result instantaneously, avoiding the need to scan every 27.109 + directory and file in the repository.</para> 27.110 + 27.111 + <para>Recall the ten seconds that I measured plain Mercurial as 27.112 + taking to run <command role="hg-cmd">hg status</command> on a 27.113 + 150,000 file repository. With the <literal 27.114 + role="hg-ext">inotify</literal> extension enabled, the time 27.115 + dropped to 0.1 seconds, a factor of <emphasis>one 27.116 + hundred</emphasis> faster.</para> 27.117 + 27.118 + <para>Before we continue, please pay attention to some 27.119 + caveats.</para> 27.120 + <itemizedlist> 27.121 + <listitem><para>The <literal role="hg-ext">inotify</literal> 27.122 + extension is Linux-specific. Because it interfaces directly 27.123 + to the Linux kernel's <literal>inotify</literal> subsystem, 27.124 + it does not work on other operating systems.</para> 27.125 + </listitem> 27.126 + <listitem><para>It should work on any Linux distribution that 27.127 + was released after early 2005. Older distributions are 27.128 + likely to have a kernel that lacks 27.129 + <literal>inotify</literal>, or a version of 27.130 + <literal>glibc</literal> that does not have the necessary 27.131 + interfacing support.</para> 27.132 + </listitem> 27.133 + <listitem><para>Not all filesystems are suitable for use with 27.134 + the <literal role="hg-ext">inotify</literal> extension. 27.135 + Network filesystems such as NFS are a non-starter, for 27.136 + example, particularly if you're running Mercurial on several 27.137 + systems, all mounting the same network filesystem. The 27.138 + kernel's <literal>inotify</literal> system has no way of 27.139 + knowing about changes made on another system. Most local 27.140 + filesystems (e.g. ext3, XFS, ReiserFS) should work 27.141 + fine.</para> 27.142 + </listitem></itemizedlist> 27.143 + 27.144 + <para>The <literal role="hg-ext">inotify</literal> extension is 27.145 + not yet shipped with Mercurial as of May 2007, so it's a little 27.146 + more involved to set up than other extensions. But the 27.147 + performance improvement is worth it!</para> 27.148 + 27.149 + <para>The extension currently comes in two parts: a set of patches 27.150 + to the Mercurial source code, and a library of Python bindings 27.151 + to the <literal>inotify</literal> subsystem.</para> 27.152 + <note> 27.153 + <para> There are <emphasis>two</emphasis> Python 27.154 + <literal>inotify</literal> binding libraries. One of them is 27.155 + called <literal>pyinotify</literal>, and is packaged by some 27.156 + Linux distributions as <literal>python-inotify</literal>. 27.157 + This is <emphasis>not</emphasis> the one you'll need, as it is 27.158 + too buggy and inefficient to be practical.</para> 27.159 + </note> 27.160 + <para>To get going, it's best to already have a functioning copy 27.161 + of Mercurial installed.</para> 27.162 + <note> 27.163 + <para> If you follow the instructions below, you'll be 27.164 + <emphasis>replacing</emphasis> and overwriting any existing 27.165 + installation of Mercurial that you might already have, using 27.166 + the latest <quote>bleeding edge</quote> Mercurial code. Don't 27.167 + say you weren't warned!</para> 27.168 + </note> 27.169 + <orderedlist> 27.170 + <listitem><para>Clone the Python <literal>inotify</literal> 27.171 + binding repository. Build and install it.</para> 27.172 + <programlisting>hg clone http://hg.kublai.com/python/inotify 27.173 +cd inotify 27.174 +python setup.py build --force 27.175 +sudo python setup.py install --skip-build</programlisting> 27.176 + </listitem> 27.177 + <listitem><para>Clone the <filename 27.178 + class="directory">crew</filename> Mercurial repository. 27.179 + Clone the <literal role="hg-ext">inotify</literal> patch 27.180 + repository so that Mercurial Queues will be able to apply 27.181 + patches to your cope of the <filename 27.182 + class="directory">crew</filename> repository.</para> 27.183 + <programlisting>hg clone http://hg.intevation.org/mercurial/crew 27.184 +hg clone crew inotify 27.185 +hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting> 27.186 + </listitem> 27.187 + <listitem><para>Make sure that you have the Mercurial Queues 27.188 + extension, <literal role="hg-ext">mq</literal>, enabled. If 27.189 + you've never used MQ, read section <xref 27.190 + linkend="sec:mq:start"/> to get started 27.191 + quickly.</para> 27.192 + </listitem> 27.193 + <listitem><para>Go into the <filename 27.194 + class="directory">inotify</filename> repo, and apply all 27.195 + of the <literal role="hg-ext">inotify</literal> patches 27.196 + using the <option role="hg-ext-mq-cmd-qpush-opt">hg 27.197 + -a</option> option to the <command 27.198 + role="hg-ext-mq">qpush</command> command.</para> 27.199 + <programlisting>cd inotify 27.200 +hg qpush -a</programlisting> 27.201 + </listitem> 27.202 + <listitem><para> If you get an error message from <command 27.203 + role="hg-ext-mq">qpush</command>, you should not continue. 27.204 + Instead, ask for help.</para> 27.205 + </listitem> 27.206 + <listitem><para>Build and install the patched version of 27.207 + Mercurial.</para> 27.208 + <programlisting>python setup.py build --force 27.209 +sudo python setup.py install --skip-build</programlisting> 27.210 + </listitem> 27.211 + </orderedlist> 27.212 + <para>Once you've build a suitably patched version of Mercurial, 27.213 + all you need to do to enable the <literal 27.214 + role="hg-ext">inotify</literal> extension is add an entry to 27.215 + your <filename role="special">~/.hgrc</filename>.</para> 27.216 + <programlisting>[extensions] inotify =</programlisting> 27.217 + <para>When the <literal role="hg-ext">inotify</literal> extension 27.218 + is enabled, Mercurial will automatically and transparently start 27.219 + the status daemon the first time you run a command that needs 27.220 + status in a repository. It runs one status daemon per 27.221 + repository.</para> 27.222 + 27.223 + <para>The status daemon is started silently, and runs in the 27.224 + background. If you look at a list of running processes after 27.225 + you've enabled the <literal role="hg-ext">inotify</literal> 27.226 + extension and run a few commands in different repositories, 27.227 + you'll thus see a few <literal>hg</literal> processes sitting 27.228 + around, waiting for updates from the kernel and queries from 27.229 + Mercurial.</para> 27.230 + 27.231 + <para>The first time you run a Mercurial command in a repository 27.232 + when you have the <literal role="hg-ext">inotify</literal> 27.233 + extension enabled, it will run with about the same performance 27.234 + as a normal Mercurial command. This is because the status 27.235 + daemon needs to perform a normal status scan so that it has a 27.236 + baseline against which to apply later updates from the kernel. 27.237 + However, <emphasis>every</emphasis> subsequent command that does 27.238 + any kind of status check should be noticeably faster on 27.239 + repositories of even fairly modest size. Better yet, the bigger 27.240 + your repository is, the greater a performance advantage you'll 27.241 + see. The <literal role="hg-ext">inotify</literal> daemon makes 27.242 + status operations almost instantaneous on repositories of all 27.243 + sizes!</para> 27.244 + 27.245 + <para>If you like, you can manually start a status daemon using 27.246 + the <command role="hg-ext-inotify">inserve</command> command. 27.247 + This gives you slightly finer control over how the daemon ought 27.248 + to run. This command will of course only be available when the 27.249 + <literal role="hg-ext">inotify</literal> extension is 27.250 + enabled.</para> 27.251 + 27.252 + <para>When you're using the <literal 27.253 + role="hg-ext">inotify</literal> extension, you should notice 27.254 + <emphasis>no difference at all</emphasis> in Mercurial's 27.255 + behaviour, with the sole exception of status-related commands 27.256 + running a whole lot faster than they used to. You should 27.257 + specifically expect that commands will not print different 27.258 + output; neither should they give different results. If either of 27.259 + these situations occurs, please report a bug.</para> 27.260 + 27.261 + </sect1> 27.262 + <sect1 id="sec:hgext:extdiff"> 27.263 + <title>Flexible diff support with the <literal 27.264 + role="hg-ext">extdiff</literal> extension</title> 27.265 + 27.266 + <para>Mercurial's built-in <command role="hg-cmd">hg 27.267 + diff</command> command outputs plaintext unified diffs.</para> 27.268 + 27.269 + &interaction.extdiff.diff; 27.270 + 27.271 + <para>If you would like to use an external tool to display 27.272 + modifications, you'll want to use the <literal 27.273 + role="hg-ext">extdiff</literal> extension. This will let you 27.274 + use, for example, a graphical diff tool.</para> 27.275 + 27.276 + <para>The <literal role="hg-ext">extdiff</literal> extension is 27.277 + bundled with Mercurial, so it's easy to set up. In the <literal 27.278 + role="rc-extensions">extensions</literal> section of your 27.279 + <filename role="special">~/.hgrc</filename>, simply add a 27.280 + one-line entry to enable the extension.</para> 27.281 + <programlisting>[extensions] 27.282 +extdiff =</programlisting> 27.283 + <para>This introduces a command named <command 27.284 + role="hg-ext-extdiff">extdiff</command>, which by default uses 27.285 + your system's <command>diff</command> command to generate a 27.286 + unified diff in the same form as the built-in <command 27.287 + role="hg-cmd">hg diff</command> command.</para> 27.288 + 27.289 + &interaction.extdiff.extdiff; 27.290 + 27.291 + <para>The result won't be exactly the same as with the built-in 27.292 + <command role="hg-cmd">hg diff</command> variations, because the 27.293 + output of <command>diff</command> varies from one system to 27.294 + another, even when passed the same options.</para> 27.295 + 27.296 + <para>As the <quote><literal>making snapshot</literal></quote> 27.297 + lines of output above imply, the <command 27.298 + role="hg-ext-extdiff">extdiff</command> command works by 27.299 + creating two snapshots of your source tree. The first snapshot 27.300 + is of the source revision; the second, of the target revision or 27.301 + working directory. The <command 27.302 + role="hg-ext-extdiff">extdiff</command> command generates 27.303 + these snapshots in a temporary directory, passes the name of 27.304 + each directory to an external diff viewer, then deletes the 27.305 + temporary directory. For efficiency, it only snapshots the 27.306 + directories and files that have changed between the two 27.307 + revisions.</para> 27.308 + 27.309 + <para>Snapshot directory names have the same base name as your 27.310 + repository. If your repository path is <filename 27.311 + class="directory">/quux/bar/foo</filename>, then <filename 27.312 + class="directory">foo</filename> will be the name of each 27.313 + snapshot directory. Each snapshot directory name has its 27.314 + changeset ID appended, if appropriate. If a snapshot is of 27.315 + revision <literal>a631aca1083f</literal>, the directory will be 27.316 + named <filename class="directory">foo.a631aca1083f</filename>. 27.317 + A snapshot of the working directory won't have a changeset ID 27.318 + appended, so it would just be <filename 27.319 + class="directory">foo</filename> in this example. To see what 27.320 + this looks like in practice, look again at the <command 27.321 + role="hg-ext-extdiff">extdiff</command> example above. Notice 27.322 + that the diff has the snapshot directory names embedded in its 27.323 + header.</para> 27.324 + 27.325 + <para>The <command role="hg-ext-extdiff">extdiff</command> command 27.326 + accepts two important options. The <option 27.327 + role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option 27.328 + lets you choose a program to view differences with, instead of 27.329 + <command>diff</command>. With the <option 27.330 + role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option, 27.331 + you can change the options that <command 27.332 + role="hg-ext-extdiff">extdiff</command> passes to the program 27.333 + (by default, these options are 27.334 + <quote><literal>-Npru</literal></quote>, which only make sense 27.335 + if you're running <command>diff</command>). In other respects, 27.336 + the <command role="hg-ext-extdiff">extdiff</command> command 27.337 + acts similarly to the built-in <command role="hg-cmd">hg 27.338 + diff</command> command: you use the same option names, syntax, 27.339 + and arguments to specify the revisions you want, the files you 27.340 + want, and so on.</para> 27.341 + 27.342 + <para>As an example, here's how to run the normal system 27.343 + <command>diff</command> command, getting it to generate context 27.344 + diffs (using the <option role="cmd-opt-diff">-c</option> option) 27.345 + instead of unified diffs, and five lines of context instead of 27.346 + the default three (passing <literal>5</literal> as the argument 27.347 + to the <option role="cmd-opt-diff">-C</option> option).</para> 27.348 + 27.349 + &interaction.extdiff.extdiff-ctx; 27.350 + 27.351 + <para>Launching a visual diff tool is just as easy. Here's how to 27.352 + launch the <command>kdiff3</command> viewer.</para> 27.353 + <programlisting>hg extdiff -p kdiff3 -o</programlisting> 27.354 + 27.355 + <para>If your diff viewing command can't deal with directories, 27.356 + you can easily work around this with a little scripting. For an 27.357 + example of such scripting in action with the <literal 27.358 + role="hg-ext">mq</literal> extension and the 27.359 + <command>interdiff</command> command, see section <xref 27.360 + linkend="mq-collab:tips:interdiff"/>.</para> 27.361 + 27.362 + <sect2> 27.363 + <title>Defining command aliases</title> 27.364 + 27.365 + <para>It can be cumbersome to remember the options to both the 27.366 + <command role="hg-ext-extdiff">extdiff</command> command and 27.367 + the diff viewer you want to use, so the <literal 27.368 + role="hg-ext">extdiff</literal> extension lets you define 27.369 + <emphasis>new</emphasis> commands that will invoke your diff 27.370 + viewer with exactly the right options.</para> 27.371 + 27.372 + <para>All you need to do is edit your <filename 27.373 + role="special">~/.hgrc</filename>, and add a section named 27.374 + <literal role="rc-extdiff">extdiff</literal>. Inside this 27.375 + section, you can define multiple commands. Here's how to add 27.376 + a <literal>kdiff3</literal> command. Once you've defined 27.377 + this, you can type <quote><literal>hg kdiff3</literal></quote> 27.378 + and the <literal role="hg-ext">extdiff</literal> extension 27.379 + will run <command>kdiff3</command> for you.</para> 27.380 + <programlisting>[extdiff] 27.381 +cmd.kdiff3 =</programlisting> 27.382 + <para>If you leave the right hand side of the definition empty, 27.383 + as above, the <literal role="hg-ext">extdiff</literal> 27.384 + extension uses the name of the command you defined as the name 27.385 + of the external program to run. But these names don't have to 27.386 + be the same. Here, we define a command named 27.387 + <quote><literal>hg wibble</literal></quote>, which runs 27.388 + <command>kdiff3</command>.</para> 27.389 + <programlisting>[extdiff] 27.390 + cmd.wibble = kdiff3</programlisting> 27.391 + 27.392 + <para>You can also specify the default options that you want to 27.393 + invoke your diff viewing program with. The prefix to use is 27.394 + <quote><literal>opts.</literal></quote>, followed by the name 27.395 + of the command to which the options apply. This example 27.396 + defines a <quote><literal>hg vimdiff</literal></quote> command 27.397 + that runs the <command>vim</command> editor's 27.398 + <literal>DirDiff</literal> extension.</para> 27.399 + <programlisting>[extdiff] 27.400 + cmd.vimdiff = vim 27.401 +opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting> 27.402 + 27.403 + </sect2> 27.404 + </sect1> 27.405 + <sect1 id="sec:hgext:transplant"> 27.406 + <title>Cherrypicking changes with the <literal 27.407 + role="hg-ext">transplant</literal> extension</title> 27.408 + 27.409 + <para>Need to have a long chat with Brendan about this.</para> 27.410 + 27.411 + </sect1> 27.412 + <sect1 id="sec:hgext:patchbomb"> 27.413 + <title>Send changes via email with the <literal 27.414 + role="hg-ext">patchbomb</literal> extension</title> 27.415 + 27.416 + <para>Many projects have a culture of <quote>change 27.417 + review</quote>, in which people send their modifications to a 27.418 + mailing list for others to read and comment on before they 27.419 + commit the final version to a shared repository. Some projects 27.420 + have people who act as gatekeepers; they apply changes from 27.421 + other people to a repository to which those others don't have 27.422 + access.</para> 27.423 + 27.424 + <para>Mercurial makes it easy to send changes over email for 27.425 + review or application, via its <literal 27.426 + role="hg-ext">patchbomb</literal> extension. The extension is 27.427 + so named because changes are formatted as patches, and it's usual 27.428 + to send one changeset per email message. Sending a long series 27.429 + of changes by email is thus much like <quote>bombing</quote> the 27.430 + recipient's inbox, hence <quote>patchbomb</quote>.</para> 27.431 + 27.432 + <para>As usual, the basic configuration of the <literal 27.433 + role="hg-ext">patchbomb</literal> extension takes just one or 27.434 + two lines in your <filename role="special"> 27.435 + /.hgrc</filename>.</para> 27.436 + <programlisting>[extensions] 27.437 +patchbomb =</programlisting> 27.438 + <para>Once you've enabled the extension, you will have a new 27.439 + command available, named <command 27.440 + role="hg-ext-patchbomb">email</command>.</para> 27.441 + 27.442 + <para>The safest and best way to invoke the <command 27.443 + role="hg-ext-patchbomb">email</command> command is to 27.444 + <emphasis>always</emphasis> run it first with the <option 27.445 + role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option. 27.446 + This will show you what the command <emphasis>would</emphasis> 27.447 + send, without actually sending anything. Once you've had a 27.448 + quick glance over the changes and verified that you are sending 27.449 + the right ones, you can rerun the same command, with the <option 27.450 + role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option 27.451 + removed.</para> 27.452 + 27.453 + <para>The <command role="hg-ext-patchbomb">email</command> command 27.454 + accepts the same kind of revision syntax as every other 27.455 + Mercurial command. For example, this command will send every 27.456 + revision between 7 and <literal>tip</literal>, inclusive.</para> 27.457 + <programlisting>hg email -n 7:tip</programlisting> 27.458 + <para>You can also specify a <emphasis>repository</emphasis> to 27.459 + compare with. If you provide a repository but no revisions, the 27.460 + <command role="hg-ext-patchbomb">email</command> command will 27.461 + send all revisions in the local repository that are not present 27.462 + in the remote repository. If you additionally specify revisions 27.463 + or a branch name (the latter using the <option 27.464 + role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option), 27.465 + this will constrain the revisions sent.</para> 27.466 + 27.467 + <para>It's perfectly safe to run the <command 27.468 + role="hg-ext-patchbomb">email</command> command without the 27.469 + names of the people you want to send to: if you do this, it will 27.470 + just prompt you for those values interactively. (If you're 27.471 + using a Linux or Unix-like system, you should have enhanced 27.472 + <literal>readline</literal>-style editing capabilities when 27.473 + entering those headers, too, which is useful.)</para> 27.474 + 27.475 + <para>When you are sending just one revision, the <command 27.476 + role="hg-ext-patchbomb">email</command> command will by 27.477 + default use the first line of the changeset description as the 27.478 + subject of the single email message it sends.</para> 27.479 + 27.480 + <para>If you send multiple revisions, the <command 27.481 + role="hg-ext-patchbomb">email</command> command will usually 27.482 + send one message per changeset. It will preface the series with 27.483 + an introductory message, in which you should describe the 27.484 + purpose of the series of changes you're sending.</para> 27.485 + 27.486 + <sect2> 27.487 + <title>Changing the behaviour of patchbombs</title> 27.488 + 27.489 + <para>Not every project has exactly the same conventions for 27.490 + sending changes in email; the <literal 27.491 + role="hg-ext">patchbomb</literal> extension tries to 27.492 + accommodate a number of variations through command line 27.493 + options.</para> 27.494 + <itemizedlist> 27.495 + <listitem><para>You can write a subject for the introductory 27.496 + message on the command line using the <option 27.497 + role="hg-ext-patchbomb-cmd-email-opt">hg -s</option> 27.498 + option. This takes one argument, the text of the subject 27.499 + to use.</para> 27.500 + </listitem> 27.501 + <listitem><para>To change the email address from which the 27.502 + messages originate, use the <option 27.503 + role="hg-ext-patchbomb-cmd-email-opt">hg -f</option> 27.504 + option. This takes one argument, the email address to 27.505 + use.</para> 27.506 + </listitem> 27.507 + <listitem><para>The default behaviour is to send unified diffs 27.508 + (see section <xref linkend="sec:mq:patch"/> for a 27.509 + description of the 27.510 + format), one per message. You can send a binary bundle 27.511 + instead with the <option 27.512 + role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> 27.513 + option.</para> 27.514 + </listitem> 27.515 + <listitem><para>Unified diffs are normally prefaced with a 27.516 + metadata header. You can omit this, and send unadorned 27.517 + diffs, with the <option 27.518 + role="hg-ext-patchbomb-cmd-email-opt">hg 27.519 + --plain</option> option.</para> 27.520 + </listitem> 27.521 + <listitem><para>Diffs are normally sent <quote>inline</quote>, 27.522 + in the same body part as the description of a patch. This 27.523 + makes it easiest for the largest number of readers to 27.524 + quote and respond to parts of a diff, as some mail clients 27.525 + will only quote the first MIME body part in a message. If 27.526 + you'd prefer to send the description and the diff in 27.527 + separate body parts, use the <option 27.528 + role="hg-ext-patchbomb-cmd-email-opt">hg -a</option> 27.529 + option.</para> 27.530 + </listitem> 27.531 + <listitem><para>Instead of sending mail messages, you can 27.532 + write them to an <literal>mbox</literal>-format mail 27.533 + folder using the <option 27.534 + role="hg-ext-patchbomb-cmd-email-opt">hg -m</option> 27.535 + option. That option takes one argument, the name of the 27.536 + file to write to.</para> 27.537 + </listitem> 27.538 + <listitem><para>If you would like to add a 27.539 + <command>diffstat</command>-format summary to each patch, 27.540 + and one to the introductory message, use the <option 27.541 + role="hg-ext-patchbomb-cmd-email-opt">hg -d</option> 27.542 + option. The <command>diffstat</command> command displays 27.543 + a table containing the name of each file patched, the 27.544 + number of lines affected, and a histogram showing how much 27.545 + each file is modified. This gives readers a qualitative 27.546 + glance at how complex a patch is.</para> 27.547 + </listitem></itemizedlist> 27.548 + 27.549 + </sect2> 27.550 + </sect1> 27.551 +</chapter> 27.552 + 27.553 +<!-- 27.554 +local variables: 27.555 +sgml-parent-document: ("00book.xml" "book" "chapter") 27.556 +end: 27.557 +-->
28.1 --- a/en/ch13-mq-collab.xml Wed Mar 18 00:08:22 2009 -0700 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,518 +0,0 @@ 28.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 28.5 - 28.6 -<chapter id="chap:mq-collab"> 28.7 - <?dbhtml filename="advanced-uses-of-mercurial-queues.html"?> 28.8 - <title>Advanced uses of Mercurial Queues</title> 28.9 - 28.10 - <para>While it's easy to pick up straightforward uses of Mercurial 28.11 - Queues, use of a little discipline and some of MQ's less 28.12 - frequently used capabilities makes it possible to work in 28.13 - complicated development environments.</para> 28.14 - 28.15 - <para>In this chapter, I will use as an example a technique I have 28.16 - used to manage the development of an Infiniband device driver for 28.17 - the Linux kernel. The driver in question is large (at least as 28.18 - drivers go), with 25,000 lines of code spread across 35 source 28.19 - files. It is maintained by a small team of developers.</para> 28.20 - 28.21 - <para>While much of the material in this chapter is specific to 28.22 - Linux, the same principles apply to any code base for which you're 28.23 - not the primary owner, and upon which you need to do a lot of 28.24 - development.</para> 28.25 - 28.26 - <sect1> 28.27 - <title>The problem of many targets</title> 28.28 - 28.29 - <para>The Linux kernel changes rapidly, and has never been 28.30 - internally stable; developers frequently make drastic changes 28.31 - between releases. This means that a version of the driver that 28.32 - works well with a particular released version of the kernel will 28.33 - not even <emphasis>compile</emphasis> correctly against, 28.34 - typically, any other version.</para> 28.35 - 28.36 - <para>To maintain a driver, we have to keep a number of distinct 28.37 - versions of Linux in mind.</para> 28.38 - <itemizedlist> 28.39 - <listitem><para>One target is the main Linux kernel development 28.40 - tree. Maintenance of the code is in this case partly shared 28.41 - by other developers in the kernel community, who make 28.42 - <quote>drive-by</quote> modifications to the driver as they 28.43 - develop and refine kernel subsystems.</para> 28.44 - </listitem> 28.45 - <listitem><para>We also maintain a number of 28.46 - <quote>backports</quote> to older versions of the Linux 28.47 - kernel, to support the needs of customers who are running 28.48 - older Linux distributions that do not incorporate our 28.49 - drivers. (To <emphasis>backport</emphasis> a piece of code 28.50 - is to modify it to work in an older version of its target 28.51 - environment than the version it was developed for.)</para> 28.52 - </listitem> 28.53 - <listitem><para>Finally, we make software releases on a schedule 28.54 - that is necessarily not aligned with those used by Linux 28.55 - distributors and kernel developers, so that we can deliver 28.56 - new features to customers without forcing them to upgrade 28.57 - their entire kernels or distributions.</para> 28.58 - </listitem></itemizedlist> 28.59 - 28.60 - <sect2> 28.61 - <title>Tempting approaches that don't work well</title> 28.62 - 28.63 - <para>There are two <quote>standard</quote> ways to maintain a 28.64 - piece of software that has to target many different 28.65 - environments.</para> 28.66 - 28.67 - <para>The first is to maintain a number of branches, each 28.68 - intended for a single target. The trouble with this approach 28.69 - is that you must maintain iron discipline in the flow of 28.70 - changes between repositories. A new feature or bug fix must 28.71 - start life in a <quote>pristine</quote> repository, then 28.72 - percolate out to every backport repository. Backport changes 28.73 - are more limited in the branches they should propagate to; a 28.74 - backport change that is applied to a branch where it doesn't 28.75 - belong will probably stop the driver from compiling.</para> 28.76 - 28.77 - <para>The second is to maintain a single source tree filled with 28.78 - conditional statements that turn chunks of code on or off 28.79 - depending on the intended target. Because these 28.80 - <quote>ifdefs</quote> are not allowed in the Linux kernel 28.81 - tree, a manual or automatic process must be followed to strip 28.82 - them out and yield a clean tree. A code base maintained in 28.83 - this fashion rapidly becomes a rat's nest of conditional 28.84 - blocks that are difficult to understand and maintain.</para> 28.85 - 28.86 - <para>Neither of these approaches is well suited to a situation 28.87 - where you don't <quote>own</quote> the canonical copy of a 28.88 - source tree. In the case of a Linux driver that is 28.89 - distributed with the standard kernel, Linus's tree contains 28.90 - the copy of the code that will be treated by the world as 28.91 - canonical. The upstream version of <quote>my</quote> driver 28.92 - can be modified by people I don't know, without me even 28.93 - finding out about it until after the changes show up in 28.94 - Linus's tree.</para> 28.95 - 28.96 - <para>These approaches have the added weakness of making it 28.97 - difficult to generate well-formed patches to submit 28.98 - upstream.</para> 28.99 - 28.100 - <para>In principle, Mercurial Queues seems like a good candidate 28.101 - to manage a development scenario such as the above. While 28.102 - this is indeed the case, MQ contains a few added features that 28.103 - make the job more pleasant.</para> 28.104 - 28.105 - </sect2> 28.106 - </sect1> 28.107 - <sect1> 28.108 - <title>Conditionally applying patches with guards</title> 28.109 - 28.110 - <para>Perhaps the best way to maintain sanity with so many targets 28.111 - is to be able to choose specific patches to apply for a given 28.112 - situation. MQ provides a feature called <quote>guards</quote> 28.113 - (which originates with quilt's <literal>guards</literal> 28.114 - command) that does just this. To start off, let's create a 28.115 - simple repository for experimenting in.</para> 28.116 - 28.117 - &interaction.mq.guards.init; 28.118 - 28.119 - <para>This gives us a tiny repository that contains two patches 28.120 - that don't have any dependencies on each other, because they 28.121 - touch different files.</para> 28.122 - 28.123 - <para>The idea behind conditional application is that you can 28.124 - <quote>tag</quote> a patch with a <emphasis>guard</emphasis>, 28.125 - which is simply a text string of your choosing, then tell MQ to 28.126 - select specific guards to use when applying patches. MQ will 28.127 - then either apply, or skip over, a guarded patch, depending on 28.128 - the guards that you have selected.</para> 28.129 - 28.130 - <para>A patch can have an arbitrary number of guards; each one is 28.131 - <emphasis>positive</emphasis> (<quote>apply this patch if this 28.132 - guard is selected</quote>) or <emphasis>negative</emphasis> 28.133 - (<quote>skip this patch if this guard is selected</quote>). A 28.134 - patch with no guards is always applied.</para> 28.135 - 28.136 - </sect1> 28.137 - <sect1> 28.138 - <title>Controlling the guards on a patch</title> 28.139 - 28.140 - <para>The <command role="hg-ext-mq">qguard</command> command lets 28.141 - you determine which guards should apply to a patch, or display 28.142 - the guards that are already in effect. Without any arguments, it 28.143 - displays the guards on the current topmost patch.</para> 28.144 - 28.145 - &interaction.mq.guards.qguard; 28.146 - 28.147 - <para>To set a positive guard on a patch, prefix the name of the 28.148 - guard with a <quote><literal>+</literal></quote>.</para> 28.149 - 28.150 - &interaction.mq.guards.qguard.pos; 28.151 - 28.152 - <para>To set a negative guard 28.153 - on a patch, prefix the name of the guard with a 28.154 - <quote><literal>-</literal></quote>.</para> 28.155 - 28.156 - &interaction.mq.guards.qguard.neg; 28.157 - 28.158 - <note> 28.159 - <para> The <command role="hg-ext-mq">qguard</command> command 28.160 - <emphasis>sets</emphasis> the guards on a patch; it doesn't 28.161 - <emphasis>modify</emphasis> them. What this means is that if 28.162 - you run <command role="hg-cmd">hg qguard +a +b</command> on a 28.163 - patch, then <command role="hg-cmd">hg qguard +c</command> on 28.164 - the same patch, the <emphasis>only</emphasis> guard that will 28.165 - be set on it afterwards is <literal>+c</literal>.</para> 28.166 - </note> 28.167 - 28.168 - <para>Mercurial stores guards in the <filename 28.169 - role="special">series</filename> file; the form in which they 28.170 - are stored is easy both to understand and to edit by hand. (In 28.171 - other words, you don't have to use the <command 28.172 - role="hg-ext-mq">qguard</command> command if you don't want 28.173 - to; it's okay to simply edit the <filename 28.174 - role="special">series</filename> file.)</para> 28.175 - 28.176 - &interaction.mq.guards.series; 28.177 - 28.178 - </sect1> 28.179 - <sect1> 28.180 - <title>Selecting the guards to use</title> 28.181 - 28.182 - <para>The <command role="hg-ext-mq">qselect</command> command 28.183 - determines which guards are active at a given time. The effect 28.184 - of this is to determine which patches MQ will apply the next 28.185 - time you run <command role="hg-ext-mq">qpush</command>. It has 28.186 - no other effect; in particular, it doesn't do anything to 28.187 - patches that are already applied.</para> 28.188 - 28.189 - <para>With no arguments, the <command 28.190 - role="hg-ext-mq">qselect</command> command lists the guards 28.191 - currently in effect, one per line of output. Each argument is 28.192 - treated as the name of a guard to apply.</para> 28.193 - 28.194 - &interaction.mq.guards.qselect.foo; 28.195 - 28.196 - <para>In case you're interested, the currently selected guards are 28.197 - stored in the <filename role="special">guards</filename> file.</para> 28.198 - 28.199 - &interaction.mq.guards.qselect.cat; 28.200 - 28.201 - <para>We can see the effect the selected guards have when we run 28.202 - <command role="hg-ext-mq">qpush</command>.</para> 28.203 - 28.204 - &interaction.mq.guards.qselect.qpush; 28.205 - 28.206 - <para>A guard cannot start with a 28.207 - <quote><literal>+</literal></quote> or 28.208 - <quote><literal>-</literal></quote> character. The name of a 28.209 - guard must not contain white space, but most other characters 28.210 - are acceptable. If you try to use a guard with an invalid name, 28.211 - MQ will complain:</para> 28.212 - 28.213 - &interaction.mq.guards.qselect.error; 28.214 - 28.215 - <para>Changing the selected guards changes the patches that are 28.216 - applied.</para> 28.217 - 28.218 - &interaction.mq.guards.qselect.quux; 28.219 - 28.220 - <para>You can see in the example below that negative guards take 28.221 - precedence over positive guards.</para> 28.222 - 28.223 - &interaction.mq.guards.qselect.foobar; 28.224 - 28.225 - </sect1> 28.226 - <sect1> 28.227 - <title>MQ's rules for applying patches</title> 28.228 - 28.229 - <para>The rules that MQ uses when deciding whether to apply a 28.230 - patch are as follows.</para> 28.231 - <itemizedlist> 28.232 - <listitem><para>A patch that has no guards is always 28.233 - applied.</para> 28.234 - </listitem> 28.235 - <listitem><para>If the patch has any negative guard that matches 28.236 - any currently selected guard, the patch is skipped.</para> 28.237 - </listitem> 28.238 - <listitem><para>If the patch has any positive guard that matches 28.239 - any currently selected guard, the patch is applied.</para> 28.240 - </listitem> 28.241 - <listitem><para>If the patch has positive or negative guards, 28.242 - but none matches any currently selected guard, the patch is 28.243 - skipped.</para> 28.244 - </listitem></itemizedlist> 28.245 - 28.246 - </sect1> 28.247 - <sect1> 28.248 - <title>Trimming the work environment</title> 28.249 - 28.250 - <para>In working on the device driver I mentioned earlier, I don't 28.251 - apply the patches to a normal Linux kernel tree. Instead, I use 28.252 - a repository that contains only a snapshot of the source files 28.253 - and headers that are relevant to Infiniband development. This 28.254 - repository is 1% the size of a kernel repository, so it's easier 28.255 - to work with.</para> 28.256 - 28.257 - <para>I then choose a <quote>base</quote> version on top of which 28.258 - the patches are applied. This is a snapshot of the Linux kernel 28.259 - tree as of a revision of my choosing. When I take the snapshot, 28.260 - I record the changeset ID from the kernel repository in the 28.261 - commit message. Since the snapshot preserves the 28.262 - <quote>shape</quote> and content of the relevant parts of the 28.263 - kernel tree, I can apply my patches on top of either my tiny 28.264 - repository or a normal kernel tree.</para> 28.265 - 28.266 - <para>Normally, the base tree atop which the patches apply should 28.267 - be a snapshot of a very recent upstream tree. This best 28.268 - facilitates the development of patches that can easily be 28.269 - submitted upstream with few or no modifications.</para> 28.270 - 28.271 - </sect1> 28.272 - <sect1> 28.273 - <title>Dividing up the <filename role="special">series</filename> 28.274 - file</title> 28.275 - 28.276 - <para>I categorise the patches in the <filename 28.277 - role="special">series</filename> file into a number of logical 28.278 - groups. Each section of like patches begins with a block of 28.279 - comments that describes the purpose of the patches that 28.280 - follow.</para> 28.281 - 28.282 - <para>The sequence of patch groups that I maintain follows. The 28.283 - ordering of these groups is important; I'll describe why after I 28.284 - introduce the groups.</para> 28.285 - <itemizedlist> 28.286 - <listitem><para>The <quote>accepted</quote> group. Patches that 28.287 - the development team has submitted to the maintainer of the 28.288 - Infiniband subsystem, and which he has accepted, but which 28.289 - are not present in the snapshot that the tiny repository is 28.290 - based on. These are <quote>read only</quote> patches, 28.291 - present only to transform the tree into a similar state as 28.292 - it is in the upstream maintainer's repository.</para> 28.293 - </listitem> 28.294 - <listitem><para>The <quote>rework</quote> group. Patches that I 28.295 - have submitted, but that the upstream maintainer has 28.296 - requested modifications to before he will accept 28.297 - them.</para> 28.298 - </listitem> 28.299 - <listitem><para>The <quote>pending</quote> group. Patches that 28.300 - I have not yet submitted to the upstream maintainer, but 28.301 - which we have finished working on. These will be <quote>read 28.302 - only</quote> for a while. If the upstream maintainer 28.303 - accepts them upon submission, I'll move them to the end of 28.304 - the <quote>accepted</quote> group. If he requests that I 28.305 - modify any, I'll move them to the beginning of the 28.306 - <quote>rework</quote> group.</para> 28.307 - </listitem> 28.308 - <listitem><para>The <quote>in progress</quote> group. Patches 28.309 - that are actively being developed, and should not be 28.310 - submitted anywhere yet.</para> 28.311 - </listitem> 28.312 - <listitem><para>The <quote>backport</quote> group. Patches that 28.313 - adapt the source tree to older versions of the kernel 28.314 - tree.</para> 28.315 - </listitem> 28.316 - <listitem><para>The <quote>do not ship</quote> group. Patches 28.317 - that for some reason should never be submitted upstream. 28.318 - For example, one such patch might change embedded driver 28.319 - identification strings to make it easier to distinguish, in 28.320 - the field, between an out-of-tree version of the driver and 28.321 - a version shipped by a distribution vendor.</para> 28.322 - </listitem></itemizedlist> 28.323 - 28.324 - <para>Now to return to the reasons for ordering groups of patches 28.325 - in this way. We would like the lowest patches in the stack to 28.326 - be as stable as possible, so that we will not need to rework 28.327 - higher patches due to changes in context. Putting patches that 28.328 - will never be changed first in the <filename 28.329 - role="special">series</filename> file serves this 28.330 - purpose.</para> 28.331 - 28.332 - <para>We would also like the patches that we know we'll need to 28.333 - modify to be applied on top of a source tree that resembles the 28.334 - upstream tree as closely as possible. This is why we keep 28.335 - accepted patches around for a while.</para> 28.336 - 28.337 - <para>The <quote>backport</quote> and <quote>do not ship</quote> 28.338 - patches float at the end of the <filename 28.339 - role="special">series</filename> file. The backport patches 28.340 - must be applied on top of all other patches, and the <quote>do 28.341 - not ship</quote> patches might as well stay out of harm's 28.342 - way.</para> 28.343 - 28.344 - </sect1> 28.345 - <sect1> 28.346 - <title>Maintaining the patch series</title> 28.347 - 28.348 - <para>In my work, I use a number of guards to control which 28.349 - patches are to be applied.</para> 28.350 - 28.351 - <itemizedlist> 28.352 - <listitem><para><quote>Accepted</quote> patches are guarded with 28.353 - <literal>accepted</literal>. I enable this guard most of 28.354 - the time. When I'm applying the patches on top of a tree 28.355 - where the patches are already present, I can turn this patch 28.356 - off, and the patches that follow it will apply 28.357 - cleanly.</para> 28.358 - </listitem> 28.359 - <listitem><para>Patches that are <quote>finished</quote>, but 28.360 - not yet submitted, have no guards. If I'm applying the 28.361 - patch stack to a copy of the upstream tree, I don't need to 28.362 - enable any guards in order to get a reasonably safe source 28.363 - tree.</para> 28.364 - </listitem> 28.365 - <listitem><para>Those patches that need reworking before being 28.366 - resubmitted are guarded with 28.367 - <literal>rework</literal>.</para> 28.368 - </listitem> 28.369 - <listitem><para>For those patches that are still under 28.370 - development, I use <literal>devel</literal>.</para> 28.371 - </listitem> 28.372 - <listitem><para>A backport patch may have several guards, one 28.373 - for each version of the kernel to which it applies. For 28.374 - example, a patch that backports a piece of code to 2.6.9 28.375 - will have a <literal>2.6.9</literal> guard.</para> 28.376 - </listitem></itemizedlist> 28.377 - <para>This variety of guards gives me considerable flexibility in 28.378 - determining what kind of source tree I want to end up with. For 28.379 - most situations, the selection of appropriate guards is 28.380 - automated during the build process, but I can manually tune the 28.381 - guards to use for less common circumstances.</para> 28.382 - 28.383 - <sect2> 28.384 - <title>The art of writing backport patches</title> 28.385 - 28.386 - <para>Using MQ, writing a backport patch is a simple process. 28.387 - All such a patch has to do is modify a piece of code that uses 28.388 - a kernel feature not present in the older version of the 28.389 - kernel, so that the driver continues to work correctly under 28.390 - that older version.</para> 28.391 - 28.392 - <para>A useful goal when writing a good backport patch is to 28.393 - make your code look as if it was written for the older version 28.394 - of the kernel you're targeting. The less obtrusive the patch, 28.395 - the easier it will be to understand and maintain. If you're 28.396 - writing a collection of backport patches to avoid the 28.397 - <quote>rat's nest</quote> effect of lots of 28.398 - <literal>#ifdef</literal>s (hunks of source code that are only 28.399 - used conditionally) in your code, don't introduce 28.400 - version-dependent <literal>#ifdef</literal>s into the patches. 28.401 - Instead, write several patches, each of which makes 28.402 - unconditional changes, and control their application using 28.403 - guards.</para> 28.404 - 28.405 - <para>There are two reasons to divide backport patches into a 28.406 - distinct group, away from the <quote>regular</quote> patches 28.407 - whose effects they modify. The first is that intermingling the 28.408 - two makes it more difficult to use a tool like the <literal 28.409 - role="hg-ext">patchbomb</literal> extension to automate the 28.410 - process of submitting the patches to an upstream maintainer. 28.411 - The second is that a backport patch could perturb the context 28.412 - in which a subsequent regular patch is applied, making it 28.413 - impossible to apply the regular patch cleanly 28.414 - <emphasis>without</emphasis> the earlier backport patch 28.415 - already being applied.</para> 28.416 - 28.417 - </sect2> 28.418 - </sect1> 28.419 - <sect1> 28.420 - <title>Useful tips for developing with MQ</title> 28.421 - 28.422 - <sect2> 28.423 - <title>Organising patches in directories</title> 28.424 - 28.425 - <para>If you're working on a substantial project with MQ, it's 28.426 - not difficult to accumulate a large number of patches. For 28.427 - example, I have one patch repository that contains over 250 28.428 - patches.</para> 28.429 - 28.430 - <para>If you can group these patches into separate logical 28.431 - categories, you can if you like store them in different 28.432 - directories; MQ has no problems with patch names that contain 28.433 - path separators.</para> 28.434 - 28.435 - </sect2> 28.436 - <sect2 id="mq-collab:tips:interdiff"> 28.437 - <title>Viewing the history of a patch</title> 28.438 - 28.439 - <para>If you're developing a set of patches over a long time, 28.440 - it's a good idea to maintain them in a repository, as 28.441 - discussed in section <xref linkend="sec:mq:repo"/>. If you do 28.442 - so, you'll quickly 28.443 - discover that using the <command role="hg-cmd">hg 28.444 - diff</command> command to look at the history of changes to 28.445 - a patch is unworkable. This is in part because you're looking 28.446 - at the second derivative of the real code (a diff of a diff), 28.447 - but also because MQ adds noise to the process by modifying 28.448 - time stamps and directory names when it updates a 28.449 - patch.</para> 28.450 - 28.451 - <para>However, you can use the <literal 28.452 - role="hg-ext">extdiff</literal> extension, which is bundled 28.453 - with Mercurial, to turn a diff of two versions of a patch into 28.454 - something readable. To do this, you will need a third-party 28.455 - package called <literal role="package">patchutils</literal> 28.456 - <citation>web:patchutils</citation>. This provides a command 28.457 - named <command>interdiff</command>, which shows the 28.458 - differences between two diffs as a diff. Used on two versions 28.459 - of the same diff, it generates a diff that represents the diff 28.460 - from the first to the second version.</para> 28.461 - 28.462 - <para>You can enable the <literal 28.463 - role="hg-ext">extdiff</literal> extension in the usual way, 28.464 - by adding a line to the <literal 28.465 - role="rc-extensions">extensions</literal> section of your 28.466 - <filename role="special">~/.hgrc</filename>.</para> 28.467 - <programlisting>[extensions] 28.468 -extdiff =</programlisting> 28.469 - <para>The <command>interdiff</command> command expects to be 28.470 - passed the names of two files, but the <literal 28.471 - role="hg-ext">extdiff</literal> extension passes the program 28.472 - it runs a pair of directories, each of which can contain an 28.473 - arbitrary number of files. We thus need a small program that 28.474 - will run <command>interdiff</command> on each pair of files in 28.475 - these two directories. This program is available as <filename 28.476 - role="special">hg-interdiff</filename> in the <filename 28.477 - class="directory">examples</filename> directory of the 28.478 - source code repository that accompanies this book. <!-- 28.479 - &example.hg-interdiff; --></para> 28.480 - 28.481 - <para>With the <filename role="special">hg-interdiff</filename> 28.482 - program in your shell's search path, you can run it as 28.483 - follows, from inside an MQ patch directory:</para> 28.484 - <programlisting>hg extdiff -p hg-interdiff -r A:B my-change.patch</programlisting> 28.485 - <para>Since you'll probably want to use this long-winded command 28.486 - a lot, you can get <literal role="hg-ext">hgext</literal> to 28.487 - make it available as a normal Mercurial command, again by 28.488 - editing your <filename 28.489 - role="special">~/.hgrc</filename>.</para> 28.490 - <programlisting>[extdiff] 28.491 -cmd.interdiff = hg-interdiff</programlisting> 28.492 - <para>This directs <literal role="hg-ext">hgext</literal> to 28.493 - make an <literal>interdiff</literal> command available, so you 28.494 - can now shorten the previous invocation of <command 28.495 - role="hg-ext-extdiff">extdiff</command> to something a 28.496 - little more wieldy.</para> 28.497 - <programlisting>hg interdiff -r A:B my-change.patch</programlisting> 28.498 - 28.499 - <note> 28.500 - <para> The <command>interdiff</command> command works well 28.501 - only if the underlying files against which versions of a 28.502 - patch are generated remain the same. If you create a patch, 28.503 - modify the underlying files, and then regenerate the patch, 28.504 - <command>interdiff</command> may not produce useful 28.505 - output.</para> 28.506 - </note> 28.507 - 28.508 - <para>The <literal role="hg-ext">extdiff</literal> extension is 28.509 - useful for more than merely improving the presentation of MQ 28.510 - patches. To read more about it, go to section <xref 28.511 - linkend="sec:hgext:extdiff"/>.</para> 28.512 - 28.513 - </sect2> 28.514 - </sect1> 28.515 -</chapter> 28.516 - 28.517 -<!-- 28.518 -local variables: 28.519 -sgml-parent-document: ("00book.xml" "book" "chapter") 28.520 -end: 28.521 --->
29.1 --- a/en/ch14-hgext.xml Wed Mar 18 00:08:22 2009 -0700 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,554 +0,0 @@ 29.4 -<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 29.5 - 29.6 -<chapter id="chap:hgext"> 29.7 - <?dbhtml filename="adding-functionality-with-extensions.html"?> 29.8 - <title>Adding functionality with extensions</title> 29.9 - 29.10 - <para>While the core of Mercurial is quite complete from a 29.11 - functionality standpoint, it's deliberately shorn of fancy 29.12 - features. This approach of preserving simplicity keeps the 29.13 - software easy to deal with for both maintainers and users.</para> 29.14 - 29.15 - <para>However, Mercurial doesn't box you in with an inflexible 29.16 - command set: you can add features to it as 29.17 - <emphasis>extensions</emphasis> (sometimes known as 29.18 - <emphasis>plugins</emphasis>). We've already discussed a few of 29.19 - these extensions in earlier chapters.</para> 29.20 - <itemizedlist> 29.21 - <listitem><para>Section <xref linkend="sec:tour-merge:fetch"/> 29.22 - covers the <literal role="hg-ext">fetch</literal> extension; 29.23 - this combines pulling new changes and merging them with local 29.24 - changes into a single command, <command 29.25 - role="hg-ext-fetch">fetch</command>.</para> 29.26 - </listitem> 29.27 - <listitem><para>In chapter <xref linkend="chap:hook"/>, we covered 29.28 - several extensions that are useful for hook-related 29.29 - functionality: <literal role="hg-ext">acl</literal> adds 29.30 - access control lists; <literal 29.31 - role="hg-ext">bugzilla</literal> adds integration with the 29.32 - Bugzilla bug tracking system; and <literal 29.33 - role="hg-ext">notify</literal> sends notification emails on 29.34 - new changes.</para> 29.35 - </listitem> 29.36 - <listitem><para>The Mercurial Queues patch management extension is 29.37 - so invaluable that it merits two chapters and an appendix all 29.38 - to itself. Chapter <xref linkend="chap:mq"/> covers the 29.39 - basics; chapter <xref 29.40 - linkend="chap:mq-collab"/> discusses advanced topics; 29.41 - and appendix <xref linkend="chap:mqref"/> goes into detail on 29.42 - each 29.43 - command.</para> 29.44 - </listitem></itemizedlist> 29.45 - 29.46 - <para>In this chapter, we'll cover some of the other extensions that 29.47 - are available for Mercurial, and briefly touch on some of the 29.48 - machinery you'll need to know about if you want to write an 29.49 - extension of your own.</para> 29.50 - <itemizedlist> 29.51 - <listitem><para>In section <xref linkend="sec:hgext:inotify"/>, 29.52 - we'll discuss the possibility of <emphasis>huge</emphasis> 29.53 - performance improvements using the <literal 29.54 - role="hg-ext">inotify</literal> extension.</para> 29.55 - </listitem></itemizedlist> 29.56 - 29.57 - <sect1 id="sec:hgext:inotify"> 29.58 - <title>Improve performance with the <literal 29.59 - role="hg-ext">inotify</literal> extension</title> 29.60 - 29.61 - <para>Are you interested in having some of the most common 29.62 - Mercurial operations run as much as a hundred times faster? 29.63 - Read on!</para> 29.64 - 29.65 - <para>Mercurial has great performance under normal circumstances. 29.66 - For example, when you run the <command role="hg-cmd">hg 29.67 - status</command> command, Mercurial has to scan almost every 29.68 - directory and file in your repository so that it can display 29.69 - file status. Many other Mercurial commands need to do the same 29.70 - work behind the scenes; for example, the <command 29.71 - role="hg-cmd">hg diff</command> command uses the status 29.72 - machinery to avoid doing an expensive comparison operation on 29.73 - files that obviously haven't changed.</para> 29.74 - 29.75 - <para>Because obtaining file status is crucial to good 29.76 - performance, the authors of Mercurial have optimised this code 29.77 - to within an inch of its life. However, there's no avoiding the 29.78 - fact that when you run <command role="hg-cmd">hg 29.79 - status</command>, Mercurial is going to have to perform at 29.80 - least one expensive system call for each managed file to 29.81 - determine whether it's changed since the last time Mercurial 29.82 - checked. For a sufficiently large repository, this can take a 29.83 - long time.</para> 29.84 - 29.85 - <para>To put a number on the magnitude of this effect, I created a 29.86 - repository containing 150,000 managed files. I timed <command 29.87 - role="hg-cmd">hg status</command> as taking ten seconds to 29.88 - run, even when <emphasis>none</emphasis> of those files had been 29.89 - modified.</para> 29.90 - 29.91 - <para>Many modern operating systems contain a file notification 29.92 - facility. If a program signs up to an appropriate service, the 29.93 - operating system will notify it every time a file of interest is 29.94 - created, modified, or deleted. On Linux systems, the kernel 29.95 - component that does this is called 29.96 - <literal>inotify</literal>.</para> 29.97 - 29.98 - <para>Mercurial's <literal role="hg-ext">inotify</literal> 29.99 - extension talks to the kernel's <literal>inotify</literal> 29.100 - component to optimise <command role="hg-cmd">hg status</command> 29.101 - commands. The extension has two components. A daemon sits in 29.102 - the background and receives notifications from the 29.103 - <literal>inotify</literal> subsystem. It also listens for 29.104 - connections from a regular Mercurial command. The extension 29.105 - modifies Mercurial's behaviour so that instead of scanning the 29.106 - filesystem, it queries the daemon. Since the daemon has perfect 29.107 - information about the state of the repository, it can respond 29.108 - with a result instantaneously, avoiding the need to scan every 29.109 - directory and file in the repository.</para> 29.110 - 29.111 - <para>Recall the ten seconds that I measured plain Mercurial as 29.112 - taking to run <command role="hg-cmd">hg status</command> on a 29.113 - 150,000 file repository. With the <literal 29.114 - role="hg-ext">inotify</literal> extension enabled, the time 29.115 - dropped to 0.1 seconds, a factor of <emphasis>one 29.116 - hundred</emphasis> faster.</para> 29.117 - 29.118 - <para>Before we continue, please pay attention to some 29.119 - caveats.</para> 29.120 - <itemizedlist> 29.121 - <listitem><para>The <literal role="hg-ext">inotify</literal> 29.122 - extension is Linux-specific. Because it interfaces directly 29.123 - to the Linux kernel's <literal>inotify</literal> subsystem, 29.124 - it does not work on other operating systems.</para> 29.125 - </listitem> 29.126 - <listitem><para>It should work on any Linux distribution that 29.127 - was released after early 2005. Older distributions are 29.128 - likely to have a kernel that lacks 29.129 - <literal>inotify</literal>, or a version of 29.130 - <literal>glibc</literal> that does not have the necessary 29.131 - interfacing support.</para> 29.132 - </listitem> 29.133 - <listitem><para>Not all filesystems are suitable for use with 29.134 - the <literal role="hg-ext">inotify</literal> extension. 29.135 - Network filesystems such as NFS are a non-starter, for 29.136 - example, particularly if you're running Mercurial on several 29.137 - systems, all mounting the same network filesystem. The 29.138 - kernel's <literal>inotify</literal> system has no way of 29.139 - knowing about changes made on another system. Most local 29.140 - filesystems (e.g. ext3, XFS, ReiserFS) should work 29.141 - fine.</para> 29.142 - </listitem></itemizedlist> 29.143 - 29.144 - <para>The <literal role="hg-ext">inotify</literal> extension is 29.145 - not yet shipped with Mercurial as of May 2007, so it's a little 29.146 - more involved to set up than other extensions. But the 29.147 - performance improvement is worth it!</para> 29.148 - 29.149 - <para>The extension currently comes in two parts: a set of patches 29.150 - to the Mercurial source code, and a library of Python bindings 29.151 - to the <literal>inotify</literal> subsystem.</para> 29.152 - <note> 29.153 - <para> There are <emphasis>two</emphasis> Python 29.154 - <literal>inotify</literal> binding libraries. One of them is 29.155 - called <literal>pyinotify</literal>, and is packaged by some 29.156 - Linux distributions as <literal>python-inotify</literal>. 29.157 - This is <emphasis>not</emphasis> the one you'll need, as it is 29.158 - too buggy and inefficient to be practical.</para> 29.159 - </note> 29.160 - <para>To get going, it's best to already have a functioning copy 29.161 - of Mercurial installed.</para> 29.162 - <note> 29.163 - <para> If you follow the instructions below, you'll be 29.164 - <emphasis>replacing</emphasis> and overwriting any existing 29.165 - installation of Mercurial that you might already have, using 29.166 - the latest <quote>bleeding edge</quote> Mercurial code. Don't 29.167 - say you weren't warned!</para> 29.168 - </note> 29.169 - <orderedlist> 29.170 - <listitem><para>Clone the Python <literal>inotify</literal> 29.171 - binding repository. Build and install it.</para> 29.172 - <programlisting>hg clone http://hg.kublai.com/python/inotify 29.173 -cd inotify 29.174 -python setup.py build --force 29.175 -sudo python setup.py install --skip-build</programlisting> 29.176 - </listitem> 29.177 - <listitem><para>Clone the <filename 29.178 - class="directory">crew</filename> Mercurial repository. 29.179 - Clone the <literal role="hg-ext">inotify</literal> patch 29.180 - repository so that Mercurial Queues will be able to apply 29.181 - patches to your cope of the <filename 29.182 - class="directory">crew</filename> repository.</para> 29.183 - <programlisting>hg clone http://hg.intevation.org/mercurial/crew 29.184 -hg clone crew inotify 29.185 -hg clone http://hg.kublai.com/mercurial/patches/inotify inotify/.hg/patches</programlisting> 29.186 - </listitem> 29.187 - <listitem><para>Make sure that you have the Mercurial Queues 29.188 - extension, <literal role="hg-ext">mq</literal>, enabled. If 29.189 - you've never used MQ, read section <xref 29.190 - linkend="sec:mq:start"/> to get started 29.191 - quickly.</para> 29.192 - </listitem> 29.193 - <listitem><para>Go into the <filename 29.194 - class="directory">inotify</filename> repo, and apply all 29.195 - of the <literal role="hg-ext">inotify</literal> patches 29.196 - using the <option role="hg-ext-mq-cmd-qpush-opt">hg 29.197 - -a</option> option to the <command 29.198 - role="hg-ext-mq">qpush</command> command.</para> 29.199 - <programlisting>cd inotify 29.200 -hg qpush -a</programlisting> 29.201 - </listitem> 29.202 - <listitem><para> If you get an error message from <command 29.203 - role="hg-ext-mq">qpush</command>, you should not continue. 29.204 - Instead, ask for help.</para> 29.205 - </listitem> 29.206 - <listitem><para>Build and install the patched version of 29.207 - Mercurial.</para> 29.208 - <programlisting>python setup.py build --force 29.209 -sudo python setup.py install --skip-build</programlisting> 29.210 - </listitem> 29.211 - </orderedlist> 29.212 - <para>Once you've build a suitably patched version of Mercurial, 29.213 - all you need to do to enable the <literal 29.214 - role="hg-ext">inotify</literal> extension is add an entry to 29.215 - your <filename role="special">~/.hgrc</filename>.</para> 29.216 - <programlisting>[extensions] inotify =</programlisting> 29.217 - <para>When the <literal role="hg-ext">inotify</literal> extension 29.218 - is enabled, Mercurial will automatically and transparently start 29.219 - the status daemon the first time you run a command that needs 29.220 - status in a repository. It runs one status daemon per 29.221 - repository.</para> 29.222 - 29.223 - <para>The status daemon is started silently, and runs in the 29.224 - background. If you look at a list of running processes after 29.225 - you've enabled the <literal role="hg-ext">inotify</literal> 29.226 - extension and run a few commands in different repositories, 29.227 - you'll thus see a few <literal>hg</literal> processes sitting 29.228 - around, waiting for updates from the kernel and queries from 29.229 - Mercurial.</para> 29.230 - 29.231 - <para>The first time you run a Mercurial command in a repository 29.232 - when you have the <literal role="hg-ext">inotify</literal> 29.233 - extension enabled, it will run with about the same performance 29.234 - as a normal Mercurial command. This is because the status 29.235 - daemon needs to perform a normal status scan so that it has a 29.236 - baseline against which to apply later updates from the kernel. 29.237 - However, <emphasis>every</emphasis> subsequent command that does 29.238 - any kind of status check should be noticeably faster on 29.239 - repositories of even fairly modest size. Better yet, the bigger 29.240 - your repository is, the greater a performance advantage you'll 29.241 - see. The <literal role="hg-ext">inotify</literal> daemon makes 29.242 - status operations almost instantaneous on repositories of all 29.243 - sizes!</para> 29.244 - 29.245 - <para>If you like, you can manually start a status daemon using 29.246 - the <command role="hg-ext-inotify">inserve</command> command. 29.247 - This gives you slightly finer control over how the daemon ought 29.248 - to run. This command will of course only be available when the 29.249 - <literal role="hg-ext">inotify</literal> extension is 29.250 - enabled.</para> 29.251 - 29.252 - <para>When you're using the <literal 29.253 - role="hg-ext">inotify</literal> extension, you should notice 29.254 - <emphasis>no difference at all</emphasis> in Mercurial's 29.255 - behaviour, with the sole exception of status-related commands 29.256 - running a whole lot faster than they used to. You should 29.257 - specifically expect that commands will not print different 29.258 - output; neither should they give different results. If either of 29.259 - these situations occurs, please report a bug.</para> 29.260 - 29.261 - </sect1> 29.262 - <sect1 id="sec:hgext:extdiff"> 29.263 - <title>Flexible diff support with the <literal 29.264 - role="hg-ext">extdiff</literal> extension</title> 29.265 - 29.266 - <para>Mercurial's built-in <command role="hg-cmd">hg 29.267 - diff</command> command outputs plaintext unified diffs.</para> 29.268 - 29.269 - &interaction.extdiff.diff; 29.270 - 29.271 - <para>If you would like to use an external tool to display 29.272 - modifications, you'll want to use the <literal 29.273 - role="hg-ext">extdiff</literal> extension. This will let you 29.274 - use, for example, a graphical diff tool.</para> 29.275 - 29.276 - <para>The <literal role="hg-ext">extdiff</literal> extension is 29.277 - bundled with Mercurial, so it's easy to set up. In the <literal 29.278 - role="rc-extensions">extensions</literal> section of your 29.279 - <filename role="special">~/.hgrc</filename>, simply add a 29.280 - one-line entry to enable the extension.</para> 29.281 - <programlisting>[extensions] 29.282 -extdiff =</programlisting> 29.283 - <para>This introduces a command named <command 29.284 - role="hg-ext-extdiff">extdiff</command>, which by default uses 29.285 - your system's <command>diff</command> command to generate a 29.286 - unified diff in the same form as the built-in <command 29.287 - role="hg-cmd">hg diff</command> command.</para> 29.288 - 29.289 - &interaction.extdiff.extdiff; 29.290 - 29.291 - <para>The result won't be exactly the same as with the built-in 29.292 - <command role="hg-cmd">hg diff</command> variations, because the 29.293 - output of <command>diff</command> varies from one system to 29.294 - another, even when passed the same options.</para> 29.295 - 29.296 - <para>As the <quote><literal>making snapshot</literal></quote> 29.297 - lines of output above imply, the <command 29.298 - role="hg-ext-extdiff">extdiff</command> command works by 29.299 - creating two snapshots of your source tree. The first snapshot 29.300 - is of the source revision; the second, of the target revision or 29.301 - working directory. The <command 29.302 - role="hg-ext-extdiff">extdiff</command> command generates 29.303 - these snapshots in a temporary directory, passes the name of 29.304 - each directory to an external diff viewer, then deletes the 29.305 - temporary directory. For efficiency, it only snapshots the 29.306 - directories and files that have changed between the two 29.307 - revisions.</para> 29.308 - 29.309 - <para>Snapshot directory names have the same base name as your 29.310 - repository. If your repository path is <filename 29.311 - class="directory">/quux/bar/foo</filename>, then <filename 29.312 - class="directory">foo</filename> will be the name of each 29.313 - snapshot directory. Each snapshot directory name has its 29.314 - changeset ID appended, if appropriate. If a snapshot is of 29.315 - revision <literal>a631aca1083f</literal>, the directory will be 29.316 - named <filename class="directory">foo.a631aca1083f</filename>. 29.317 - A snapshot of the working directory won't have a changeset ID 29.318 - appended, so it would just be <filename 29.319 - class="directory">foo</filename> in this example. To see what 29.320 - this looks like in practice, look again at the <command 29.321 - role="hg-ext-extdiff">extdiff</command> example above. Notice 29.322 - that the diff has the snapshot directory names embedded in its 29.323 - header.</para> 29.324 - 29.325 - <para>The <command role="hg-ext-extdiff">extdiff</command> command 29.326 - accepts two important options. The <option 29.327 - role="hg-ext-extdiff-cmd-extdiff-opt">hg -p</option> option 29.328 - lets you choose a program to view differences with, instead of 29.329 - <command>diff</command>. With the <option 29.330 - role="hg-ext-extdiff-cmd-extdiff-opt">hg -o</option> option, 29.331 - you can change the options that <command 29.332 - role="hg-ext-extdiff">extdiff</command> passes to the program 29.333 - (by default, these options are 29.334 - <quote><literal>-Npru</literal></quote>, which only make sense 29.335 - if you're running <command>diff</command>). In other respects, 29.336 - the <command role="hg-ext-extdiff">extdiff</command> command 29.337 - acts similarly to the built-in <command role="hg-cmd">hg 29.338 - diff</command> command: you use the same option names, syntax, 29.339 - and arguments to specify the revisions you want, the files you 29.340 - want, and so on.</para> 29.341 - 29.342 - <para>As an example, here's how to run the normal system 29.343 - <command>diff</command> command, getting it to generate context 29.344 - diffs (using the <option role="cmd-opt-diff">-c</option> option) 29.345 - instead of unified diffs, and five lines of context instead of 29.346 - the default three (passing <literal>5</literal> as the argument 29.347 - to the <option role="cmd-opt-diff">-C</option> option).</para> 29.348 - 29.349 - &interaction.extdiff.extdiff-ctx; 29.350 - 29.351 - <para>Launching a visual diff tool is just as easy. Here's how to 29.352 - launch the <command>kdiff3</command> viewer.</para> 29.353 - <programlisting>hg extdiff -p kdiff3 -o</programlisting> 29.354 - 29.355 - <para>If your diff viewing command can't deal with directories, 29.356 - you can easily work around this with a little scripting. For an 29.357 - example of such scripting in action with the <literal 29.358 - role="hg-ext">mq</literal> extension and the 29.359 - <command>interdiff</command> command, see section <xref 29.360 - linkend="mq-collab:tips:interdiff"/>.</para> 29.361 - 29.362 - <sect2> 29.363 - <title>Defining command aliases</title> 29.364 - 29.365 - <para>It can be cumbersome to remember the options to both the 29.366 - <command role="hg-ext-extdiff">extdiff</command> command and 29.367 - the diff viewer you want to use, so the <literal 29.368 - role="hg-ext">extdiff</literal> extension lets you define 29.369 - <emphasis>new</emphasis> commands that will invoke your diff 29.370 - viewer with exactly the right options.</para> 29.371 - 29.372 - <para>All you need to do is edit your <filename 29.373 - role="special">~/.hgrc</filename>, and add a section named 29.374 - <literal role="rc-extdiff">extdiff</literal>. Inside this 29.375 - section, you can define multiple commands. Here's how to add 29.376 - a <literal>kdiff3</literal> command. Once you've defined 29.377 - this, you can type <quote><literal>hg kdiff3</literal></quote> 29.378 - and the <literal role="hg-ext">extdiff</literal> extension 29.379 - will run <command>kdiff3</command> for you.</para> 29.380 - <programlisting>[extdiff] 29.381 -cmd.kdiff3 =</programlisting> 29.382 - <para>If you leave the right hand side of the definition empty, 29.383 - as above, the <literal role="hg-ext">extdiff</literal> 29.384 - extension uses the name of the command you defined as the name 29.385 - of the external program to run. But these names don't have to 29.386 - be the same. Here, we define a command named 29.387 - <quote><literal>hg wibble</literal></quote>, which runs 29.388 - <command>kdiff3</command>.</para> 29.389 - <programlisting>[extdiff] 29.390 - cmd.wibble = kdiff3</programlisting> 29.391 - 29.392 - <para>You can also specify the default options that you want to 29.393 - invoke your diff viewing program with. The prefix to use is 29.394 - <quote><literal>opts.</literal></quote>, followed by the name 29.395 - of the command to which the options apply. This example 29.396 - defines a <quote><literal>hg vimdiff</literal></quote> command 29.397 - that runs the <command>vim</command> editor's 29.398 - <literal>DirDiff</literal> extension.</para> 29.399 - <programlisting>[extdiff] 29.400 - cmd.vimdiff = vim 29.401 -opts.vimdiff = -f '+next' '+execute "DirDiff" argv(0) argv(1)'</programlisting> 29.402 - 29.403 - </sect2> 29.404 - </sect1> 29.405 - <sect1 id="sec:hgext:transplant"> 29.406 - <title>Cherrypicking changes with the <literal 29.407 - role="hg-ext">transplant</literal> extension</title> 29.408 - 29.409 - <para>Need to have a long chat with Brendan about this.</para> 29.410 - 29.411 - </sect1> 29.412 - <sect1 id="sec:hgext:patchbomb"> 29.413 - <title>Send changes via email with the <literal 29.414 - role="hg-ext">patchbomb</literal> extension</title> 29.415 - 29.416 - <para>Many projects have a culture of <quote>change 29.417 - review</quote>, in which people send their modifications to a 29.418 - mailing list for others to read and comment on before they 29.419 - commit the final version to a shared repository. Some projects 29.420 - have people who act as gatekeepers; they apply changes from 29.421 - other people to a repository to which those others don't have 29.422 - access.</para> 29.423 - 29.424 - <para>Mercurial makes it easy to send changes over email for 29.425 - review or application, via its <literal 29.426 - role="hg-ext">patchbomb</literal> extension. The extension is 29.427 - so named because changes are formatted as patches, and it's usual 29.428 - to send one changeset per email message. Sending a long series 29.429 - of changes by email is thus much like <quote>bombing</quote> the 29.430 - recipient's inbox, hence <quote>patchbomb</quote>.</para> 29.431 - 29.432 - <para>As usual, the basic configuration of the <literal 29.433 - role="hg-ext">patchbomb</literal> extension takes just one or 29.434 - two lines in your <filename role="special"> 29.435 - /.hgrc</filename>.</para> 29.436 - <programlisting>[extensions] 29.437 -patchbomb =</programlisting> 29.438 - <para>Once you've enabled the extension, you will have a new 29.439 - command available, named <command 29.440 - role="hg-ext-patchbomb">email</command>.</para> 29.441 - 29.442 - <para>The safest and best way to invoke the <command 29.443 - role="hg-ext-patchbomb">email</command> command is to 29.444 - <emphasis>always</emphasis> run it first with the <option 29.445 - role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option. 29.446 - This will show you what the command <emphasis>would</emphasis> 29.447 - send, without actually sending anything. Once you've had a 29.448 - quick glance over the changes and verified that you are sending 29.449 - the right ones, you can rerun the same command, with the <option 29.450 - role="hg-ext-patchbomb-cmd-email-opt">hg -n</option> option 29.451 - removed.</para> 29.452 - 29.453 - <para>The <command role="hg-ext-patchbomb">email</command> command 29.454 - accepts the same kind of revision syntax as every other 29.455 - Mercurial command. For example, this command will send every 29.456 - revision between 7 and <literal>tip</literal>, inclusive.</para> 29.457 - <programlisting>hg email -n 7:tip</programlisting> 29.458 - <para>You can also specify a <emphasis>repository</emphasis> to 29.459 - compare with. If you provide a repository but no revisions, the 29.460 - <command role="hg-ext-patchbomb">email</command> command will 29.461 - send all revisions in the local repository that are not present 29.462 - in the remote repository. If you additionally specify revisions 29.463 - or a branch name (the latter using the <option 29.464 - role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> option), 29.465 - this will constrain the revisions sent.</para> 29.466 - 29.467 - <para>It's perfectly safe to run the <command 29.468 - role="hg-ext-patchbomb">email</command> command without the 29.469 - names of the people you want to send to: if you do this, it will 29.470 - just prompt you for those values interactively. (If you're 29.471 - using a Linux or Unix-like system, you should have enhanced 29.472 - <literal>readline</literal>-style editing capabilities when 29.473 - entering those headers, too, which is useful.)</para> 29.474 - 29.475 - <para>When you are sending just one revision, the <command 29.476 - role="hg-ext-patchbomb">email</command> command will by 29.477 - default use the first line of the changeset description as the 29.478 - subject of the single email message it sends.</para> 29.479 - 29.480 - <para>If you send multiple revisions, the <command 29.481 - role="hg-ext-patchbomb">email</command> command will usually 29.482 - send one message per changeset. It will preface the series with 29.483 - an introductory message, in which you should describe the 29.484 - purpose of the series of changes you're sending.</para> 29.485 - 29.486 - <sect2> 29.487 - <title>Changing the behaviour of patchbombs</title> 29.488 - 29.489 - <para>Not every project has exactly the same conventions for 29.490 - sending changes in email; the <literal 29.491 - role="hg-ext">patchbomb</literal> extension tries to 29.492 - accommodate a number of variations through command line 29.493 - options.</para> 29.494 - <itemizedlist> 29.495 - <listitem><para>You can write a subject for the introductory 29.496 - message on the command line using the <option 29.497 - role="hg-ext-patchbomb-cmd-email-opt">hg -s</option> 29.498 - option. This takes one argument, the text of the subject 29.499 - to use.</para> 29.500 - </listitem> 29.501 - <listitem><para>To change the email address from which the 29.502 - messages originate, use the <option 29.503 - role="hg-ext-patchbomb-cmd-email-opt">hg -f</option> 29.504 - option. This takes one argument, the email address to 29.505 - use.</para> 29.506 - </listitem> 29.507 - <listitem><para>The default behaviour is to send unified diffs 29.508 - (see section <xref linkend="sec:mq:patch"/> for a 29.509 - description of the 29.510 - format), one per message. You can send a binary bundle 29.511 - instead with the <option 29.512 - role="hg-ext-patchbomb-cmd-email-opt">hg -b</option> 29.513 - option.</para> 29.514 - </listitem> 29.515 - <listitem><para>Unified diffs are normally prefaced with a 29.516 - metadata header. You can omit this, and send unadorned 29.517 - diffs, with the <option 29.518 - role="hg-ext-patchbomb-cmd-email-opt">hg 29.519 - --plain</option> option.</para> 29.520 - </listitem> 29.521 - <listitem><para>Diffs are normally sent <quote>inline</quote>, 29.522 - in the same body part as the description of a patch. This 29.523 - makes it easiest for the largest number of readers to 29.524 - quote and respond to parts of a diff, as some mail clients 29.525 - will only quote the first MIME body part in a message. If 29.526 - you'd prefer to send the description and the diff in 29.527 - separate body parts, use the <option 29.528 - role="hg-ext-patchbomb-cmd-email-opt">hg -a</option> 29.529 - option.</para> 29.530 - </listitem> 29.531 - <listitem><para>Instead of sending mail messages, you can 29.532 - write them to an <literal>mbox</literal>-format mail 29.533 - folder using the <option 29.534 - role="hg-ext-patchbomb-cmd-email-opt">hg -m</option> 29.535 - option. That option takes one argument, the name of the 29.536 - file to write to.</para> 29.537 - </listitem> 29.538 - <listitem><para>If you would like to add a 29.539 - <command>diffstat</command>-format summary to each patch, 29.540 - and one to the introductory message, use the <option 29.541 - role="hg-ext-patchbomb-cmd-email-opt">hg -d</option> 29.542 - option. The <command>diffstat</command> command displays 29.543 - a table containing the name of each file patched, the 29.544 - number of lines affected, and a histogram showing how much 29.545 - each file is modified. This gives readers a qualitative 29.546 - glance at how complex a patch is.</para> 29.547 - </listitem></itemizedlist> 29.548 - 29.549 - </sect2> 29.550 - </sect1> 29.551 -</chapter> 29.552 - 29.553 -<!-- 29.554 -local variables: 29.555 -sgml-parent-document: ("00book.xml" "book" "chapter") 29.556 -end: 29.557 --->