hgbook
diff en/ch06-collab.xml @ 559:b90b024729f1
WIP DocBook snapshot that all compiles. Mirabile dictu!
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Wed Feb 18 00:22:09 2009 -0800 (2009-02-18) |
parents | en/ch06-collab.tex@f72b7e6cbe90 |
children | dbe91bb622d8 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/en/ch06-collab.xml Wed Feb 18 00:22:09 2009 -0800 1.3 @@ -0,0 +1,1415 @@ 1.4 +<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> 1.5 + 1.6 +<chapter id="cha:collab"> 1.7 + <title>Collaborating with other people</title> 1.8 + 1.9 + <para>As a completely decentralised tool, Mercurial doesn't impose 1.10 + any policy on how people ought to work with each other. However, 1.11 + if you're new to distributed revision control, it helps to have 1.12 + some tools and examples in mind when you're thinking about 1.13 + possible workflow models.</para> 1.14 + 1.15 + <sect1> 1.16 + <title>Mercurial's web interface</title> 1.17 + 1.18 + <para>Mercurial has a powerful web interface that provides several 1.19 + useful capabilities.</para> 1.20 + 1.21 + <para>For interactive use, the web interface lets you browse a 1.22 + single repository or a collection of repositories. You can view 1.23 + the history of a repository, examine each change (comments and 1.24 + diffs), and view the contents of each directory and file.</para> 1.25 + 1.26 + <para>Also for human consumption, the web interface provides an 1.27 + RSS feed of the changes in a repository. This lets you 1.28 + <quote>subscribe</quote> to a repository using your favourite 1.29 + feed reader, and be automatically notified of activity in that 1.30 + repository as soon as it happens. I find this capability much 1.31 + more convenient than the model of subscribing to a mailing list 1.32 + to which notifications are sent, as it requires no additional 1.33 + configuration on the part of whoever is serving the 1.34 + repository.</para> 1.35 + 1.36 + <para>The web interface also lets remote users clone a repository, 1.37 + pull changes from it, and (when the server is configured to 1.38 + permit it) push changes back to it. Mercurial's HTTP tunneling 1.39 + protocol aggressively compresses data, so that it works 1.40 + efficiently even over low-bandwidth network connections.</para> 1.41 + 1.42 + <para>The easiest way to get started with the web interface is to 1.43 + use your web browser to visit an existing repository, such as 1.44 + the master Mercurial repository at <ulink 1.45 + url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para> 1.46 + 1.47 + <para>If you're interested in providing a web interface to your 1.48 + own repositories, Mercurial provides two ways to do this. The 1.49 + first is using the <command role="hg-cmd">hg serve</command> 1.50 + command, which is best suited to short-term 1.51 + <quote>lightweight</quote> serving. See section <xref 1.52 + linkend="sec:collab:serve"/> below for details of how to use 1.53 + this command. If you have a long-lived repository that you'd 1.54 + like to make permanently available, Mercurial has built-in 1.55 + support for the CGI (Common Gateway Interface) standard, which 1.56 + all common web servers support. See section <xref 1.57 + linkend="sec:collab:cgi"/> for details of CGI 1.58 + configuration.</para> 1.59 + 1.60 + </sect1> 1.61 + <sect1> 1.62 + <title>Collaboration models</title> 1.63 + 1.64 + <para>With a suitably flexible tool, making decisions about 1.65 + workflow is much more of a social engineering challenge than a 1.66 + technical one. Mercurial imposes few limitations on how you can 1.67 + structure the flow of work in a project, so it's up to you and 1.68 + your group to set up and live with a model that matches your own 1.69 + particular needs.</para> 1.70 + 1.71 + <sect2> 1.72 + <title>Factors to keep in mind</title> 1.73 + 1.74 + <para>The most important aspect of any model that you must keep 1.75 + in mind is how well it matches the needs and capabilities of 1.76 + the people who will be using it. This might seem 1.77 + self-evident; even so, you still can't afford to forget it for 1.78 + a moment.</para> 1.79 + 1.80 + <para>I once put together a workflow model that seemed to make 1.81 + perfect sense to me, but that caused a considerable amount of 1.82 + consternation and strife within my development team. In spite 1.83 + of my attempts to explain why we needed a complex set of 1.84 + branches, and how changes ought to flow between them, a few 1.85 + team members revolted. Even though they were smart people, 1.86 + they didn't want to pay attention to the constraints we were 1.87 + operating under, or face the consequences of those constraints 1.88 + in the details of the model that I was advocating.</para> 1.89 + 1.90 + <para>Don't sweep foreseeable social or technical problems under 1.91 + the rug. Whatever scheme you put into effect, you should plan 1.92 + for mistakes and problem scenarios. Consider adding automated 1.93 + machinery to prevent, or quickly recover from, trouble that 1.94 + you can anticipate. As an example, if you intend to have a 1.95 + branch with not-for-release changes in it, you'd do well to 1.96 + think early about the possibility that someone might 1.97 + accidentally merge those changes into a release branch. You 1.98 + could avoid this particular problem by writing a hook that 1.99 + prevents changes from being merged from an inappropriate 1.100 + branch.</para> 1.101 + 1.102 + </sect2> 1.103 + <sect2> 1.104 + <title>Informal anarchy</title> 1.105 + 1.106 + <para>I wouldn't suggest an <quote>anything goes</quote> 1.107 + approach as something sustainable, but it's a model that's 1.108 + easy to grasp, and it works perfectly well in a few unusual 1.109 + situations.</para> 1.110 + 1.111 + <para>As one example, many projects have a loose-knit group of 1.112 + collaborators who rarely physically meet each other. Some 1.113 + groups like to overcome the isolation of working at a distance 1.114 + by organising occasional <quote>sprints</quote>. In a sprint, 1.115 + a number of people get together in a single location (a 1.116 + company's conference room, a hotel meeting room, that kind of 1.117 + place) and spend several days more or less locked in there, 1.118 + hacking intensely on a handful of projects.</para> 1.119 + 1.120 + <para>A sprint is the perfect place to use the <command 1.121 + role="hg-cmd">hg serve</command> command, since <command 1.122 + role="hg-cmd">hg serve</command> does not requires any fancy 1.123 + server infrastructure. You can get started with <command 1.124 + role="hg-cmd">hg serve</command> in moments, by reading 1.125 + section <xref linkend="sec:collab:serve"/> below. Then simply 1.126 + tell 1.127 + the person next to you that you're running a server, send the 1.128 + URL to them in an instant message, and you immediately have a 1.129 + quick-turnaround way to work together. They can type your URL 1.130 + into their web browser and quickly review your changes; or 1.131 + they can pull a bugfix from you and verify it; or they can 1.132 + clone a branch containing a new feature and try it out.</para> 1.133 + 1.134 + <para>The charm, and the problem, with doing things in an ad hoc 1.135 + fashion like this is that only people who know about your 1.136 + changes, and where they are, can see them. Such an informal 1.137 + approach simply doesn't scale beyond a handful people, because 1.138 + each individual needs to know about $n$ different repositories 1.139 + to pull from.</para> 1.140 + 1.141 + </sect2> 1.142 + <sect2> 1.143 + <title>A single central repository</title> 1.144 + 1.145 + <para>For smaller projects migrating from a centralised revision 1.146 + control tool, perhaps the easiest way to get started is to 1.147 + have changes flow through a single shared central repository. 1.148 + This is also the most common <quote>building block</quote> for 1.149 + more ambitious workflow schemes.</para> 1.150 + 1.151 + <para>Contributors start by cloning a copy of this repository. 1.152 + They can pull changes from it whenever they need to, and some 1.153 + (perhaps all) developers have permission to push a change back 1.154 + when they're ready for other people to see it.</para> 1.155 + 1.156 + <para>Under this model, it can still often make sense for people 1.157 + to pull changes directly from each other, without going 1.158 + through the central repository. Consider a case in which I 1.159 + have a tentative bug fix, but I am worried that if I were to 1.160 + publish it to the central repository, it might subsequently 1.161 + break everyone else's trees as they pull it. To reduce the 1.162 + potential for damage, I can ask you to clone my repository 1.163 + into a temporary repository of your own and test it. This 1.164 + lets us put off publishing the potentially unsafe change until 1.165 + it has had a little testing.</para> 1.166 + 1.167 + <para>In this kind of scenario, people usually use the 1.168 + <command>ssh</command> protocol to securely push changes to 1.169 + the central repository, as documented in section <xref 1.170 + linkend="sec:collab:ssh"/>. It's also 1.171 + usual to publish a read-only copy of the repository over HTTP 1.172 + using CGI, as in section <xref linkend="sec:collab:cgi"/>. 1.173 + Publishing over HTTP 1.174 + satisfies the needs of people who don't have push access, and 1.175 + those who want to use web browsers to browse the repository's 1.176 + history.</para> 1.177 + 1.178 + </sect2> 1.179 + <sect2> 1.180 + <title>Working with multiple branches</title> 1.181 + 1.182 + <para>Projects of any significant size naturally tend to make 1.183 + progress on several fronts simultaneously. In the case of 1.184 + software, it's common for a project to go through periodic 1.185 + official releases. A release might then go into 1.186 + <quote>maintenance mode</quote> for a while after its first 1.187 + publication; maintenance releases tend to contain only bug 1.188 + fixes, not new features. In parallel with these maintenance 1.189 + releases, one or more future releases may be under 1.190 + development. People normally use the word 1.191 + <quote>branch</quote> to refer to one of these many slightly 1.192 + different directions in which development is 1.193 + proceeding.</para> 1.194 + 1.195 + <para>Mercurial is particularly well suited to managing a number 1.196 + of simultaneous, but not identical, branches. Each 1.197 + <quote>development direction</quote> can live in its own 1.198 + central repository, and you can merge changes from one to 1.199 + another as the need arises. Because repositories are 1.200 + independent of each other, unstable changes in a development 1.201 + branch will never affect a stable branch unless someone 1.202 + explicitly merges those changes in.</para> 1.203 + 1.204 + <para>Here's an example of how this can work in practice. Let's 1.205 + say you have one <quote>main branch</quote> on a central 1.206 + server. <!-- &interaction.branching.init; --> People clone it, 1.207 + make changes locally, test them, and push them back.</para> 1.208 + 1.209 + <para>Once the main branch reaches a release milestone, you can 1.210 + use the <command role="hg-cmd">hg tag</command> command to 1.211 + give a permanent name to the milestone revision. <!-- 1.212 + &interaction.branching.tag; --> Let's say some ongoing 1.213 + development occurs on the main branch. <!-- 1.214 + &interaction.branching.main; --> Using the tag that was 1.215 + recorded at the milestone, people who clone that repository at 1.216 + any time in the future can use <command role="hg-cmd">hg 1.217 + update</command> to get a copy of the working directory 1.218 + exactly as it was when that tagged revision was committed. 1.219 + <!-- &interaction.branching.update; --></para> 1.220 + 1.221 + <para>In addition, immediately after the main branch is tagged, 1.222 + someone can then clone the main branch on the server to a new 1.223 + <quote>stable</quote> branch, also on the server. <!-- 1.224 + &interaction.branching.clone; --></para> 1.225 + 1.226 + <para>Someone who needs to make a change to the stable branch 1.227 + can then clone <emphasis>that</emphasis> repository, make 1.228 + their changes, commit, and push their changes back there. <!-- 1.229 + &interaction.branching.stable; --> Because Mercurial 1.230 + repositories are independent, and Mercurial doesn't move 1.231 + changes around automatically, the stable and main branches are 1.232 + <emphasis>isolated</emphasis> from each other. The changes 1.233 + that you made on the main branch don't <quote>leak</quote> to 1.234 + the stable branch, and vice versa.</para> 1.235 + 1.236 + <para>You'll often want all of your bugfixes on the stable 1.237 + branch to show up on the main branch, too. Rather than 1.238 + rewrite a bugfix on the main branch, you can simply pull and 1.239 + merge changes from the stable to the main branch, and 1.240 + Mercurial will bring those bugfixes in for you. <!-- 1.241 + &interaction.branching.merge; --> The main branch will still 1.242 + contain changes that are not on the stable branch, but it will 1.243 + also contain all of the bugfixes from the stable branch. The 1.244 + stable branch remains unaffected by these changes.</para> 1.245 + 1.246 + </sect2> 1.247 + <sect2> 1.248 + <title>Feature branches</title> 1.249 + 1.250 + <para>For larger projects, an effective way to manage change is 1.251 + to break up a team into smaller groups. Each group has a 1.252 + shared branch of its own, cloned from a single 1.253 + <quote>master</quote> branch used by the entire project. 1.254 + People working on an individual branch are typically quite 1.255 + isolated from developments on other branches.</para> 1.256 + 1.257 + <informalfigure id="fig:collab:feature-branches"> 1.258 + <mediaobject><imageobject><imagedata 1.259 + fileref="feature-branches"/></imageobject><textobject><phrase>XXX 1.260 + add text</phrase></textobject><caption><para>Feature 1.261 + branches</para></caption></mediaobject> 1.262 + </informalfigure> 1.263 + 1.264 + <para>When a particular feature is deemed to be in suitable 1.265 + shape, someone on that feature team pulls and merges from the 1.266 + master branch into the feature branch, then pushes back up to 1.267 + the master branch.</para> 1.268 + 1.269 + </sect2> 1.270 + <sect2> 1.271 + <title>The release train</title> 1.272 + 1.273 + <para>Some projects are organised on a <quote>train</quote> 1.274 + basis: a release is scheduled to happen every few months, and 1.275 + whatever features are ready when the <quote>train</quote> is 1.276 + ready to leave are allowed in.</para> 1.277 + 1.278 + <para>This model resembles working with feature branches. The 1.279 + difference is that when a feature branch misses a train, 1.280 + someone on the feature team pulls and merges the changes that 1.281 + went out on that train release into the feature branch, and 1.282 + the team continues its work on top of that release so that 1.283 + their feature can make the next release.</para> 1.284 + 1.285 + </sect2> 1.286 + <sect2> 1.287 + <title>The Linux kernel model</title> 1.288 + 1.289 + <para>The development of the Linux kernel has a shallow 1.290 + hierarchical structure, surrounded by a cloud of apparent 1.291 + chaos. Because most Linux developers use 1.292 + <command>git</command>, a distributed revision control tool 1.293 + with capabilities similar to Mercurial, it's useful to 1.294 + describe the way work flows in that environment; if you like 1.295 + the ideas, the approach translates well across tools.</para> 1.296 + 1.297 + <para>At the center of the community sits Linus Torvalds, the 1.298 + creator of Linux. He publishes a single source repository 1.299 + that is considered the <quote>authoritative</quote> current 1.300 + tree by the entire developer community. Anyone can clone 1.301 + Linus's tree, but he is very choosy about whose trees he pulls 1.302 + from.</para> 1.303 + 1.304 + <para>Linus has a number of <quote>trusted lieutenants</quote>. 1.305 + As a general rule, he pulls whatever changes they publish, in 1.306 + most cases without even reviewing those changes. Some of 1.307 + those lieutenants are generally agreed to be 1.308 + <quote>maintainers</quote>, responsible for specific 1.309 + subsystems within the kernel. If a random kernel hacker wants 1.310 + to make a change to a subsystem that they want to end up in 1.311 + Linus's tree, they must find out who the subsystem's 1.312 + maintainer is, and ask that maintainer to take their change. 1.313 + If the maintainer reviews their changes and agrees to take 1.314 + them, they'll pass them along to Linus in due course.</para> 1.315 + 1.316 + <para>Individual lieutenants have their own approaches to 1.317 + reviewing, accepting, and publishing changes; and for deciding 1.318 + when to feed them to Linus. In addition, there are several 1.319 + well known branches that people use for different purposes. 1.320 + For example, a few people maintain <quote>stable</quote> 1.321 + repositories of older versions of the kernel, to which they 1.322 + apply critical fixes as needed. Some maintainers publish 1.323 + multiple trees: one for experimental changes; one for changes 1.324 + that they are about to feed upstream; and so on. Others just 1.325 + publish a single tree.</para> 1.326 + 1.327 + <para>This model has two notable features. The first is that 1.328 + it's <quote>pull only</quote>. You have to ask, convince, or 1.329 + beg another developer to take a change from you, because there 1.330 + are almost no trees to which more than one person can push, 1.331 + and there's no way to push changes into a tree that someone 1.332 + else controls.</para> 1.333 + 1.334 + <para>The second is that it's based on reputation and acclaim. 1.335 + If you're an unknown, Linus will probably ignore changes from 1.336 + you without even responding. But a subsystem maintainer will 1.337 + probably review them, and will likely take them if they pass 1.338 + their criteria for suitability. The more <quote>good</quote> 1.339 + changes you contribute to a maintainer, the more likely they 1.340 + are to trust your judgment and accept your changes. If you're 1.341 + well-known and maintain a long-lived branch for something 1.342 + Linus hasn't yet accepted, people with similar interests may 1.343 + pull your changes regularly to keep up with your work.</para> 1.344 + 1.345 + <para>Reputation and acclaim don't necessarily cross subsystem 1.346 + or <quote>people</quote> boundaries. If you're a respected 1.347 + but specialised storage hacker, and you try to fix a 1.348 + networking bug, that change will receive a level of scrutiny 1.349 + from a network maintainer comparable to a change from a 1.350 + complete stranger.</para> 1.351 + 1.352 + <para>To people who come from more orderly project backgrounds, 1.353 + the comparatively chaotic Linux kernel development process 1.354 + often seems completely insane. It's subject to the whims of 1.355 + individuals; people make sweeping changes whenever they deem 1.356 + it appropriate; and the pace of development is astounding. 1.357 + And yet Linux is a highly successful, well-regarded piece of 1.358 + software.</para> 1.359 + 1.360 + </sect2> 1.361 + <sect2> 1.362 + <title>Pull-only versus shared-push collaboration</title> 1.363 + 1.364 + <para>A perpetual source of heat in the open source community is 1.365 + whether a development model in which people only ever pull 1.366 + changes from others is <quote>better than</quote> one in which 1.367 + multiple people can push changes to a shared 1.368 + repository.</para> 1.369 + 1.370 + <para>Typically, the backers of the shared-push model use tools 1.371 + that actively enforce this approach. If you're using a 1.372 + centralised revision control tool such as Subversion, there's 1.373 + no way to make a choice over which model you'll use: the tool 1.374 + gives you shared-push, and if you want to do anything else, 1.375 + you'll have to roll your own approach on top (such as applying 1.376 + a patch by hand).</para> 1.377 + 1.378 + <para>A good distributed revision control tool, such as 1.379 + Mercurial, will support both models. You and your 1.380 + collaborators can then structure how you work together based 1.381 + on your own needs and preferences, not on what contortions 1.382 + your tools force you into.</para> 1.383 + 1.384 + </sect2> 1.385 + <sect2> 1.386 + <title>Where collaboration meets branch management</title> 1.387 + 1.388 + <para>Once you and your team set up some shared repositories and 1.389 + start propagating changes back and forth between local and 1.390 + shared repos, you begin to face a related, but slightly 1.391 + different challenge: that of managing the multiple directions 1.392 + in which your team may be moving at once. Even though this 1.393 + subject is intimately related to how your team collaborates, 1.394 + it's dense enough to merit treatment of its own, in chapter 1.395 + <xref linkend="chap:branch"/>.</para> 1.396 + 1.397 + </sect2> 1.398 + </sect1> 1.399 + <sect1> 1.400 + <title>The technical side of sharing</title> 1.401 + 1.402 + <para>The remainder of this chapter is devoted to the question of 1.403 + serving data to your collaborators.</para> 1.404 + 1.405 + </sect1> 1.406 + <sect1 id="sec:collab:serve"> 1.407 + <title>Informal sharing with <command role="hg-cmd">hg 1.408 + serve</command></title> 1.409 + 1.410 + <para>Mercurial's <command role="hg-cmd">hg serve</command> 1.411 + command is wonderfully suited to small, tight-knit, and 1.412 + fast-paced group environments. It also provides a great way to 1.413 + get a feel for using Mercurial commands over a network.</para> 1.414 + 1.415 + <para>Run <command role="hg-cmd">hg serve</command> inside a 1.416 + repository, and in under a second it will bring up a specialised 1.417 + HTTP server; this will accept connections from any client, and 1.418 + serve up data for that repository until you terminate it. 1.419 + Anyone who knows the URL of the server you just started, and can 1.420 + talk to your computer over the network, can then use a web 1.421 + browser or Mercurial to read data from that repository. A URL 1.422 + for a <command role="hg-cmd">hg serve</command> instance running 1.423 + on a laptop is likely to look something like 1.424 + <literal>http://my-laptop.local:8000/</literal>.</para> 1.425 + 1.426 + <para>The <command role="hg-cmd">hg serve</command> command is 1.427 + <emphasis>not</emphasis> a general-purpose web server. It can do 1.428 + only two things:</para> 1.429 + <itemizedlist> 1.430 + <listitem><para>Allow people to browse the history of the 1.431 + repository it's serving, from their normal web 1.432 + browsers.</para> 1.433 + </listitem> 1.434 + <listitem><para>Speak Mercurial's wire protocol, so that people 1.435 + can <command role="hg-cmd">hg clone</command> or <command 1.436 + role="hg-cmd">hg pull</command> changes from that 1.437 + repository.</para> 1.438 + </listitem></itemizedlist> 1.439 + <para>In particular, <command role="hg-cmd">hg serve</command> 1.440 + won't allow remote users to <emphasis>modify</emphasis> your 1.441 + repository. It's intended for read-only use.</para> 1.442 + 1.443 + <para>If you're getting started with Mercurial, there's nothing to 1.444 + prevent you from using <command role="hg-cmd">hg serve</command> 1.445 + to serve up a repository on your own computer, then use commands 1.446 + like <command role="hg-cmd">hg clone</command>, <command 1.447 + role="hg-cmd">hg incoming</command>, and so on to talk to that 1.448 + server as if the repository was hosted remotely. This can help 1.449 + you to quickly get acquainted with using commands on 1.450 + network-hosted repositories.</para> 1.451 + 1.452 + <sect2> 1.453 + <title>A few things to keep in mind</title> 1.454 + 1.455 + <para>Because it provides unauthenticated read access to all 1.456 + clients, you should only use <command role="hg-cmd">hg 1.457 + serve</command> in an environment where you either don't 1.458 + care, or have complete control over, who can access your 1.459 + network and pull data from your repository.</para> 1.460 + 1.461 + <para>The <command role="hg-cmd">hg serve</command> command 1.462 + knows nothing about any firewall software you might have 1.463 + installed on your system or network. It cannot detect or 1.464 + control your firewall software. If other people are unable to 1.465 + talk to a running <command role="hg-cmd">hg serve</command> 1.466 + instance, the second thing you should do 1.467 + (<emphasis>after</emphasis> you make sure that they're using 1.468 + the correct URL) is check your firewall configuration.</para> 1.469 + 1.470 + <para>By default, <command role="hg-cmd">hg serve</command> 1.471 + listens for incoming connections on port 8000. If another 1.472 + process is already listening on the port you want to use, you 1.473 + can specify a different port to listen on using the <option 1.474 + role="hg-opt-serve">-p</option> option.</para> 1.475 + 1.476 + <para>Normally, when <command role="hg-cmd">hg serve</command> 1.477 + starts, it prints no output, which can be a bit unnerving. If 1.478 + you'd like to confirm that it is indeed running correctly, and 1.479 + find out what URL you should send to your collaborators, start 1.480 + it with the <option role="hg-opt-global">-v</option> 1.481 + option.</para> 1.482 + 1.483 + </sect2> 1.484 + </sect1> 1.485 + <sect1 id="sec:collab:ssh"> 1.486 + <title>Using the Secure Shell (ssh) protocol</title> 1.487 + 1.488 + <para>You can pull and push changes securely over a network 1.489 + connection using the Secure Shell (<literal>ssh</literal>) 1.490 + protocol. To use this successfully, you may have to do a little 1.491 + bit of configuration on the client or server sides.</para> 1.492 + 1.493 + <para>If you're not familiar with ssh, it's a network protocol 1.494 + that lets you securely communicate with another computer. To 1.495 + use it with Mercurial, you'll be setting up one or more user 1.496 + accounts on a server so that remote users can log in and execute 1.497 + commands.</para> 1.498 + 1.499 + <para>(If you <emphasis>are</emphasis> familiar with ssh, you'll 1.500 + probably find some of the material that follows to be elementary 1.501 + in nature.)</para> 1.502 + 1.503 + <sect2> 1.504 + <title>How to read and write ssh URLs</title> 1.505 + 1.506 + <para>An ssh URL tends to look like this:</para> 1.507 + <programlisting>ssh://bos@hg.serpentine.com:22/hg/hgbook</programlisting> 1.508 + <orderedlist> 1.509 + <listitem><para>The <quote><literal>ssh://</literal></quote> 1.510 + part tells Mercurial to use the ssh protocol.</para> 1.511 + </listitem> 1.512 + <listitem><para>The <quote><literal>bos@</literal></quote> 1.513 + component indicates what username to log into the server 1.514 + as. You can leave this out if the remote username is the 1.515 + same as your local username.</para> 1.516 + </listitem> 1.517 + <listitem><para>The 1.518 + <quote><literal>hg.serpentine.com</literal></quote> gives 1.519 + the hostname of the server to log into.</para> 1.520 + </listitem> 1.521 + <listitem><para>The <quote>:22</quote> identifies the port 1.522 + number to connect to the server on. The default port is 1.523 + 22, so you only need to specify this part if you're 1.524 + <emphasis>not</emphasis> using port 22.</para> 1.525 + </listitem> 1.526 + <listitem><para>The remainder of the URL is the local path to 1.527 + the repository on the server.</para> 1.528 + </listitem></orderedlist> 1.529 + 1.530 + <para>There's plenty of scope for confusion with the path 1.531 + component of ssh URLs, as there is no standard way for tools 1.532 + to interpret it. Some programs behave differently than others 1.533 + when dealing with these paths. This isn't an ideal situation, 1.534 + but it's unlikely to change. Please read the following 1.535 + paragraphs carefully.</para> 1.536 + 1.537 + <para>Mercurial treats the path to a repository on the server as 1.538 + relative to the remote user's home directory. For example, if 1.539 + user <literal>foo</literal> on the server has a home directory 1.540 + of <filename class="directory">/home/foo</filename>, then an 1.541 + ssh URL that contains a path component of <filename 1.542 + class="directory">bar</filename> <emphasis>really</emphasis> 1.543 + refers to the directory <filename 1.544 + class="directory">/home/foo/bar</filename>.</para> 1.545 + 1.546 + <para>If you want to specify a path relative to another user's 1.547 + home directory, you can use a path that starts with a tilde 1.548 + character followed by the user's name (let's call them 1.549 + <literal>otheruser</literal>), like this.</para> 1.550 + <programlisting>ssh://server/~otheruser/hg/repo</programlisting> 1.551 + 1.552 + <para>And if you really want to specify an 1.553 + <emphasis>absolute</emphasis> path on the server, begin the 1.554 + path component with two slashes, as in this example.</para> 1.555 + <programlisting>ssh://server//absolute/path</programlisting> 1.556 + 1.557 + </sect2> 1.558 + <sect2> 1.559 + <title>Finding an ssh client for your system</title> 1.560 + 1.561 + <para>Almost every Unix-like system comes with OpenSSH 1.562 + preinstalled. If you're using such a system, run 1.563 + <literal>which ssh</literal> to find out if the 1.564 + <command>ssh</command> command is installed (it's usually in 1.565 + <filename class="directory">/usr/bin</filename>). In the 1.566 + unlikely event that it isn't present, take a look at your 1.567 + system documentation to figure out how to install it.</para> 1.568 + 1.569 + <para>On Windows, you'll first need to download a suitable ssh 1.570 + client. There are two alternatives.</para> 1.571 + <itemizedlist> 1.572 + <listitem><para>Simon Tatham's excellent PuTTY package 1.573 + <citation>web:putty</citation> provides a complete suite 1.574 + of ssh client commands.</para> 1.575 + </listitem> 1.576 + <listitem><para>If you have a high tolerance for pain, you can 1.577 + use the Cygwin port of OpenSSH.</para> 1.578 + </listitem></itemizedlist> 1.579 + <para>In either case, you'll need to edit your \hgini\ file to 1.580 + tell Mercurial where to find the actual client command. For 1.581 + example, if you're using PuTTY, you'll need to use the 1.582 + <command>plink</command> command as a command-line ssh 1.583 + client.</para> 1.584 + <programlisting>[ui] ssh = C:/path/to/plink.exe -ssh -i 1.585 + "C:/path/to/my/private/key"</programlisting> 1.586 + 1.587 + <note> 1.588 + <para> The path to <command>plink</command> shouldn't contain 1.589 + any whitespace characters, or Mercurial may not be able to 1.590 + run it correctly (so putting it in <filename 1.591 + class="directory">C:\\Program Files</filename> is probably 1.592 + not a good idea).</para> 1.593 + </note> 1.594 + 1.595 + </sect2> 1.596 + <sect2> 1.597 + <title>Generating a key pair</title> 1.598 + 1.599 + <para>To avoid the need to repetitively type a password every 1.600 + time you need to use your ssh client, I recommend generating a 1.601 + key pair. On a Unix-like system, the 1.602 + <command>ssh-keygen</command> command will do the trick. On 1.603 + Windows, if you're using PuTTY, the 1.604 + <command>puttygen</command> command is what you'll 1.605 + need.</para> 1.606 + 1.607 + <para>When you generate a key pair, it's usually 1.608 + <emphasis>highly</emphasis> advisable to protect it with a 1.609 + passphrase. (The only time that you might not want to do this 1.610 + is when you're using the ssh protocol for automated tasks on a 1.611 + secure network.)</para> 1.612 + 1.613 + <para>Simply generating a key pair isn't enough, however. 1.614 + You'll need to add the public key to the set of authorised 1.615 + keys for whatever user you're logging in remotely as. For 1.616 + servers using OpenSSH (the vast majority), this will mean 1.617 + adding the public key to a list in a file called <filename 1.618 + role="special">authorized_keys</filename> in their <filename 1.619 + role="special" class="directory">.ssh</filename> 1.620 + directory.</para> 1.621 + 1.622 + <para>On a Unix-like system, your public key will have a 1.623 + <filename>.pub</filename> extension. If you're using 1.624 + <command>puttygen</command> on Windows, you can save the 1.625 + public key to a file of your choosing, or paste it from the 1.626 + window it's displayed in straight into the <filename 1.627 + role="special">authorized_keys</filename> file.</para> 1.628 + 1.629 + </sect2> 1.630 + <sect2> 1.631 + <title>Using an authentication agent</title> 1.632 + 1.633 + <para>An authentication agent is a daemon that stores 1.634 + passphrases in memory (so it will forget passphrases if you 1.635 + log out and log back in again). An ssh client will notice if 1.636 + it's running, and query it for a passphrase. If there's no 1.637 + authentication agent running, or the agent doesn't store the 1.638 + necessary passphrase, you'll have to type your passphrase 1.639 + every time Mercurial tries to communicate with a server on 1.640 + your behalf (e.g. whenever you pull or push changes).</para> 1.641 + 1.642 + <para>The downside of storing passphrases in an agent is that 1.643 + it's possible for a well-prepared attacker to recover the 1.644 + plain text of your passphrases, in some cases even if your 1.645 + system has been power-cycled. You should make your own 1.646 + judgment as to whether this is an acceptable risk. It 1.647 + certainly saves a lot of repeated typing.</para> 1.648 + 1.649 + <para>On Unix-like systems, the agent is called 1.650 + <command>ssh-agent</command>, and it's often run automatically 1.651 + for you when you log in. You'll need to use the 1.652 + <command>ssh-add</command> command to add passphrases to the 1.653 + agent's store. On Windows, if you're using PuTTY, the 1.654 + <command>pageant</command> command acts as the agent. It adds 1.655 + an icon to your system tray that will let you manage stored 1.656 + passphrases.</para> 1.657 + 1.658 + </sect2> 1.659 + <sect2> 1.660 + <title>Configuring the server side properly</title> 1.661 + 1.662 + <para>Because ssh can be fiddly to set up if you're new to it, 1.663 + there's a variety of things that can go wrong. Add Mercurial 1.664 + on top, and there's plenty more scope for head-scratching. 1.665 + Most of these potential problems occur on the server side, not 1.666 + the client side. The good news is that once you've gotten a 1.667 + configuration working, it will usually continue to work 1.668 + indefinitely.</para> 1.669 + 1.670 + <para>Before you try using Mercurial to talk to an ssh server, 1.671 + it's best to make sure that you can use the normal 1.672 + <command>ssh</command> or <command>putty</command> command to 1.673 + talk to the server first. If you run into problems with using 1.674 + these commands directly, Mercurial surely won't work. Worse, 1.675 + it will obscure the underlying problem. Any time you want to 1.676 + debug ssh-related Mercurial problems, you should drop back to 1.677 + making sure that plain ssh client commands work first, 1.678 + <emphasis>before</emphasis> you worry about whether there's a 1.679 + problem with Mercurial.</para> 1.680 + 1.681 + <para>The first thing to be sure of on the server side is that 1.682 + you can actually log in from another machine at all. If you 1.683 + can't use <command>ssh</command> or <command>putty</command> 1.684 + to log in, the error message you get may give you a few hints 1.685 + as to what's wrong. The most common problems are as 1.686 + follows.</para> 1.687 + <itemizedlist> 1.688 + <listitem><para>If you get a <quote>connection refused</quote> 1.689 + error, either there isn't an SSH daemon running on the 1.690 + server at all, or it's inaccessible due to firewall 1.691 + configuration.</para> 1.692 + </listitem> 1.693 + <listitem><para>If you get a <quote>no route to host</quote> 1.694 + error, you either have an incorrect address for the server 1.695 + or a seriously locked down firewall that won't admit its 1.696 + existence at all.</para> 1.697 + </listitem> 1.698 + <listitem><para>If you get a <quote>permission denied</quote> 1.699 + error, you may have mistyped the username on the server, 1.700 + or you could have mistyped your key's passphrase or the 1.701 + remote user's password.</para> 1.702 + </listitem></itemizedlist> 1.703 + <para>In summary, if you're having trouble talking to the 1.704 + server's ssh daemon, first make sure that one is running at 1.705 + all. On many systems it will be installed, but disabled, by 1.706 + default. Once you're done with this step, you should then 1.707 + check that the server's firewall is configured to allow 1.708 + incoming connections on the port the ssh daemon is listening 1.709 + on (usually 22). Don't worry about more exotic possibilities 1.710 + for misconfiguration until you've checked these two 1.711 + first.</para> 1.712 + 1.713 + <para>If you're using an authentication agent on the client side 1.714 + to store passphrases for your keys, you ought to be able to 1.715 + log into the server without being prompted for a passphrase or 1.716 + a password. If you're prompted for a passphrase, there are a 1.717 + few possible culprits.</para> 1.718 + <itemizedlist> 1.719 + <listitem><para>You might have forgotten to use 1.720 + <command>ssh-add</command> or <command>pageant</command> 1.721 + to store the passphrase.</para> 1.722 + </listitem> 1.723 + <listitem><para>You might have stored the passphrase for the 1.724 + wrong key.</para> 1.725 + </listitem></itemizedlist> 1.726 + <para>If you're being prompted for the remote user's password, 1.727 + there are another few possible problems to check.</para> 1.728 + <itemizedlist> 1.729 + <listitem><para>Either the user's home directory or their 1.730 + <filename role="special" class="directory">.ssh</filename> 1.731 + directory might have excessively liberal permissions. As 1.732 + a result, the ssh daemon will not trust or read their 1.733 + <filename role="special">authorized_keys</filename> file. 1.734 + For example, a group-writable home or <filename 1.735 + role="special" class="directory">.ssh</filename> 1.736 + directory will often cause this symptom.</para> 1.737 + </listitem> 1.738 + <listitem><para>The user's <filename 1.739 + role="special">authorized_keys</filename> file may have 1.740 + a problem. If anyone other than the user owns or can write 1.741 + to that file, the ssh daemon will not trust or read 1.742 + it.</para> 1.743 + </listitem></itemizedlist> 1.744 + 1.745 + <para>In the ideal world, you should be able to run the 1.746 + following command successfully, and it should print exactly 1.747 + one line of output, the current date and time.</para> 1.748 + <programlisting>ssh myserver date</programlisting> 1.749 + 1.750 + <para>If, on your server, you have login scripts that print 1.751 + banners or other junk even when running non-interactive 1.752 + commands like this, you should fix them before you continue, 1.753 + so that they only print output if they're run interactively. 1.754 + Otherwise these banners will at least clutter up Mercurial's 1.755 + output. Worse, they could potentially cause problems with 1.756 + running Mercurial commands remotely. Mercurial makes tries to 1.757 + detect and ignore banners in non-interactive 1.758 + <command>ssh</command> sessions, but it is not foolproof. (If 1.759 + you're editing your login scripts on your server, the usual 1.760 + way to see if a login script is running in an interactive 1.761 + shell is to check the return code from the command 1.762 + <literal>tty -s</literal>.)</para> 1.763 + 1.764 + <para>Once you've verified that plain old ssh is working with 1.765 + your server, the next step is to ensure that Mercurial runs on 1.766 + the server. The following command should run 1.767 + successfully:</para> 1.768 + <programlisting>ssh myserver hg version</programlisting> 1.769 + <para>If you see an error message instead of normal <command 1.770 + role="hg-cmd">hg version</command> output, this is usually 1.771 + because you haven't installed Mercurial to <filename 1.772 + class="directory">/usr/bin</filename>. Don't worry if this 1.773 + is the case; you don't need to do that. But you should check 1.774 + for a few possible problems.</para> 1.775 + <itemizedlist> 1.776 + <listitem><para>Is Mercurial really installed on the server at 1.777 + all? I know this sounds trivial, but it's worth 1.778 + checking!</para> 1.779 + </listitem> 1.780 + <listitem><para>Maybe your shell's search path (usually set 1.781 + via the <envar>PATH</envar> environment variable) is 1.782 + simply misconfigured.</para> 1.783 + </listitem> 1.784 + <listitem><para>Perhaps your <envar>PATH</envar> environment 1.785 + variable is only being set to point to the location of the 1.786 + <command>hg</command> executable if the login session is 1.787 + interactive. This can happen if you're setting the path 1.788 + in the wrong shell login script. See your shell's 1.789 + documentation for details.</para> 1.790 + </listitem> 1.791 + <listitem><para>The <envar>PYTHONPATH</envar> environment 1.792 + variable may need to contain the path to the Mercurial 1.793 + Python modules. It might not be set at all; it could be 1.794 + incorrect; or it may be set only if the login is 1.795 + interactive.</para> 1.796 + </listitem></itemizedlist> 1.797 + 1.798 + <para>If you can run <command role="hg-cmd">hg version</command> 1.799 + over an ssh connection, well done! You've got the server and 1.800 + client sorted out. You should now be able to use Mercurial to 1.801 + access repositories hosted by that username on that server. 1.802 + If you run into problems with Mercurial and ssh at this point, 1.803 + try using the <option role="hg-opt-global">--debug</option> 1.804 + option to get a clearer picture of what's going on.</para> 1.805 + 1.806 + </sect2> 1.807 + <sect2> 1.808 + <title>Using compression with ssh</title> 1.809 + 1.810 + <para>Mercurial does not compress data when it uses the ssh 1.811 + protocol, because the ssh protocol can transparently compress 1.812 + data. However, the default behaviour of ssh clients is 1.813 + <emphasis>not</emphasis> to request compression.</para> 1.814 + 1.815 + <para>Over any network other than a fast LAN (even a wireless 1.816 + network), using compression is likely to significantly speed 1.817 + up Mercurial's network operations. For example, over a WAN, 1.818 + someone measured compression as reducing the amount of time 1.819 + required to clone a particularly large repository from 51 1.820 + minutes to 17 minutes.</para> 1.821 + 1.822 + <para>Both <command>ssh</command> and <command>plink</command> 1.823 + accept a <option role="cmd-opt-ssh">-C</option> option which 1.824 + turns on compression. You can easily edit your <filename 1.825 + role="special"> /.hgrc</filename>\ to enable compression for 1.826 + all of Mercurial's uses of the ssh protocol.</para> 1.827 + <programlisting>[ui] ssh = ssh -C</programlisting> 1.828 + 1.829 + <para>If you use <command>ssh</command>, you can configure it to 1.830 + always use compression when talking to your server. To do 1.831 + this, edit your <filename 1.832 + role="special">.ssh/config</filename> file (which may not 1.833 + yet exist), as follows.</para> 1.834 + <programlisting>Host hg Compression yes HostName 1.835 + hg.example.com</programlisting> 1.836 + <para>This defines an alias, <literal>hg</literal>. When you 1.837 + use it on the <command>ssh</command> command line or in a 1.838 + Mercurial <literal>ssh</literal>-protocol URL, it will cause 1.839 + <command>ssh</command> to connect to 1.840 + <literal>hg.example.com</literal> and use compression. This 1.841 + gives you both a shorter name to type and compression, each of 1.842 + which is a good thing in its own right.</para> 1.843 + 1.844 + </sect2> 1.845 + </sect1> 1.846 + <sect1 id="sec:collab:cgi"> 1.847 + <title>Serving over HTTP using CGI</title> 1.848 + 1.849 + <para>Depending on how ambitious you are, configuring Mercurial's 1.850 + CGI interface can take anything from a few moments to several 1.851 + hours.</para> 1.852 + 1.853 + <para>We'll begin with the simplest of examples, and work our way 1.854 + towards a more complex configuration. Even for the most basic 1.855 + case, you're almost certainly going to need to read and modify 1.856 + your web server's configuration.</para> 1.857 + 1.858 + <note> 1.859 + <para> Configuring a web server is a complex, fiddly, and 1.860 + highly system-dependent activity. I can't possibly give you 1.861 + instructions that will cover anything like all of the cases 1.862 + you will encounter. Please use your discretion and judgment in 1.863 + following the sections below. Be prepared to make plenty of 1.864 + mistakes, and to spend a lot of time reading your server's 1.865 + error logs.</para> 1.866 + </note> 1.867 + 1.868 + <sect2> 1.869 + <title>Web server configuration checklist</title> 1.870 + 1.871 + <para>Before you continue, do take a few moments to check a few 1.872 + aspects of your system's setup.</para> 1.873 + 1.874 + <orderedlist> 1.875 + <listitem><para>Do you have a web server installed at all? 1.876 + Mac OS X ships with Apache, but many other systems may not 1.877 + have a web server installed.</para> 1.878 + </listitem> 1.879 + <listitem><para>If you have a web server installed, is it 1.880 + actually running? On most systems, even if one is 1.881 + present, it will be disabled by default.</para> 1.882 + </listitem> 1.883 + <listitem><para>Is your server configured to allow you to run 1.884 + CGI programs in the directory where you plan to do so? 1.885 + Most servers default to explicitly disabling the ability 1.886 + to run CGI programs.</para> 1.887 + </listitem></orderedlist> 1.888 + 1.889 + <para>If you don't have a web server installed, and don't have 1.890 + substantial experience configuring Apache, you should consider 1.891 + using the <literal>lighttpd</literal> web server instead of 1.892 + Apache. Apache has a well-deserved reputation for baroque and 1.893 + confusing configuration. While <literal>lighttpd</literal> is 1.894 + less capable in some ways than Apache, most of these 1.895 + capabilities are not relevant to serving Mercurial 1.896 + repositories. And <literal>lighttpd</literal> is undeniably 1.897 + <emphasis>much</emphasis> easier to get started with than 1.898 + Apache.</para> 1.899 + 1.900 + </sect2> 1.901 + <sect2> 1.902 + <title>Basic CGI configuration</title> 1.903 + 1.904 + <para>On Unix-like systems, it's common for users to have a 1.905 + subdirectory named something like <filename 1.906 + class="directory">public_html</filename> in their home 1.907 + directory, from which they can serve up web pages. A file 1.908 + named <filename>foo</filename> in this directory will be 1.909 + accessible at a URL of the form 1.910 + <literal>http://www.example.com/\ 1.911 + {</literal>username/foo}.</para> 1.912 + 1.913 + <para>To get started, find the <filename 1.914 + role="special">hgweb.cgi</filename> script that should be 1.915 + present in your Mercurial installation. If you can't quickly 1.916 + find a local copy on your system, simply download one from the 1.917 + master Mercurial repository at <ulink 1.918 + 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> 1.919 + 1.920 + <para>You'll need to copy this script into your <filename 1.921 + class="directory">public_html</filename> directory, and 1.922 + ensure that it's executable.</para> 1.923 + <programlisting>cp .../hgweb.cgi ~/public_html chmod 755 1.924 + ~/public_html/hgweb.cgi</programlisting> 1.925 + <para>The <literal>755</literal> argument to 1.926 + <command>chmod</command> is a little more general than just 1.927 + making the script executable: it ensures that the script is 1.928 + executable by anyone, and that <quote>group</quote> and 1.929 + <quote>other</quote> write permissions are 1.930 + <emphasis>not</emphasis> set. If you were to leave those 1.931 + write permissions enabled, Apache's <literal>suexec</literal> 1.932 + subsystem would likely refuse to execute the script. In fact, 1.933 + <literal>suexec</literal> also insists that the 1.934 + <emphasis>directory</emphasis> in which the script resides 1.935 + must not be writable by others.</para> 1.936 + <programlisting>chmod 755 ~/public_html</programlisting> 1.937 + 1.938 + <sect3 id="sec:collab:wtf"> 1.939 + <title>What could <emphasis>possibly</emphasis> go 1.940 + wrong?</title> 1.941 + 1.942 + <para>Once you've copied the CGI script into place, go into a 1.943 + web browser, and try to open the URL <ulink 1.944 + url="http://myhostname/ 1.945 + myuser/hgweb.cgi">http://myhostname/ 1.946 + myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace 1.947 + yourself for instant failure. There's a high probability 1.948 + that trying to visit this URL will fail, and there are many 1.949 + possible reasons for this. In fact, you're likely to 1.950 + stumble over almost every one of the possible errors below, 1.951 + so please read carefully. The following are all of the 1.952 + problems I ran into on a system running Fedora 7, with a 1.953 + fresh installation of Apache, and a user account that I 1.954 + created specially to perform this exercise.</para> 1.955 + 1.956 + <para>Your web server may have per-user directories disabled. 1.957 + If you're using Apache, search your config file for a 1.958 + <literal>UserDir</literal> directive. If there's none 1.959 + present, per-user directories will be disabled. If one 1.960 + exists, but its value is <literal>disabled</literal>, then 1.961 + per-user directories will be disabled. Otherwise, the 1.962 + string after <literal>UserDir</literal> gives the name of 1.963 + the subdirectory that Apache will look in under your home 1.964 + directory, for example <filename 1.965 + class="directory">public_html</filename>.</para> 1.966 + 1.967 + <para>Your file access permissions may be too restrictive. 1.968 + The web server must be able to traverse your home directory 1.969 + and directories under your <filename 1.970 + class="directory">public_html</filename> directory, and 1.971 + read files under the latter too. Here's a quick recipe to 1.972 + help you to make your permissions more appropriate.</para> 1.973 + <programlisting>chmod 755 ~ find ~/public_html -type d -print0 1.974 + | xargs -0r chmod 755 find ~/public_html -type f -print0 | 1.975 + xargs -0r chmod 644</programlisting> 1.976 + 1.977 + <para>The other possibility with permissions is that you might 1.978 + get a completely empty window when you try to load the 1.979 + script. In this case, it's likely that your access 1.980 + permissions are \emph{too permissive}. Apache's 1.981 + <literal>suexec</literal> subsystem won't execute a script 1.982 + that's group- or world-writable, for example.</para> 1.983 + 1.984 + <para>Your web server may be configured to disallow execution 1.985 + of CGI programs in your per-user web directory. Here's 1.986 + Apache's default per-user configuration from my Fedora 1.987 + system.</para> 1.988 + <programlisting><Directory /home/*/public_html> 1.989 + AllowOverride FileInfo AuthConfig Limit Options MultiViews 1.990 + Indexes SymLinksIfOwnerMatch IncludesNoExec <Limit GET 1.991 + POST OPTIONS> Order allow,deny Allow from all 1.992 + </Limit> <LimitExcept GET POST OPTIONS> Order 1.993 + deny,allow Deny from all </LimitExcept> 1.994 + </Directory></programlisting> 1.995 + <para>If you find a similar-looking 1.996 + <literal>Directory</literal> group in your Apache 1.997 + configuration, the directive to look at inside it is 1.998 + <literal>Options</literal>. Add <literal>ExecCGI</literal> 1.999 + to the end of this list if it's missing, and restart the web 1.1000 + server.</para> 1.1001 + 1.1002 + <para>If you find that Apache serves you the text of the CGI 1.1003 + script instead of executing it, you may need to either 1.1004 + uncomment (if already present) or add a directive like 1.1005 + this.</para> 1.1006 + <programlisting>AddHandler cgi-script .cgi</programlisting> 1.1007 + 1.1008 + <para>The next possibility is that you might be served with a 1.1009 + colourful Python backtrace claiming that it can't import a 1.1010 + <literal>mercurial</literal>-related module. This is 1.1011 + actually progress! The server is now capable of executing 1.1012 + your CGI script. This error is only likely to occur if 1.1013 + you're running a private installation of Mercurial, instead 1.1014 + of a system-wide version. Remember that the web server runs 1.1015 + the CGI program without any of the environment variables 1.1016 + that you take for granted in an interactive session. If 1.1017 + this error happens to you, edit your copy of <filename 1.1018 + role="special">hgweb.cgi</filename> and follow the 1.1019 + directions inside it to correctly set your 1.1020 + <envar>PYTHONPATH</envar> environment variable.</para> 1.1021 + 1.1022 + <para>Finally, you are <emphasis>certain</emphasis> to by 1.1023 + served with another colourful Python backtrace: this one 1.1024 + will complain that it can't find <filename 1.1025 + class="directory">/path/to/repository</filename>. Edit 1.1026 + your <filename role="special">hgweb.cgi</filename> script 1.1027 + and replace the <filename 1.1028 + class="directory">/path/to/repository</filename> string 1.1029 + with the complete path to the repository you want to serve 1.1030 + up.</para> 1.1031 + 1.1032 + <para>At this point, when you try to reload the page, you 1.1033 + should be presented with a nice HTML view of your 1.1034 + repository's history. Whew!</para> 1.1035 + 1.1036 + </sect3> 1.1037 + <sect3> 1.1038 + <title>Configuring lighttpd</title> 1.1039 + 1.1040 + <para>To be exhaustive in my experiments, I tried configuring 1.1041 + the increasingly popular <literal>lighttpd</literal> web 1.1042 + server to serve the same repository as I described with 1.1043 + Apache above. I had already overcome all of the problems I 1.1044 + outlined with Apache, many of which are not server-specific. 1.1045 + As a result, I was fairly sure that my file and directory 1.1046 + permissions were good, and that my <filename 1.1047 + role="special">hgweb.cgi</filename> script was properly 1.1048 + edited.</para> 1.1049 + 1.1050 + <para>Once I had Apache running, getting 1.1051 + <literal>lighttpd</literal> to serve the repository was a 1.1052 + snap (in other words, even if you're trying to use 1.1053 + <literal>lighttpd</literal>, you should read the Apache 1.1054 + section). I first had to edit the 1.1055 + <literal>mod_access</literal> section of its config file to 1.1056 + enable <literal>mod_cgi</literal> and 1.1057 + <literal>mod_userdir</literal>, both of which were disabled 1.1058 + by default on my system. I then added a few lines to the 1.1059 + end of the config file, to configure these modules.</para> 1.1060 + <programlisting>userdir.path = "public_html" cgi.assign = ( 1.1061 + ".cgi" => "" )</programlisting> 1.1062 + <para>With this done, <literal>lighttpd</literal> ran 1.1063 + immediately for me. If I had configured 1.1064 + <literal>lighttpd</literal> before Apache, I'd almost 1.1065 + certainly have run into many of the same system-level 1.1066 + configuration problems as I did with Apache. However, I 1.1067 + found <literal>lighttpd</literal> to be noticeably easier to 1.1068 + configure than Apache, even though I've used Apache for over 1.1069 + a decade, and this was my first exposure to 1.1070 + <literal>lighttpd</literal>.</para> 1.1071 + 1.1072 + </sect3> 1.1073 + </sect2> 1.1074 + <sect2> 1.1075 + <title>Sharing multiple repositories with one CGI script</title> 1.1076 + 1.1077 + <para>The <filename role="special">hgweb.cgi</filename> script 1.1078 + only lets you publish a single repository, which is an 1.1079 + annoying restriction. If you want to publish more than one 1.1080 + without wracking yourself with multiple copies of the same 1.1081 + script, each with different names, a better choice is to use 1.1082 + the <filename role="special">hgwebdir.cgi</filename> 1.1083 + script.</para> 1.1084 + 1.1085 + <para>The procedure to configure <filename 1.1086 + role="special">hgwebdir.cgi</filename> is only a little more 1.1087 + involved than for <filename 1.1088 + role="special">hgweb.cgi</filename>. First, you must obtain 1.1089 + a copy of the script. If you don't have one handy, you can 1.1090 + download a copy from the master Mercurial repository at <ulink 1.1091 + 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> 1.1092 + 1.1093 + <para>You'll need to copy this script into your <filename 1.1094 + class="directory">public_html</filename> directory, and 1.1095 + ensure that it's executable.</para> 1.1096 + <programlisting>cp .../hgwebdir.cgi ~/public_html chmod 755 1.1097 + ~/public_html ~/public_html/hgwebdir.cgi</programlisting> 1.1098 + <para>With basic configuration out of the way, try to visit 1.1099 + <ulink url="http://myhostname/ 1.1100 + myuser/hgwebdir.cgi">http://myhostname/ 1.1101 + myuser/hgwebdir.cgi</ulink> in your browser. It should 1.1102 + display an empty list of repositories. If you get a blank 1.1103 + window or error message, try walking through the list of 1.1104 + potential problems in section <xref 1.1105 + linkend="sec:collab:wtf"/>.</para> 1.1106 + 1.1107 + <para>The <filename role="special">hgwebdir.cgi</filename> 1.1108 + script relies on an external configuration file. By default, 1.1109 + it searches for a file named <filename 1.1110 + role="special">hgweb.config</filename> in the same directory 1.1111 + as itself. You'll need to create this file, and make it 1.1112 + world-readable. The format of the file is similar to a 1.1113 + Windows <quote>ini</quote> file, as understood by Python's 1.1114 + <literal>ConfigParser</literal> 1.1115 + <citation>web:configparser</citation> module.</para> 1.1116 + 1.1117 + <para>The easiest way to configure <filename 1.1118 + role="special">hgwebdir.cgi</filename> is with a section 1.1119 + named <literal>collections</literal>. This will automatically 1.1120 + publish <emphasis>every</emphasis> repository under the 1.1121 + directories you name. The section should look like 1.1122 + this:</para> 1.1123 + <programlisting>[collections] /my/root = 1.1124 + /my/root</programlisting> 1.1125 + <para>Mercurial interprets this by looking at the directory name 1.1126 + on the <emphasis>right</emphasis> hand side of the 1.1127 + <quote><literal>=</literal></quote> sign; finding repositories 1.1128 + in that directory hierarchy; and using the text on the 1.1129 + <emphasis>left</emphasis> to strip off matching text from the 1.1130 + names it will actually list in the web interface. The 1.1131 + remaining component of a path after this stripping has 1.1132 + occurred is called a <quote>virtual path</quote>.</para> 1.1133 + 1.1134 + <para>Given the example above, if we have a repository whose 1.1135 + local path is <filename 1.1136 + class="directory">/my/root/this/repo</filename>, the CGI 1.1137 + script will strip the leading <filename 1.1138 + class="directory">/my/root</filename> from the name, and 1.1139 + publish the repository with a virtual path of <filename 1.1140 + class="directory">this/repo</filename>. If the base URL for 1.1141 + our CGI script is <ulink url="http://myhostname/ 1.1142 + myuser/hgwebdir.cgi">http://myhostname/ 1.1143 + myuser/hgwebdir.cgi</ulink>, the complete URL for that 1.1144 + repository will be <ulink url="http://myhostname/ 1.1145 + myuser/hgwebdir.cgi/this/repo">http://myhostname/ 1.1146 + myuser/hgwebdir.cgi/this/repo</ulink>.</para> 1.1147 + 1.1148 + <para>If we replace <filename 1.1149 + class="directory">/my/root</filename> on the left hand side 1.1150 + of this example with <filename 1.1151 + class="directory">/my</filename>, then <filename 1.1152 + role="special">hgwebdir.cgi</filename> will only strip off 1.1153 + <filename class="directory">/my</filename> from the repository 1.1154 + name, and will give us a virtual path of <filename 1.1155 + class="directory">root/this/repo</filename> instead of 1.1156 + <filename class="directory">this/repo</filename>.</para> 1.1157 + 1.1158 + <para>The <filename role="special">hgwebdir.cgi</filename> 1.1159 + script will recursively search each directory listed in the 1.1160 + <literal>collections</literal> section of its configuration 1.1161 + file, but it will <literal>not</literal> recurse into the 1.1162 + repositories it finds.</para> 1.1163 + 1.1164 + <para>The <literal>collections</literal> mechanism makes it easy 1.1165 + to publish many repositories in a <quote>fire and 1.1166 + forget</quote> manner. You only need to set up the CGI 1.1167 + script and configuration file one time. Afterwards, you can 1.1168 + publish or unpublish a repository at any time by simply moving 1.1169 + it into, or out of, the directory hierarchy in which you've 1.1170 + configured <filename role="special">hgwebdir.cgi</filename> to 1.1171 + look.</para> 1.1172 + 1.1173 + <sect3> 1.1174 + <title>Explicitly specifying which repositories to 1.1175 + publish</title> 1.1176 + 1.1177 + <para>In addition to the <literal>collections</literal> 1.1178 + mechanism, the <filename 1.1179 + role="special">hgwebdir.cgi</filename> script allows you 1.1180 + to publish a specific list of repositories. To do so, 1.1181 + create a <literal>paths</literal> section, with contents of 1.1182 + the following form.</para> 1.1183 + <programlisting>[paths] repo1 = /my/path/to/some/repo repo2 = 1.1184 + /some/path/to/another</programlisting> 1.1185 + <para>In this case, the virtual path (the component that will 1.1186 + appear in a URL) is on the left hand side of each 1.1187 + definition, while the path to the repository is on the 1.1188 + right. Notice that there does not need to be any 1.1189 + relationship between the virtual path you choose and the 1.1190 + location of a repository in your filesystem.</para> 1.1191 + 1.1192 + <para>If you wish, you can use both the 1.1193 + <literal>collections</literal> and <literal>paths</literal> 1.1194 + mechanisms simultaneously in a single configuration 1.1195 + file.</para> 1.1196 + 1.1197 + <note> 1.1198 + <para> If multiple repositories have the same virtual path, 1.1199 + <filename role="special">hgwebdir.cgi</filename> will not 1.1200 + report an error. Instead, it will behave 1.1201 + unpredictably.</para> 1.1202 + </note> 1.1203 + 1.1204 + </sect3> 1.1205 + </sect2> 1.1206 + <sect2> 1.1207 + <title>Downloading source archives</title> 1.1208 + 1.1209 + <para>Mercurial's web interface lets users download an archive 1.1210 + of any revision. This archive will contain a snapshot of the 1.1211 + working directory as of that revision, but it will not contain 1.1212 + a copy of the repository data.</para> 1.1213 + 1.1214 + <para>By default, this feature is not enabled. To enable it, 1.1215 + you'll need to add an <envar 1.1216 + role="rc-item-web">allow_archive</envar> item to the 1.1217 + <literal role="rc-web">web</literal> section of your <filename 1.1218 + role="special"> /.hgrc</filename>.</para> 1.1219 + 1.1220 + </sect2> 1.1221 + <sect2> 1.1222 + <title>Web configuration options</title> 1.1223 + 1.1224 + <para>Mercurial's web interfaces (the <command role="hg-cmd">hg 1.1225 + serve</command> command, and the <filename 1.1226 + role="special">hgweb.cgi</filename> and <filename 1.1227 + role="special">hgwebdir.cgi</filename> scripts) have a 1.1228 + number of configuration options that you can set. These 1.1229 + belong in a section named <literal 1.1230 + role="rc-web">web</literal>.</para> 1.1231 + <itemizedlist> 1.1232 + <listitem><para><envar 1.1233 + role="rc-item-web">allow_archive</envar>: Determines 1.1234 + which (if any) archive download mechanisms Mercurial 1.1235 + supports. If you enable this feature, users of the web 1.1236 + interface will be able to download an archive of whatever 1.1237 + revision of a repository they are viewing. To enable the 1.1238 + archive feature, this item must take the form of a 1.1239 + sequence of words drawn from the list below.</para> 1.1240 + <itemizedlist> 1.1241 + <listitem><para><literal>bz2</literal>: A 1.1242 + <command>tar</command> archive, compressed using 1.1243 + <literal>bzip2</literal> compression. This has the 1.1244 + best compression ratio, but uses the most CPU time on 1.1245 + the server.</para> 1.1246 + </listitem> 1.1247 + <listitem><para><literal>gz</literal>: A 1.1248 + <command>tar</command> archive, compressed using 1.1249 + <literal>gzip</literal> compression.</para> 1.1250 + </listitem> 1.1251 + <listitem><para><literal>zip</literal>: A 1.1252 + <command>zip</command> archive, compressed using LZW 1.1253 + compression. This format has the worst compression 1.1254 + ratio, but is widely used in the Windows world.</para> 1.1255 + </listitem> 1.1256 + </itemizedlist> 1.1257 + <para> If you provide an empty list, or don't have an 1.1258 + <envar role="rc-item-web">allow_archive</envar> entry at 1.1259 + all, this feature will be disabled. Here is an example of 1.1260 + how to enable all three supported formats.</para> 1.1261 + <programlisting>[web] allow_archive = bz2 gz 1.1262 + zip</programlisting> 1.1263 + </listitem> 1.1264 + <listitem><para><envar role="rc-item-web">allowpull</envar>: 1.1265 + Boolean. Determines whether the web interface allows 1.1266 + remote users to <command role="hg-cmd">hg pull</command> 1.1267 + and <command role="hg-cmd">hg clone</command> this 1.1268 + repository over HTTP. If set to <literal>no</literal> or 1.1269 + <literal>false</literal>, only the 1.1270 + <quote>human-oriented</quote> portion of the web interface 1.1271 + is available.</para> 1.1272 + </listitem> 1.1273 + <listitem><para><envar role="rc-item-web">contact</envar>: 1.1274 + String. A free-form (but preferably brief) string 1.1275 + identifying the person or group in charge of the 1.1276 + repository. This often contains the name and email 1.1277 + address of a person or mailing list. It often makes sense 1.1278 + to place this entry in a repository's own <filename 1.1279 + role="special">.hg/hgrc</filename> file, but it can make 1.1280 + sense to use in a global <filename role="special"> 1.1281 + /.hgrc</filename>\ if every repository has a single 1.1282 + maintainer.</para> 1.1283 + </listitem> 1.1284 + <listitem><para><envar role="rc-item-web">maxchanges</envar>: 1.1285 + Integer. The default maximum number of changesets to 1.1286 + display in a single page of output.</para> 1.1287 + </listitem> 1.1288 + <listitem><para><envar role="rc-item-web">maxfiles</envar>: 1.1289 + Integer. The default maximum number of modified files to 1.1290 + display in a single page of output.</para> 1.1291 + </listitem> 1.1292 + <listitem><para><envar role="rc-item-web">stripes</envar>: 1.1293 + Integer. If the web interface displays alternating 1.1294 + <quote>stripes</quote> to make it easier to visually align 1.1295 + rows when you are looking at a table, this number controls 1.1296 + the number of rows in each stripe.</para> 1.1297 + </listitem> 1.1298 + <listitem><para><envar role="rc-item-web">style</envar>: 1.1299 + Controls the template Mercurial uses to display the web 1.1300 + interface. Mercurial ships with two web templates, named 1.1301 + <literal>default</literal> and <literal>gitweb</literal> 1.1302 + (the latter is much more visually attractive). You can 1.1303 + also specify a custom template of your own; see chapter 1.1304 + <xref linkend="chap:template"/> for details. 1.1305 + Here, you can see how to enable the 1.1306 + <literal>gitweb</literal> style.</para> 1.1307 + <programlisting>[web] style = gitweb</programlisting> 1.1308 + </listitem> 1.1309 + <listitem><para><envar role="rc-item-web">templates</envar>: 1.1310 + Path. The directory in which to search for template 1.1311 + files. By default, Mercurial searches in the directory in 1.1312 + which it was installed.</para> 1.1313 + </listitem></itemizedlist> 1.1314 + <para>If you are using <filename 1.1315 + role="special">hgwebdir.cgi</filename>, you can place a few 1.1316 + configuration items in a <literal role="rc-web">web</literal> 1.1317 + section of the <filename 1.1318 + role="special">hgweb.config</filename> file instead of a 1.1319 + <filename role="special"> /.hgrc</filename>\ file, for 1.1320 + convenience. These items are <envar 1.1321 + role="rc-item-web">motd</envar> and <envar 1.1322 + role="rc-item-web">style</envar>.</para> 1.1323 + 1.1324 + <sect3> 1.1325 + <title>Options specific to an individual repository</title> 1.1326 + 1.1327 + <para>A few <literal role="rc-web">web</literal> configuration 1.1328 + items ought to be placed in a repository's local <filename 1.1329 + role="special">.hg/hgrc</filename>, rather than a user's 1.1330 + or global <filename role="special"> 1.1331 + /.hgrc</filename>.</para> 1.1332 + <itemizedlist> 1.1333 + <listitem><para><envar 1.1334 + role="rc-item-web">description</envar>: String. A 1.1335 + free-form (but preferably brief) string that describes 1.1336 + the contents or purpose of the repository.</para> 1.1337 + </listitem> 1.1338 + <listitem><para><envar role="rc-item-web">name</envar>: 1.1339 + String. The name to use for the repository in the web 1.1340 + interface. This overrides the default name, which is 1.1341 + the last component of the repository's path.</para> 1.1342 + </listitem></itemizedlist> 1.1343 + 1.1344 + </sect3> 1.1345 + <sect3> 1.1346 + <title>Options specific to the <command role="hg-cmd">hg 1.1347 + serve</command> command</title> 1.1348 + 1.1349 + <para>Some of the items in the <literal 1.1350 + role="rc-web">web</literal> section of a <filename 1.1351 + role="special"> /.hgrc</filename>\ file are only for use 1.1352 + with the <command role="hg-cmd">hg serve</command> 1.1353 + command.</para> 1.1354 + <itemizedlist> 1.1355 + <listitem><para><envar role="rc-item-web">accesslog</envar>: 1.1356 + Path. The name of a file into which to write an access 1.1357 + log. By default, the <command role="hg-cmd">hg 1.1358 + serve</command> command writes this information to 1.1359 + standard output, not to a file. Log entries are written 1.1360 + in the standard <quote>combined</quote> file format used 1.1361 + by almost all web servers.</para> 1.1362 + </listitem> 1.1363 + <listitem><para><envar role="rc-item-web">address</envar>: 1.1364 + String. The local address on which the server should 1.1365 + listen for incoming connections. By default, the server 1.1366 + listens on all addresses.</para> 1.1367 + </listitem> 1.1368 + <listitem><para><envar role="rc-item-web">errorlog</envar>: 1.1369 + Path. The name of a file into which to write an error 1.1370 + log. By default, the <command role="hg-cmd">hg 1.1371 + serve</command> command writes this information to 1.1372 + standard error, not to a file.</para> 1.1373 + </listitem> 1.1374 + <listitem><para><envar role="rc-item-web">ipv6</envar>: 1.1375 + Boolean. Whether to use the IPv6 protocol. By default, 1.1376 + IPv6 is not used.</para> 1.1377 + </listitem> 1.1378 + <listitem><para><envar role="rc-item-web">port</envar>: 1.1379 + Integer. The TCP port number on which the server should 1.1380 + listen. The default port number used is 8000.</para> 1.1381 + </listitem></itemizedlist> 1.1382 + 1.1383 + </sect3> 1.1384 + <sect3> 1.1385 + <title>Choosing the right <filename role="special"> 1.1386 + /.hgrc</filename>\ file to add <literal 1.1387 + role="rc-web">web</literal> items to</title> 1.1388 + 1.1389 + <para>It is important to remember that a web server like 1.1390 + Apache or <literal>lighttpd</literal> will run under a user 1.1391 + ID that is different to yours. CGI scripts run by your 1.1392 + server, such as <filename 1.1393 + role="special">hgweb.cgi</filename>, will usually also run 1.1394 + under that user ID.</para> 1.1395 + 1.1396 + <para>If you add <literal role="rc-web">web</literal> items to 1.1397 + your own personal <filename role="special"> 1.1398 + /.hgrc</filename>\ file, CGI scripts won't read that 1.1399 + <filename role="special"> /.hgrc</filename>\ file. Those 1.1400 + settings will thus only affect the behaviour of the <command 1.1401 + role="hg-cmd">hg serve</command> command when you run it. 1.1402 + To cause CGI scripts to see your settings, either create a 1.1403 + <filename role="special"> /.hgrc</filename>\ file in the 1.1404 + home directory of the user ID that runs your web server, or 1.1405 + add those settings to a system-wide <filename 1.1406 + role="special"> /.hgrc</filename>\ file.</para> 1.1407 + 1.1408 + 1.1409 + </sect3> 1.1410 + </sect2> 1.1411 + </sect1> 1.1412 +</chapter> 1.1413 + 1.1414 +<!-- 1.1415 +local variables: 1.1416 +sgml-parent-document: ("00book.xml" "book" "chapter") 1.1417 +end: 1.1418 +-->