hgbook
annotate fr/ch06-collab.xml @ 964:6b680d569bb4
deleting a bunch of files not longer necessary to build the documentation.
Adding missing newly files needed to build the documentation
Adding missing newly files needed to build the documentation
author | Romain PELISSE <belaran@gmail.com> |
---|---|
date | Sun Aug 16 04:58:01 2009 +0200 (2009-08-16) |
parents | |
children | 6f8c48362758 |
rev | line source |
---|---|
belaran@964 | 1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : --> |
belaran@964 | 2 |
belaran@964 | 3 <chapter> |
belaran@964 | 4 <title>Collaborating with other people</title> |
belaran@964 | 5 <para>\label{cha:collab}</para> |
belaran@964 | 6 |
belaran@964 | 7 <para>As a completely decentralised tool, Mercurial doesn't impose any |
belaran@964 | 8 policy on how people ought to work with each other. However, if |
belaran@964 | 9 you're new to distributed revision control, it helps to have some |
belaran@964 | 10 tools and examples in mind when you're thinking about possible |
belaran@964 | 11 workflow models.</para> |
belaran@964 | 12 |
belaran@964 | 13 <sect1> |
belaran@964 | 14 <title>Mercurial's web interface</title> |
belaran@964 | 15 |
belaran@964 | 16 <para>Mercurial has a powerful web interface that provides several |
belaran@964 | 17 useful capabilities.</para> |
belaran@964 | 18 |
belaran@964 | 19 <para>For interactive use, the web interface lets you browse a single |
belaran@964 | 20 repository or a collection of repositories. You can view the history |
belaran@964 | 21 of a repository, examine each change (comments and diffs), and view |
belaran@964 | 22 the contents of each directory and file.</para> |
belaran@964 | 23 |
belaran@964 | 24 <para>Also for human consumption, the web interface provides an RSS feed of |
belaran@964 | 25 the changes in a repository. This lets you <quote>subscribe</quote> to a |
belaran@964 | 26 repository using your favourite feed reader, and be automatically |
belaran@964 | 27 notified of activity in that repository as soon as it happens. I find |
belaran@964 | 28 this capability much more convenient than the model of subscribing to |
belaran@964 | 29 a mailing list to which notifications are sent, as it requires no |
belaran@964 | 30 additional configuration on the part of whoever is serving the |
belaran@964 | 31 repository.</para> |
belaran@964 | 32 |
belaran@964 | 33 <para>The web interface also lets remote users clone a repository, pull |
belaran@964 | 34 changes from it, and (when the server is configured to permit it) push |
belaran@964 | 35 changes back to it. Mercurial's HTTP tunneling protocol aggressively |
belaran@964 | 36 compresses data, so that it works efficiently even over low-bandwidth |
belaran@964 | 37 network connections.</para> |
belaran@964 | 38 |
belaran@964 | 39 <para>The easiest way to get started with the web interface is to use your |
belaran@964 | 40 web browser to visit an existing repository, such as the master |
belaran@964 | 41 Mercurial repository at |
belaran@964 | 42 <ulink url="http://www.selenic.com/repo/hg?style=gitweb">http://www.selenic.com/repo/hg?style=gitweb</ulink>.</para> |
belaran@964 | 43 |
belaran@964 | 44 <para>If you're interested in providing a web interface to your own |
belaran@964 | 45 repositories, Mercurial provides two ways to do this. The first is |
belaran@964 | 46 using the <command role="hg-cmd">hg serve</command> command, which is best suited to short-term |
belaran@964 | 47 <quote>lightweight</quote> serving. See section <xref linkend="sec:collab:serve"/> below for |
belaran@964 | 48 details of how to use this command. If you have a long-lived |
belaran@964 | 49 repository that you'd like to make permanently available, Mercurial |
belaran@964 | 50 has built-in support for the CGI (Common Gateway Interface) standard, |
belaran@964 | 51 which all common web servers support. See |
belaran@964 | 52 section <xref linkend="sec:collab:cgi"/> for details of CGI configuration.</para> |
belaran@964 | 53 |
belaran@964 | 54 </sect1> |
belaran@964 | 55 <sect1> |
belaran@964 | 56 <title>Collaboration models</title> |
belaran@964 | 57 |
belaran@964 | 58 <para>With a suitably flexible tool, making decisions about workflow is much |
belaran@964 | 59 more of a social engineering challenge than a technical one. |
belaran@964 | 60 Mercurial imposes few limitations on how you can structure the flow of |
belaran@964 | 61 work in a project, so it's up to you and your group to set up and live |
belaran@964 | 62 with a model that matches your own particular needs. |
belaran@964 | 63 </para> |
belaran@964 | 64 |
belaran@964 | 65 <sect2> |
belaran@964 | 66 <title>Factors to keep in mind</title> |
belaran@964 | 67 |
belaran@964 | 68 <para>The most important aspect of any model that you must keep in mind is |
belaran@964 | 69 how well it matches the needs and capabilities of the people who will |
belaran@964 | 70 be using it. This might seem self-evident; even so, you still can't |
belaran@964 | 71 afford to forget it for a moment. |
belaran@964 | 72 </para> |
belaran@964 | 73 |
belaran@964 | 74 <para>I once put together a workflow model that seemed to make perfect sense |
belaran@964 | 75 to me, but that caused a considerable amount of consternation and |
belaran@964 | 76 strife within my development team. In spite of my attempts to explain |
belaran@964 | 77 why we needed a complex set of branches, and how changes ought to flow |
belaran@964 | 78 between them, a few team members revolted. Even though they were |
belaran@964 | 79 smart people, they didn't want to pay attention to the constraints we |
belaran@964 | 80 were operating under, or face the consequences of those constraints in |
belaran@964 | 81 the details of the model that I was advocating. |
belaran@964 | 82 </para> |
belaran@964 | 83 |
belaran@964 | 84 <para>Don't sweep foreseeable social or technical problems under the rug. |
belaran@964 | 85 Whatever scheme you put into effect, you should plan for mistakes and |
belaran@964 | 86 problem scenarios. Consider adding automated machinery to prevent, or |
belaran@964 | 87 quickly recover from, trouble that you can anticipate. As an example, |
belaran@964 | 88 if you intend to have a branch with not-for-release changes in it, |
belaran@964 | 89 you'd do well to think early about the possibility that someone might |
belaran@964 | 90 accidentally merge those changes into a release branch. You could |
belaran@964 | 91 avoid this particular problem by writing a hook that prevents changes |
belaran@964 | 92 from being merged from an inappropriate branch. |
belaran@964 | 93 </para> |
belaran@964 | 94 |
belaran@964 | 95 </sect2> |
belaran@964 | 96 <sect2> |
belaran@964 | 97 <title>Informal anarchy</title> |
belaran@964 | 98 |
belaran@964 | 99 <para>I wouldn't suggest an <quote>anything goes</quote> approach as something |
belaran@964 | 100 sustainable, but it's a model that's easy to grasp, and it works |
belaran@964 | 101 perfectly well in a few unusual situations. |
belaran@964 | 102 </para> |
belaran@964 | 103 |
belaran@964 | 104 <para>As one example, many projects have a loose-knit group of collaborators |
belaran@964 | 105 who rarely physically meet each other. Some groups like to overcome |
belaran@964 | 106 the isolation of working at a distance by organising occasional |
belaran@964 | 107 <quote>sprints</quote>. In a sprint, a number of people get together in a single |
belaran@964 | 108 location (a company's conference room, a hotel meeting room, that kind |
belaran@964 | 109 of place) and spend several days more or less locked in there, hacking |
belaran@964 | 110 intensely on a handful of projects. |
belaran@964 | 111 </para> |
belaran@964 | 112 |
belaran@964 | 113 <para>A sprint is the perfect place to use the <command role="hg-cmd">hg serve</command> command, since |
belaran@964 | 114 <command role="hg-cmd">hg serve</command> does not requires any fancy server infrastructure. You |
belaran@964 | 115 can get started with <command role="hg-cmd">hg serve</command> in moments, by reading |
belaran@964 | 116 section <xref linkend="sec:collab:serve"/> below. Then simply tell the person |
belaran@964 | 117 next to you that you're running a server, send the URL to them in an |
belaran@964 | 118 instant message, and you immediately have a quick-turnaround way to |
belaran@964 | 119 work together. They can type your URL into their web browser and |
belaran@964 | 120 quickly review your changes; or they can pull a bugfix from you and |
belaran@964 | 121 verify it; or they can clone a branch containing a new feature and try |
belaran@964 | 122 it out. |
belaran@964 | 123 </para> |
belaran@964 | 124 |
belaran@964 | 125 <para>The charm, and the problem, with doing things in an ad hoc fashion |
belaran@964 | 126 like this is that only people who know about your changes, and where |
belaran@964 | 127 they are, can see them. Such an informal approach simply doesn't |
belaran@964 | 128 scale beyond a handful people, because each individual needs to know |
belaran@964 | 129 about $n$ different repositories to pull from. |
belaran@964 | 130 </para> |
belaran@964 | 131 |
belaran@964 | 132 </sect2> |
belaran@964 | 133 <sect2> |
belaran@964 | 134 <title>A single central repository</title> |
belaran@964 | 135 |
belaran@964 | 136 <para>For smaller projects migrating from a centralised revision control |
belaran@964 | 137 tool, perhaps the easiest way to get started is to have changes flow |
belaran@964 | 138 through a single shared central repository. This is also the |
belaran@964 | 139 most common <quote>building block</quote> for more ambitious workflow schemes. |
belaran@964 | 140 </para> |
belaran@964 | 141 |
belaran@964 | 142 <para>Contributors start by cloning a copy of this repository. They can |
belaran@964 | 143 pull changes from it whenever they need to, and some (perhaps all) |
belaran@964 | 144 developers have permission to push a change back when they're ready |
belaran@964 | 145 for other people to see it. |
belaran@964 | 146 </para> |
belaran@964 | 147 |
belaran@964 | 148 <para>Under this model, it can still often make sense for people to pull |
belaran@964 | 149 changes directly from each other, without going through the central |
belaran@964 | 150 repository. Consider a case in which I have a tentative bug fix, but |
belaran@964 | 151 I am worried that if I were to publish it to the central repository, |
belaran@964 | 152 it might subsequently break everyone else's trees as they pull it. To |
belaran@964 | 153 reduce the potential for damage, I can ask you to clone my repository |
belaran@964 | 154 into a temporary repository of your own and test it. This lets us put |
belaran@964 | 155 off publishing the potentially unsafe change until it has had a little |
belaran@964 | 156 testing. |
belaran@964 | 157 </para> |
belaran@964 | 158 |
belaran@964 | 159 <para>In this kind of scenario, people usually use the <command>ssh</command> |
belaran@964 | 160 protocol to securely push changes to the central repository, as |
belaran@964 | 161 documented in section <xref linkend="sec:collab:ssh"/>. It's also usual to |
belaran@964 | 162 publish a read-only copy of the repository over HTTP using CGI, as in |
belaran@964 | 163 section <xref linkend="sec:collab:cgi"/>. Publishing over HTTP satisfies the |
belaran@964 | 164 needs of people who don't have push access, and those who want to use |
belaran@964 | 165 web browsers to browse the repository's history. |
belaran@964 | 166 </para> |
belaran@964 | 167 |
belaran@964 | 168 </sect2> |
belaran@964 | 169 <sect2> |
belaran@964 | 170 <title>Working with multiple branches</title> |
belaran@964 | 171 |
belaran@964 | 172 <para>Projects of any significant size naturally tend to make progress on |
belaran@964 | 173 several fronts simultaneously. In the case of software, it's common |
belaran@964 | 174 for a project to go through periodic official releases. A release |
belaran@964 | 175 might then go into <quote>maintenance mode</quote> for a while after its first |
belaran@964 | 176 publication; maintenance releases tend to contain only bug fixes, not |
belaran@964 | 177 new features. In parallel with these maintenance releases, one or |
belaran@964 | 178 more future releases may be under development. People normally use |
belaran@964 | 179 the word <quote>branch</quote> to refer to one of these many slightly different |
belaran@964 | 180 directions in which development is proceeding. |
belaran@964 | 181 </para> |
belaran@964 | 182 |
belaran@964 | 183 <para>Mercurial is particularly well suited to managing a number of |
belaran@964 | 184 simultaneous, but not identical, branches. Each <quote>development |
belaran@964 | 185 direction</quote> can live in its own central repository, and you can merge |
belaran@964 | 186 changes from one to another as the need arises. Because repositories |
belaran@964 | 187 are independent of each other, unstable changes in a development |
belaran@964 | 188 branch will never affect a stable branch unless someone explicitly |
belaran@964 | 189 merges those changes in. |
belaran@964 | 190 </para> |
belaran@964 | 191 |
belaran@964 | 192 <para>Here's an example of how this can work in practice. Let's say you |
belaran@964 | 193 have one <quote>main branch</quote> on a central server. |
belaran@964 | 194 <!-- &interaction.branching.init; --> |
belaran@964 | 195 People clone it, make changes locally, test them, and push them back. |
belaran@964 | 196 </para> |
belaran@964 | 197 |
belaran@964 | 198 <para>Once the main branch reaches a release milestone, you can use the |
belaran@964 | 199 <command role="hg-cmd">hg tag</command> command to give a permanent name to the milestone |
belaran@964 | 200 revision. |
belaran@964 | 201 <!-- &interaction.branching.tag; --> |
belaran@964 | 202 Let's say some ongoing development occurs on the main branch. |
belaran@964 | 203 <!-- &interaction.branching.main; --> |
belaran@964 | 204 Using the tag that was recorded at the milestone, people who clone |
belaran@964 | 205 that repository at any time in the future can use <command role="hg-cmd">hg update</command> to |
belaran@964 | 206 get a copy of the working directory exactly as it was when that tagged |
belaran@964 | 207 revision was committed. |
belaran@964 | 208 <!-- &interaction.branching.update; --> |
belaran@964 | 209 </para> |
belaran@964 | 210 |
belaran@964 | 211 <para>In addition, immediately after the main branch is tagged, someone can |
belaran@964 | 212 then clone the main branch on the server to a new <quote>stable</quote> branch, |
belaran@964 | 213 also on the server. |
belaran@964 | 214 <!-- &interaction.branching.clone; --> |
belaran@964 | 215 </para> |
belaran@964 | 216 |
belaran@964 | 217 <para>Someone who needs to make a change to the stable branch can then clone |
belaran@964 | 218 <emphasis>that</emphasis> repository, make their changes, commit, and push their |
belaran@964 | 219 changes back there. |
belaran@964 | 220 <!-- &interaction.branching.stable; --> |
belaran@964 | 221 Because Mercurial repositories are independent, and Mercurial doesn't |
belaran@964 | 222 move changes around automatically, the stable and main branches are |
belaran@964 | 223 <emphasis>isolated</emphasis> from each other. The changes that you made on the |
belaran@964 | 224 main branch don't <quote>leak</quote> to the stable branch, and vice versa. |
belaran@964 | 225 </para> |
belaran@964 | 226 |
belaran@964 | 227 <para>You'll often want all of your bugfixes on the stable branch to show up |
belaran@964 | 228 on the main branch, too. Rather than rewrite a bugfix on the main |
belaran@964 | 229 branch, you can simply pull and merge changes from the stable to the |
belaran@964 | 230 main branch, and Mercurial will bring those bugfixes in for you. |
belaran@964 | 231 <!-- &interaction.branching.merge; --> |
belaran@964 | 232 The main branch will still contain changes that are not on the stable |
belaran@964 | 233 branch, but it will also contain all of the bugfixes from the stable |
belaran@964 | 234 branch. The stable branch remains unaffected by these changes. |
belaran@964 | 235 </para> |
belaran@964 | 236 |
belaran@964 | 237 </sect2> |
belaran@964 | 238 <sect2> |
belaran@964 | 239 <title>Feature branches</title> |
belaran@964 | 240 |
belaran@964 | 241 <para>For larger projects, an effective way to manage change is to break up |
belaran@964 | 242 a team into smaller groups. Each group has a shared branch of its |
belaran@964 | 243 own, cloned from a single <quote>master</quote> branch used by the entire |
belaran@964 | 244 project. People working on an individual branch are typically quite |
belaran@964 | 245 isolated from developments on other branches. |
belaran@964 | 246 </para> |
belaran@964 | 247 |
belaran@964 | 248 <informalfigure> |
belaran@964 | 249 |
belaran@964 | 250 <para> <mediaobject><imageobject><imagedata fileref="feature-branches"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject> |
belaran@964 | 251 <caption><para>Feature branches</para></caption> |
belaran@964 | 252 \label{fig:collab:feature-branches} |
belaran@964 | 253 </para> |
belaran@964 | 254 </informalfigure> |
belaran@964 | 255 |
belaran@964 | 256 <para>When a particular feature is deemed to be in suitable shape, someone |
belaran@964 | 257 on that feature team pulls and merges from the master branch into the |
belaran@964 | 258 feature branch, then pushes back up to the master branch. |
belaran@964 | 259 </para> |
belaran@964 | 260 |
belaran@964 | 261 </sect2> |
belaran@964 | 262 <sect2> |
belaran@964 | 263 <title>The release train</title> |
belaran@964 | 264 |
belaran@964 | 265 <para>Some projects are organised on a <quote>train</quote> basis: a release is |
belaran@964 | 266 scheduled to happen every few months, and whatever features are ready |
belaran@964 | 267 when the <quote>train</quote> is ready to leave are allowed in. |
belaran@964 | 268 </para> |
belaran@964 | 269 |
belaran@964 | 270 <para>This model resembles working with feature branches. The difference is |
belaran@964 | 271 that when a feature branch misses a train, someone on the feature team |
belaran@964 | 272 pulls and merges the changes that went out on that train release into |
belaran@964 | 273 the feature branch, and the team continues its work on top of that |
belaran@964 | 274 release so that their feature can make the next release. |
belaran@964 | 275 </para> |
belaran@964 | 276 |
belaran@964 | 277 </sect2> |
belaran@964 | 278 <sect2> |
belaran@964 | 279 <title>The Linux kernel model</title> |
belaran@964 | 280 |
belaran@964 | 281 <para>The development of the Linux kernel has a shallow hierarchical |
belaran@964 | 282 structure, surrounded by a cloud of apparent chaos. Because most |
belaran@964 | 283 Linux developers use <command>git</command>, a distributed revision control |
belaran@964 | 284 tool with capabilities similar to Mercurial, it's useful to describe |
belaran@964 | 285 the way work flows in that environment; if you like the ideas, the |
belaran@964 | 286 approach translates well across tools. |
belaran@964 | 287 </para> |
belaran@964 | 288 |
belaran@964 | 289 <para>At the center of the community sits Linus Torvalds, the creator of |
belaran@964 | 290 Linux. He publishes a single source repository that is considered the |
belaran@964 | 291 <quote>authoritative</quote> current tree by the entire developer community. |
belaran@964 | 292 Anyone can clone Linus's tree, but he is very choosy about whose trees |
belaran@964 | 293 he pulls from. |
belaran@964 | 294 </para> |
belaran@964 | 295 |
belaran@964 | 296 <para>Linus has a number of <quote>trusted lieutenants</quote>. As a general rule, he |
belaran@964 | 297 pulls whatever changes they publish, in most cases without even |
belaran@964 | 298 reviewing those changes. Some of those lieutenants are generally |
belaran@964 | 299 agreed to be <quote>maintainers</quote>, responsible for specific subsystems |
belaran@964 | 300 within the kernel. If a random kernel hacker wants to make a change |
belaran@964 | 301 to a subsystem that they want to end up in Linus's tree, they must |
belaran@964 | 302 find out who the subsystem's maintainer is, and ask that maintainer to |
belaran@964 | 303 take their change. If the maintainer reviews their changes and agrees |
belaran@964 | 304 to take them, they'll pass them along to Linus in due course. |
belaran@964 | 305 </para> |
belaran@964 | 306 |
belaran@964 | 307 <para>Individual lieutenants have their own approaches to reviewing, |
belaran@964 | 308 accepting, and publishing changes; and for deciding when to feed them |
belaran@964 | 309 to Linus. In addition, there are several well known branches that |
belaran@964 | 310 people use for different purposes. For example, a few people maintain |
belaran@964 | 311 <quote>stable</quote> repositories of older versions of the kernel, to which they |
belaran@964 | 312 apply critical fixes as needed. Some maintainers publish multiple |
belaran@964 | 313 trees: one for experimental changes; one for changes that they are |
belaran@964 | 314 about to feed upstream; and so on. Others just publish a single |
belaran@964 | 315 tree. |
belaran@964 | 316 </para> |
belaran@964 | 317 |
belaran@964 | 318 <para>This model has two notable features. The first is that it's <quote>pull |
belaran@964 | 319 only</quote>. You have to ask, convince, or beg another developer to take a |
belaran@964 | 320 change from you, because there are almost no trees to which more than |
belaran@964 | 321 one person can push, and there's no way to push changes into a tree |
belaran@964 | 322 that someone else controls. |
belaran@964 | 323 </para> |
belaran@964 | 324 |
belaran@964 | 325 <para>The second is that it's based on reputation and acclaim. If you're an |
belaran@964 | 326 unknown, Linus will probably ignore changes from you without even |
belaran@964 | 327 responding. But a subsystem maintainer will probably review them, and |
belaran@964 | 328 will likely take them if they pass their criteria for suitability. |
belaran@964 | 329 The more <quote>good</quote> changes you contribute to a maintainer, the more |
belaran@964 | 330 likely they are to trust your judgment and accept your changes. If |
belaran@964 | 331 you're well-known and maintain a long-lived branch for something Linus |
belaran@964 | 332 hasn't yet accepted, people with similar interests may pull your |
belaran@964 | 333 changes regularly to keep up with your work. |
belaran@964 | 334 </para> |
belaran@964 | 335 |
belaran@964 | 336 <para>Reputation and acclaim don't necessarily cross subsystem or <quote>people</quote> |
belaran@964 | 337 boundaries. If you're a respected but specialised storage hacker, and |
belaran@964 | 338 you try to fix a networking bug, that change will receive a level of |
belaran@964 | 339 scrutiny from a network maintainer comparable to a change from a |
belaran@964 | 340 complete stranger. |
belaran@964 | 341 </para> |
belaran@964 | 342 |
belaran@964 | 343 <para>To people who come from more orderly project backgrounds, the |
belaran@964 | 344 comparatively chaotic Linux kernel development process often seems |
belaran@964 | 345 completely insane. It's subject to the whims of individuals; people |
belaran@964 | 346 make sweeping changes whenever they deem it appropriate; and the pace |
belaran@964 | 347 of development is astounding. And yet Linux is a highly successful, |
belaran@964 | 348 well-regarded piece of software. |
belaran@964 | 349 </para> |
belaran@964 | 350 |
belaran@964 | 351 </sect2> |
belaran@964 | 352 <sect2> |
belaran@964 | 353 <title>Pull-only versus shared-push collaboration</title> |
belaran@964 | 354 |
belaran@964 | 355 <para>A perpetual source of heat in the open source community is whether a |
belaran@964 | 356 development model in which people only ever pull changes from others |
belaran@964 | 357 is <quote>better than</quote> one in which multiple people can push changes to a |
belaran@964 | 358 shared repository. |
belaran@964 | 359 </para> |
belaran@964 | 360 |
belaran@964 | 361 <para>Typically, the backers of the shared-push model use tools that |
belaran@964 | 362 actively enforce this approach. If you're using a centralised |
belaran@964 | 363 revision control tool such as Subversion, there's no way to make a |
belaran@964 | 364 choice over which model you'll use: the tool gives you shared-push, |
belaran@964 | 365 and if you want to do anything else, you'll have to roll your own |
belaran@964 | 366 approach on top (such as applying a patch by hand). |
belaran@964 | 367 </para> |
belaran@964 | 368 |
belaran@964 | 369 <para>A good distributed revision control tool, such as Mercurial, will |
belaran@964 | 370 support both models. You and your collaborators can then structure |
belaran@964 | 371 how you work together based on your own needs and preferences, not on |
belaran@964 | 372 what contortions your tools force you into. |
belaran@964 | 373 </para> |
belaran@964 | 374 |
belaran@964 | 375 </sect2> |
belaran@964 | 376 <sect2> |
belaran@964 | 377 <title>Where collaboration meets branch management</title> |
belaran@964 | 378 |
belaran@964 | 379 <para>Once you and your team set up some shared repositories and start |
belaran@964 | 380 propagating changes back and forth between local and shared repos, you |
belaran@964 | 381 begin to face a related, but slightly different challenge: that of |
belaran@964 | 382 managing the multiple directions in which your team may be moving at |
belaran@964 | 383 once. Even though this subject is intimately related to how your team |
belaran@964 | 384 collaborates, it's dense enough to merit treatment of its own, in |
belaran@964 | 385 chapter <xref linkend="chap:branch"/>. |
belaran@964 | 386 </para> |
belaran@964 | 387 |
belaran@964 | 388 </sect2> |
belaran@964 | 389 </sect1> |
belaran@964 | 390 <sect1> |
belaran@964 | 391 <title>The technical side of sharing</title> |
belaran@964 | 392 |
belaran@964 | 393 <para>The remainder of this chapter is devoted to the question of serving |
belaran@964 | 394 data to your collaborators. |
belaran@964 | 395 </para> |
belaran@964 | 396 |
belaran@964 | 397 </sect1> |
belaran@964 | 398 <sect1> |
belaran@964 | 399 <title>Informal sharing with <command role="hg-cmd">hg serve</command></title> |
belaran@964 | 400 <para>\label{sec:collab:serve} |
belaran@964 | 401 </para> |
belaran@964 | 402 |
belaran@964 | 403 <para>Mercurial's <command role="hg-cmd">hg serve</command> command is wonderfully suited to small, |
belaran@964 | 404 tight-knit, and fast-paced group environments. It also provides a |
belaran@964 | 405 great way to get a feel for using Mercurial commands over a network. |
belaran@964 | 406 </para> |
belaran@964 | 407 |
belaran@964 | 408 <para>Run <command role="hg-cmd">hg serve</command> inside a repository, and in under a second it will |
belaran@964 | 409 bring up a specialised HTTP server; this will accept connections from |
belaran@964 | 410 any client, and serve up data for that repository until you terminate |
belaran@964 | 411 it. Anyone who knows the URL of the server you just started, and can |
belaran@964 | 412 talk to your computer over the network, can then use a web browser or |
belaran@964 | 413 Mercurial to read data from that repository. A URL for a |
belaran@964 | 414 <command role="hg-cmd">hg serve</command> instance running on a laptop is likely to look something |
belaran@964 | 415 like <literal>http://my-laptop.local:8000/</literal>. |
belaran@964 | 416 </para> |
belaran@964 | 417 |
belaran@964 | 418 <para>The <command role="hg-cmd">hg serve</command> command is <emphasis>not</emphasis> a general-purpose web server. |
belaran@964 | 419 It can do only two things: |
belaran@964 | 420 </para> |
belaran@964 | 421 <itemizedlist> |
belaran@964 | 422 <listitem><para>Allow people to browse the history of the repository it's |
belaran@964 | 423 serving, from their normal web browsers. |
belaran@964 | 424 </para> |
belaran@964 | 425 </listitem> |
belaran@964 | 426 <listitem><para>Speak Mercurial's wire protocol, so that people can |
belaran@964 | 427 <command role="hg-cmd">hg clone</command> or <command role="hg-cmd">hg pull</command> changes from that repository. |
belaran@964 | 428 </para> |
belaran@964 | 429 </listitem></itemizedlist> |
belaran@964 | 430 <para>In particular, <command role="hg-cmd">hg serve</command> won't allow remote users to <emphasis>modify</emphasis> |
belaran@964 | 431 your repository. It's intended for read-only use. |
belaran@964 | 432 </para> |
belaran@964 | 433 |
belaran@964 | 434 <para>If you're getting started with Mercurial, there's nothing to prevent |
belaran@964 | 435 you from using <command role="hg-cmd">hg serve</command> to serve up a repository on your own |
belaran@964 | 436 computer, then use commands like <command role="hg-cmd">hg clone</command>, <command role="hg-cmd">hg incoming</command>, and |
belaran@964 | 437 so on to talk to that server as if the repository was hosted remotely. |
belaran@964 | 438 This can help you to quickly get acquainted with using commands on |
belaran@964 | 439 network-hosted repositories. |
belaran@964 | 440 </para> |
belaran@964 | 441 |
belaran@964 | 442 <sect2> |
belaran@964 | 443 <title>A few things to keep in mind</title> |
belaran@964 | 444 |
belaran@964 | 445 <para>Because it provides unauthenticated read access to all clients, you |
belaran@964 | 446 should only use <command role="hg-cmd">hg serve</command> in an environment where you either don't |
belaran@964 | 447 care, or have complete control over, who can access your network and |
belaran@964 | 448 pull data from your repository. |
belaran@964 | 449 </para> |
belaran@964 | 450 |
belaran@964 | 451 <para>The <command role="hg-cmd">hg serve</command> command knows nothing about any firewall software |
belaran@964 | 452 you might have installed on your system or network. It cannot detect |
belaran@964 | 453 or control your firewall software. If other people are unable to talk |
belaran@964 | 454 to a running <command role="hg-cmd">hg serve</command> instance, the second thing you should do |
belaran@964 | 455 (<emphasis>after</emphasis> you make sure that they're using the correct URL) is |
belaran@964 | 456 check your firewall configuration. |
belaran@964 | 457 </para> |
belaran@964 | 458 |
belaran@964 | 459 <para>By default, <command role="hg-cmd">hg serve</command> listens for incoming connections on |
belaran@964 | 460 port 8000. If another process is already listening on the port you |
belaran@964 | 461 want to use, you can specify a different port to listen on using the |
belaran@964 | 462 <option role="hg-opt-serve">-p</option> option. |
belaran@964 | 463 </para> |
belaran@964 | 464 |
belaran@964 | 465 <para>Normally, when <command role="hg-cmd">hg serve</command> starts, it prints no output, which can be |
belaran@964 | 466 a bit unnerving. If you'd like to confirm that it is indeed running |
belaran@964 | 467 correctly, and find out what URL you should send to your |
belaran@964 | 468 collaborators, start it with the <option role="hg-opt-global">-v</option> option. |
belaran@964 | 469 </para> |
belaran@964 | 470 |
belaran@964 | 471 </sect2> |
belaran@964 | 472 </sect1> |
belaran@964 | 473 <sect1> |
belaran@964 | 474 <title>Using the Secure Shell (ssh) protocol</title> |
belaran@964 | 475 <para>\label{sec:collab:ssh} |
belaran@964 | 476 </para> |
belaran@964 | 477 |
belaran@964 | 478 <para>You can pull and push changes securely over a network connection using |
belaran@964 | 479 the Secure Shell (<literal>ssh</literal>) protocol. To use this successfully, |
belaran@964 | 480 you may have to do a little bit of configuration on the client or |
belaran@964 | 481 server sides. |
belaran@964 | 482 </para> |
belaran@964 | 483 |
belaran@964 | 484 <para>If you're not familiar with ssh, it's a network protocol that lets you |
belaran@964 | 485 securely communicate with another computer. To use it with Mercurial, |
belaran@964 | 486 you'll be setting up one or more user accounts on a server so that |
belaran@964 | 487 remote users can log in and execute commands. |
belaran@964 | 488 </para> |
belaran@964 | 489 |
belaran@964 | 490 <para>(If you <emphasis>are</emphasis> familiar with ssh, you'll probably find some of the |
belaran@964 | 491 material that follows to be elementary in nature.) |
belaran@964 | 492 </para> |
belaran@964 | 493 |
belaran@964 | 494 <sect2> |
belaran@964 | 495 <title>How to read and write ssh URLs</title> |
belaran@964 | 496 |
belaran@964 | 497 <para>An ssh URL tends to look like this: |
belaran@964 | 498 </para> |
belaran@964 | 499 <programlisting> |
belaran@964 | 500 <para> ssh://bos@hg.serpentine.com:22/hg/hgbook |
belaran@964 | 501 </para> |
belaran@964 | 502 </programlisting> |
belaran@964 | 503 <orderedlist> |
belaran@964 | 504 <listitem><para>The <quote><literal>ssh://</literal></quote> part tells Mercurial to use the ssh |
belaran@964 | 505 protocol. |
belaran@964 | 506 </para> |
belaran@964 | 507 </listitem> |
belaran@964 | 508 <listitem><para>The <quote><literal>bos@</literal></quote> component indicates what username to log |
belaran@964 | 509 into the server as. You can leave this out if the remote username |
belaran@964 | 510 is the same as your local username. |
belaran@964 | 511 </para> |
belaran@964 | 512 </listitem> |
belaran@964 | 513 <listitem><para>The <quote><literal>hg.serpentine.com</literal></quote> gives the hostname of the |
belaran@964 | 514 server to log into. |
belaran@964 | 515 </para> |
belaran@964 | 516 </listitem> |
belaran@964 | 517 <listitem><para>The <quote>:22</quote> identifies the port number to connect to the server |
belaran@964 | 518 on. The default port is 22, so you only need to specify this part |
belaran@964 | 519 if you're <emphasis>not</emphasis> using port 22. |
belaran@964 | 520 </para> |
belaran@964 | 521 </listitem> |
belaran@964 | 522 <listitem><para>The remainder of the URL is the local path to the repository on |
belaran@964 | 523 the server. |
belaran@964 | 524 </para> |
belaran@964 | 525 </listitem></orderedlist> |
belaran@964 | 526 |
belaran@964 | 527 <para>There's plenty of scope for confusion with the path component of ssh |
belaran@964 | 528 URLs, as there is no standard way for tools to interpret it. Some |
belaran@964 | 529 programs behave differently than others when dealing with these paths. |
belaran@964 | 530 This isn't an ideal situation, but it's unlikely to change. Please |
belaran@964 | 531 read the following paragraphs carefully. |
belaran@964 | 532 </para> |
belaran@964 | 533 |
belaran@964 | 534 <para>Mercurial treats the path to a repository on the server as relative to |
belaran@964 | 535 the remote user's home directory. For example, if user <literal>foo</literal> |
belaran@964 | 536 on the server has a home directory of <filename class="directory">/home/foo</filename>, then an ssh |
belaran@964 | 537 URL that contains a path component of <filename class="directory">bar</filename> |
belaran@964 | 538 <emphasis>really</emphasis> refers to the directory <filename class="directory">/home/foo/bar</filename>. |
belaran@964 | 539 </para> |
belaran@964 | 540 |
belaran@964 | 541 <para>If you want to specify a path relative to another user's home |
belaran@964 | 542 directory, you can use a path that starts with a tilde character |
belaran@964 | 543 followed by the user's name (let's call them <literal>otheruser</literal>), like |
belaran@964 | 544 this. |
belaran@964 | 545 </para> |
belaran@964 | 546 <programlisting> |
belaran@964 | 547 <para> ssh://server/ otheruser/hg/repo |
belaran@964 | 548 </para> |
belaran@964 | 549 </programlisting> |
belaran@964 | 550 |
belaran@964 | 551 <para>And if you really want to specify an <emphasis>absolute</emphasis> path on the |
belaran@964 | 552 server, begin the path component with two slashes, as in this example. |
belaran@964 | 553 </para> |
belaran@964 | 554 <programlisting> |
belaran@964 | 555 <para> ssh://server//absolute/path |
belaran@964 | 556 </para> |
belaran@964 | 557 </programlisting> |
belaran@964 | 558 |
belaran@964 | 559 </sect2> |
belaran@964 | 560 <sect2> |
belaran@964 | 561 <title>Finding an ssh client for your system</title> |
belaran@964 | 562 |
belaran@964 | 563 <para>Almost every Unix-like system comes with OpenSSH preinstalled. If |
belaran@964 | 564 you're using such a system, run <literal>which ssh</literal> to find out if |
belaran@964 | 565 the <command>ssh</command> command is installed (it's usually in |
belaran@964 | 566 <filename class="directory">/usr/bin</filename>). In the unlikely event that it isn't present, |
belaran@964 | 567 take a look at your system documentation to figure out how to install |
belaran@964 | 568 it. |
belaran@964 | 569 </para> |
belaran@964 | 570 |
belaran@964 | 571 <para>On Windows, you'll first need to download a suitable ssh |
belaran@964 | 572 client. There are two alternatives. |
belaran@964 | 573 </para> |
belaran@964 | 574 <itemizedlist> |
belaran@964 | 575 <listitem><para>Simon Tatham's excellent PuTTY package <citation>web:putty</citation> provides |
belaran@964 | 576 a complete suite of ssh client commands. |
belaran@964 | 577 </para> |
belaran@964 | 578 </listitem> |
belaran@964 | 579 <listitem><para>If you have a high tolerance for pain, you can use the Cygwin |
belaran@964 | 580 port of OpenSSH. |
belaran@964 | 581 </para> |
belaran@964 | 582 </listitem></itemizedlist> |
belaran@964 | 583 <para>In either case, you'll need to edit your \hgini\ file to tell |
belaran@964 | 584 Mercurial where to find the actual client command. For example, if |
belaran@964 | 585 you're using PuTTY, you'll need to use the <command>plink</command> command as |
belaran@964 | 586 a command-line ssh client. |
belaran@964 | 587 </para> |
belaran@964 | 588 <programlisting> |
belaran@964 | 589 <para> [ui] |
belaran@964 | 590 ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key" |
belaran@964 | 591 </para> |
belaran@964 | 592 </programlisting> |
belaran@964 | 593 |
belaran@964 | 594 <note> |
belaran@964 | 595 <para> The path to <command>plink</command> shouldn't contain any whitespace |
belaran@964 | 596 characters, or Mercurial may not be able to run it correctly (so |
belaran@964 | 597 putting it in <filename class="directory">C:\\Program Files</filename> is probably not a good |
belaran@964 | 598 idea). |
belaran@964 | 599 </para> |
belaran@964 | 600 </note> |
belaran@964 | 601 |
belaran@964 | 602 </sect2> |
belaran@964 | 603 <sect2> |
belaran@964 | 604 <title>Generating a key pair</title> |
belaran@964 | 605 |
belaran@964 | 606 <para>To avoid the need to repetitively type a password every time you need |
belaran@964 | 607 to use your ssh client, I recommend generating a key pair. On a |
belaran@964 | 608 Unix-like system, the <command>ssh-keygen</command> command will do the trick. |
belaran@964 | 609 On Windows, if you're using PuTTY, the <command>puttygen</command> command is |
belaran@964 | 610 what you'll need. |
belaran@964 | 611 </para> |
belaran@964 | 612 |
belaran@964 | 613 <para>When you generate a key pair, it's usually <emphasis>highly</emphasis> advisable to |
belaran@964 | 614 protect it with a passphrase. (The only time that you might not want |
belaran@964 | 615 to do this is when you're using the ssh protocol for automated tasks |
belaran@964 | 616 on a secure network.) |
belaran@964 | 617 </para> |
belaran@964 | 618 |
belaran@964 | 619 <para>Simply generating a key pair isn't enough, however. You'll need to |
belaran@964 | 620 add the public key to the set of authorised keys for whatever user |
belaran@964 | 621 you're logging in remotely as. For servers using OpenSSH (the vast |
belaran@964 | 622 majority), this will mean adding the public key to a list in a file |
belaran@964 | 623 called <filename role="special">authorized_keys</filename> in their <filename role="special" class="directory">.ssh</filename> |
belaran@964 | 624 directory. |
belaran@964 | 625 </para> |
belaran@964 | 626 |
belaran@964 | 627 <para>On a Unix-like system, your public key will have a <filename>.pub</filename> |
belaran@964 | 628 extension. If you're using <command>puttygen</command> on Windows, you can |
belaran@964 | 629 save the public key to a file of your choosing, or paste it from the |
belaran@964 | 630 window it's displayed in straight into the |
belaran@964 | 631 <filename role="special">authorized_keys</filename> file. |
belaran@964 | 632 </para> |
belaran@964 | 633 |
belaran@964 | 634 </sect2> |
belaran@964 | 635 <sect2> |
belaran@964 | 636 <title>Using an authentication agent</title> |
belaran@964 | 637 |
belaran@964 | 638 <para>An authentication agent is a daemon that stores passphrases in memory |
belaran@964 | 639 (so it will forget passphrases if you log out and log back in again). |
belaran@964 | 640 An ssh client will notice if it's running, and query it for a |
belaran@964 | 641 passphrase. If there's no authentication agent running, or the agent |
belaran@964 | 642 doesn't store the necessary passphrase, you'll have to type your |
belaran@964 | 643 passphrase every time Mercurial tries to communicate with a server on |
belaran@964 | 644 your behalf (e.g. whenever you pull or push changes). |
belaran@964 | 645 </para> |
belaran@964 | 646 |
belaran@964 | 647 <para>The downside of storing passphrases in an agent is that it's possible |
belaran@964 | 648 for a well-prepared attacker to recover the plain text of your |
belaran@964 | 649 passphrases, in some cases even if your system has been power-cycled. |
belaran@964 | 650 You should make your own judgment as to whether this is an acceptable |
belaran@964 | 651 risk. It certainly saves a lot of repeated typing. |
belaran@964 | 652 </para> |
belaran@964 | 653 |
belaran@964 | 654 <para>On Unix-like systems, the agent is called <command>ssh-agent</command>, and |
belaran@964 | 655 it's often run automatically for you when you log in. You'll need to |
belaran@964 | 656 use the <command>ssh-add</command> command to add passphrases to the agent's |
belaran@964 | 657 store. On Windows, if you're using PuTTY, the <command>pageant</command> |
belaran@964 | 658 command acts as the agent. It adds an icon to your system tray that |
belaran@964 | 659 will let you manage stored passphrases. |
belaran@964 | 660 </para> |
belaran@964 | 661 |
belaran@964 | 662 </sect2> |
belaran@964 | 663 <sect2> |
belaran@964 | 664 <title>Configuring the server side properly</title> |
belaran@964 | 665 |
belaran@964 | 666 <para>Because ssh can be fiddly to set up if you're new to it, there's a |
belaran@964 | 667 variety of things that can go wrong. Add Mercurial on top, and |
belaran@964 | 668 there's plenty more scope for head-scratching. Most of these |
belaran@964 | 669 potential problems occur on the server side, not the client side. The |
belaran@964 | 670 good news is that once you've gotten a configuration working, it will |
belaran@964 | 671 usually continue to work indefinitely. |
belaran@964 | 672 </para> |
belaran@964 | 673 |
belaran@964 | 674 <para>Before you try using Mercurial to talk to an ssh server, it's best to |
belaran@964 | 675 make sure that you can use the normal <command>ssh</command> or <command>putty</command> |
belaran@964 | 676 command to talk to the server first. If you run into problems with |
belaran@964 | 677 using these commands directly, Mercurial surely won't work. Worse, it |
belaran@964 | 678 will obscure the underlying problem. Any time you want to debug |
belaran@964 | 679 ssh-related Mercurial problems, you should drop back to making sure |
belaran@964 | 680 that plain ssh client commands work first, <emphasis>before</emphasis> you worry |
belaran@964 | 681 about whether there's a problem with Mercurial. |
belaran@964 | 682 </para> |
belaran@964 | 683 |
belaran@964 | 684 <para>The first thing to be sure of on the server side is that you can |
belaran@964 | 685 actually log in from another machine at all. If you can't use |
belaran@964 | 686 <command>ssh</command> or <command>putty</command> to log in, the error message you get |
belaran@964 | 687 may give you a few hints as to what's wrong. The most common problems |
belaran@964 | 688 are as follows. |
belaran@964 | 689 </para> |
belaran@964 | 690 <itemizedlist> |
belaran@964 | 691 <listitem><para>If you get a <quote>connection refused</quote> error, either there isn't an |
belaran@964 | 692 SSH daemon running on the server at all, or it's inaccessible due to |
belaran@964 | 693 firewall configuration. |
belaran@964 | 694 </para> |
belaran@964 | 695 </listitem> |
belaran@964 | 696 <listitem><para>If you get a <quote>no route to host</quote> error, you either have an |
belaran@964 | 697 incorrect address for the server or a seriously locked down firewall |
belaran@964 | 698 that won't admit its existence at all. |
belaran@964 | 699 </para> |
belaran@964 | 700 </listitem> |
belaran@964 | 701 <listitem><para>If you get a <quote>permission denied</quote> error, you may have mistyped |
belaran@964 | 702 the username on the server, or you could have mistyped your key's |
belaran@964 | 703 passphrase or the remote user's password. |
belaran@964 | 704 </para> |
belaran@964 | 705 </listitem></itemizedlist> |
belaran@964 | 706 <para>In summary, if you're having trouble talking to the server's ssh |
belaran@964 | 707 daemon, first make sure that one is running at all. On many systems |
belaran@964 | 708 it will be installed, but disabled, by default. Once you're done with |
belaran@964 | 709 this step, you should then check that the server's firewall is |
belaran@964 | 710 configured to allow incoming connections on the port the ssh daemon is |
belaran@964 | 711 listening on (usually 22). Don't worry about more exotic |
belaran@964 | 712 possibilities for misconfiguration until you've checked these two |
belaran@964 | 713 first. |
belaran@964 | 714 </para> |
belaran@964 | 715 |
belaran@964 | 716 <para>If you're using an authentication agent on the client side to store |
belaran@964 | 717 passphrases for your keys, you ought to be able to log into the server |
belaran@964 | 718 without being prompted for a passphrase or a password. If you're |
belaran@964 | 719 prompted for a passphrase, there are a few possible culprits. |
belaran@964 | 720 </para> |
belaran@964 | 721 <itemizedlist> |
belaran@964 | 722 <listitem><para>You might have forgotten to use <command>ssh-add</command> or |
belaran@964 | 723 <command>pageant</command> to store the passphrase. |
belaran@964 | 724 </para> |
belaran@964 | 725 </listitem> |
belaran@964 | 726 <listitem><para>You might have stored the passphrase for the wrong key. |
belaran@964 | 727 </para> |
belaran@964 | 728 </listitem></itemizedlist> |
belaran@964 | 729 <para>If you're being prompted for the remote user's password, there are |
belaran@964 | 730 another few possible problems to check. |
belaran@964 | 731 </para> |
belaran@964 | 732 <itemizedlist> |
belaran@964 | 733 <listitem><para>Either the user's home directory or their <filename role="special" class="directory">.ssh</filename> |
belaran@964 | 734 directory might have excessively liberal permissions. As a result, |
belaran@964 | 735 the ssh daemon will not trust or read their |
belaran@964 | 736 <filename role="special">authorized_keys</filename> file. For example, a group-writable |
belaran@964 | 737 home or <filename role="special" class="directory">.ssh</filename> directory will often cause this symptom. |
belaran@964 | 738 </para> |
belaran@964 | 739 </listitem> |
belaran@964 | 740 <listitem><para>The user's <filename role="special">authorized_keys</filename> file may have a problem. |
belaran@964 | 741 If anyone other than the user owns or can write to that file, the |
belaran@964 | 742 ssh daemon will not trust or read it. |
belaran@964 | 743 </para> |
belaran@964 | 744 </listitem></itemizedlist> |
belaran@964 | 745 |
belaran@964 | 746 <para>In the ideal world, you should be able to run the following command |
belaran@964 | 747 successfully, and it should print exactly one line of output, the |
belaran@964 | 748 current date and time. |
belaran@964 | 749 </para> |
belaran@964 | 750 <programlisting> |
belaran@964 | 751 <para> ssh myserver date |
belaran@964 | 752 </para> |
belaran@964 | 753 </programlisting> |
belaran@964 | 754 |
belaran@964 | 755 <para>If, on your server, you have login scripts that print banners or other |
belaran@964 | 756 junk even when running non-interactive commands like this, you should |
belaran@964 | 757 fix them before you continue, so that they only print output if |
belaran@964 | 758 they're run interactively. Otherwise these banners will at least |
belaran@964 | 759 clutter up Mercurial's output. Worse, they could potentially cause |
belaran@964 | 760 problems with running Mercurial commands remotely. Mercurial makes |
belaran@964 | 761 tries to detect and ignore banners in non-interactive <command>ssh</command> |
belaran@964 | 762 sessions, but it is not foolproof. (If you're editing your login |
belaran@964 | 763 scripts on your server, the usual way to see if a login script is |
belaran@964 | 764 running in an interactive shell is to check the return code from the |
belaran@964 | 765 command <literal>tty -s</literal>.) |
belaran@964 | 766 </para> |
belaran@964 | 767 |
belaran@964 | 768 <para>Once you've verified that plain old ssh is working with your server, |
belaran@964 | 769 the next step is to ensure that Mercurial runs on the server. The |
belaran@964 | 770 following command should run successfully: |
belaran@964 | 771 </para> |
belaran@964 | 772 <programlisting> |
belaran@964 | 773 <para> ssh myserver hg version |
belaran@964 | 774 </para> |
belaran@964 | 775 </programlisting> |
belaran@964 | 776 <para>If you see an error message instead of normal <command role="hg-cmd">hg version</command> output, |
belaran@964 | 777 this is usually because you haven't installed Mercurial to |
belaran@964 | 778 <filename class="directory">/usr/bin</filename>. Don't worry if this is the case; you don't need |
belaran@964 | 779 to do that. But you should check for a few possible problems. |
belaran@964 | 780 </para> |
belaran@964 | 781 <itemizedlist> |
belaran@964 | 782 <listitem><para>Is Mercurial really installed on the server at all? I know this |
belaran@964 | 783 sounds trivial, but it's worth checking! |
belaran@964 | 784 </para> |
belaran@964 | 785 </listitem> |
belaran@964 | 786 <listitem><para>Maybe your shell's search path (usually set via the <envar>PATH</envar> |
belaran@964 | 787 environment variable) is simply misconfigured. |
belaran@964 | 788 </para> |
belaran@964 | 789 </listitem> |
belaran@964 | 790 <listitem><para>Perhaps your <envar>PATH</envar> environment variable is only being set |
belaran@964 | 791 to point to the location of the <command>hg</command> executable if the login |
belaran@964 | 792 session is interactive. This can happen if you're setting the path |
belaran@964 | 793 in the wrong shell login script. See your shell's documentation for |
belaran@964 | 794 details. |
belaran@964 | 795 </para> |
belaran@964 | 796 </listitem> |
belaran@964 | 797 <listitem><para>The <envar>PYTHONPATH</envar> environment variable may need to contain |
belaran@964 | 798 the path to the Mercurial Python modules. It might not be set at |
belaran@964 | 799 all; it could be incorrect; or it may be set only if the login is |
belaran@964 | 800 interactive. |
belaran@964 | 801 </para> |
belaran@964 | 802 </listitem></itemizedlist> |
belaran@964 | 803 |
belaran@964 | 804 <para>If you can run <command role="hg-cmd">hg version</command> over an ssh connection, well done! |
belaran@964 | 805 You've got the server and client sorted out. You should now be able |
belaran@964 | 806 to use Mercurial to access repositories hosted by that username on |
belaran@964 | 807 that server. If you run into problems with Mercurial and ssh at this |
belaran@964 | 808 point, try using the <option role="hg-opt-global">--debug</option> option to get a clearer picture |
belaran@964 | 809 of what's going on. |
belaran@964 | 810 </para> |
belaran@964 | 811 |
belaran@964 | 812 </sect2> |
belaran@964 | 813 <sect2> |
belaran@964 | 814 <title>Using compression with ssh</title> |
belaran@964 | 815 |
belaran@964 | 816 <para>Mercurial does not compress data when it uses the ssh protocol, |
belaran@964 | 817 because the ssh protocol can transparently compress data. However, |
belaran@964 | 818 the default behaviour of ssh clients is <emphasis>not</emphasis> to request |
belaran@964 | 819 compression. |
belaran@964 | 820 </para> |
belaran@964 | 821 |
belaran@964 | 822 <para>Over any network other than a fast LAN (even a wireless network), |
belaran@964 | 823 using compression is likely to significantly speed up Mercurial's |
belaran@964 | 824 network operations. For example, over a WAN, someone measured |
belaran@964 | 825 compression as reducing the amount of time required to clone a |
belaran@964 | 826 particularly large repository from 51 minutes to 17 minutes. |
belaran@964 | 827 </para> |
belaran@964 | 828 |
belaran@964 | 829 <para>Both <command>ssh</command> and <command>plink</command> accept a <option role="cmd-opt-ssh">-C</option> |
belaran@964 | 830 option which turns on compression. You can easily edit your <filename role="special"> /.hgrc</filename>\ to |
belaran@964 | 831 enable compression for all of Mercurial's uses of the ssh protocol. |
belaran@964 | 832 </para> |
belaran@964 | 833 <programlisting> |
belaran@964 | 834 <para> [ui] |
belaran@964 | 835 ssh = ssh -C |
belaran@964 | 836 </para> |
belaran@964 | 837 </programlisting> |
belaran@964 | 838 |
belaran@964 | 839 <para>If you use <command>ssh</command>, you can configure it to always use |
belaran@964 | 840 compression when talking to your server. To do this, edit your |
belaran@964 | 841 <filename role="special">.ssh/config</filename> file (which may not yet exist), as follows. |
belaran@964 | 842 </para> |
belaran@964 | 843 <programlisting> |
belaran@964 | 844 <para> Host hg |
belaran@964 | 845 Compression yes |
belaran@964 | 846 HostName hg.example.com |
belaran@964 | 847 </para> |
belaran@964 | 848 </programlisting> |
belaran@964 | 849 <para>This defines an alias, <literal>hg</literal>. When you use it on the |
belaran@964 | 850 <command>ssh</command> command line or in a Mercurial <literal>ssh</literal>-protocol |
belaran@964 | 851 URL, it will cause <command>ssh</command> to connect to <literal>hg.example.com</literal> |
belaran@964 | 852 and use compression. This gives you both a shorter name to type and |
belaran@964 | 853 compression, each of which is a good thing in its own right. |
belaran@964 | 854 </para> |
belaran@964 | 855 |
belaran@964 | 856 </sect2> |
belaran@964 | 857 </sect1> |
belaran@964 | 858 <sect1> |
belaran@964 | 859 <title>Serving over HTTP using CGI</title> |
belaran@964 | 860 <para>\label{sec:collab:cgi} |
belaran@964 | 861 </para> |
belaran@964 | 862 |
belaran@964 | 863 <para>Depending on how ambitious you are, configuring Mercurial's CGI |
belaran@964 | 864 interface can take anything from a few moments to several hours. |
belaran@964 | 865 </para> |
belaran@964 | 866 |
belaran@964 | 867 <para>We'll begin with the simplest of examples, and work our way towards a |
belaran@964 | 868 more complex configuration. Even for the most basic case, you're |
belaran@964 | 869 almost certainly going to need to read and modify your web server's |
belaran@964 | 870 configuration. |
belaran@964 | 871 </para> |
belaran@964 | 872 |
belaran@964 | 873 <note> |
belaran@964 | 874 <para> Configuring a web server is a complex, fiddly, and highly |
belaran@964 | 875 system-dependent activity. I can't possibly give you instructions |
belaran@964 | 876 that will cover anything like all of the cases you will encounter. |
belaran@964 | 877 Please use your discretion and judgment in following the sections |
belaran@964 | 878 below. Be prepared to make plenty of mistakes, and to spend a lot |
belaran@964 | 879 of time reading your server's error logs. |
belaran@964 | 880 </para> |
belaran@964 | 881 </note> |
belaran@964 | 882 |
belaran@964 | 883 <sect2> |
belaran@964 | 884 <title>Web server configuration checklist</title> |
belaran@964 | 885 |
belaran@964 | 886 <para>Before you continue, do take a few moments to check a few aspects of |
belaran@964 | 887 your system's setup. |
belaran@964 | 888 </para> |
belaran@964 | 889 |
belaran@964 | 890 <orderedlist> |
belaran@964 | 891 <listitem><para>Do you have a web server installed at all? Mac OS X ships with |
belaran@964 | 892 Apache, but many other systems may not have a web server installed. |
belaran@964 | 893 </para> |
belaran@964 | 894 </listitem> |
belaran@964 | 895 <listitem><para>If you have a web server installed, is it actually running? On |
belaran@964 | 896 most systems, even if one is present, it will be disabled by |
belaran@964 | 897 default. |
belaran@964 | 898 </para> |
belaran@964 | 899 </listitem> |
belaran@964 | 900 <listitem><para>Is your server configured to allow you to run CGI programs in |
belaran@964 | 901 the directory where you plan to do so? Most servers default to |
belaran@964 | 902 explicitly disabling the ability to run CGI programs. |
belaran@964 | 903 </para> |
belaran@964 | 904 </listitem></orderedlist> |
belaran@964 | 905 |
belaran@964 | 906 <para>If you don't have a web server installed, and don't have substantial |
belaran@964 | 907 experience configuring Apache, you should consider using the |
belaran@964 | 908 <literal>lighttpd</literal> web server instead of Apache. Apache has a |
belaran@964 | 909 well-deserved reputation for baroque and confusing configuration. |
belaran@964 | 910 While <literal>lighttpd</literal> is less capable in some ways than Apache, most |
belaran@964 | 911 of these capabilities are not relevant to serving Mercurial |
belaran@964 | 912 repositories. And <literal>lighttpd</literal> is undeniably <emphasis>much</emphasis> easier |
belaran@964 | 913 to get started with than Apache. |
belaran@964 | 914 </para> |
belaran@964 | 915 |
belaran@964 | 916 </sect2> |
belaran@964 | 917 <sect2> |
belaran@964 | 918 <title>Basic CGI configuration</title> |
belaran@964 | 919 |
belaran@964 | 920 <para>On Unix-like systems, it's common for users to have a subdirectory |
belaran@964 | 921 named something like <filename class="directory">public_html</filename> in their home directory, |
belaran@964 | 922 from which they can serve up web pages. A file named <filename>foo</filename> |
belaran@964 | 923 in this directory will be accessible at a URL of the form |
belaran@964 | 924 <literal>http://www.example.com/\ {</literal>username/foo}. |
belaran@964 | 925 </para> |
belaran@964 | 926 |
belaran@964 | 927 <para>To get started, find the <filename role="special">hgweb.cgi</filename> script that should be |
belaran@964 | 928 present in your Mercurial installation. If you can't quickly find a |
belaran@964 | 929 local copy on your system, simply download one from the master |
belaran@964 | 930 Mercurial repository at |
belaran@964 | 931 <ulink url="http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>. |
belaran@964 | 932 </para> |
belaran@964 | 933 |
belaran@964 | 934 <para>You'll need to copy this script into your <filename class="directory">public_html</filename> |
belaran@964 | 935 directory, and ensure that it's executable. |
belaran@964 | 936 </para> |
belaran@964 | 937 <programlisting> |
belaran@964 | 938 <para> cp .../hgweb.cgi /public_html |
belaran@964 | 939 chmod 755 /public_html/hgweb.cgi |
belaran@964 | 940 </para> |
belaran@964 | 941 </programlisting> |
belaran@964 | 942 <para>The <literal>755</literal> argument to <command>chmod</command> is a little more general |
belaran@964 | 943 than just making the script executable: it ensures that the script is |
belaran@964 | 944 executable by anyone, and that <quote>group</quote> and <quote>other</quote> write |
belaran@964 | 945 permissions are <emphasis>not</emphasis> set. If you were to leave those write |
belaran@964 | 946 permissions enabled, Apache's <literal>suexec</literal> subsystem would likely |
belaran@964 | 947 refuse to execute the script. In fact, <literal>suexec</literal> also insists |
belaran@964 | 948 that the <emphasis>directory</emphasis> in which the script resides must not be |
belaran@964 | 949 writable by others. |
belaran@964 | 950 </para> |
belaran@964 | 951 <programlisting> |
belaran@964 | 952 <para> chmod 755 /public_html |
belaran@964 | 953 </para> |
belaran@964 | 954 </programlisting> |
belaran@964 | 955 |
belaran@964 | 956 <sect3> |
belaran@964 | 957 <title>What could <emphasis>possibly</emphasis> go wrong?</title> |
belaran@964 | 958 <para>\label{sec:collab:wtf} |
belaran@964 | 959 </para> |
belaran@964 | 960 |
belaran@964 | 961 <para>Once you've copied the CGI script into place, go into a web browser, |
belaran@964 | 962 and try to open the URL <ulink url="http://myhostname/ myuser/hgweb.cgi">http://myhostname/ myuser/hgweb.cgi</ulink>, |
belaran@964 | 963 <emphasis>but</emphasis> brace yourself for instant failure. There's a high |
belaran@964 | 964 probability that trying to visit this URL will fail, and there are |
belaran@964 | 965 many possible reasons for this. In fact, you're likely to stumble |
belaran@964 | 966 over almost every one of the possible errors below, so please read |
belaran@964 | 967 carefully. The following are all of the problems I ran into on a |
belaran@964 | 968 system running Fedora 7, with a fresh installation of Apache, and a |
belaran@964 | 969 user account that I created specially to perform this exercise. |
belaran@964 | 970 </para> |
belaran@964 | 971 |
belaran@964 | 972 <para>Your web server may have per-user directories disabled. If you're |
belaran@964 | 973 using Apache, search your config file for a <literal>UserDir</literal> |
belaran@964 | 974 directive. If there's none present, per-user directories will be |
belaran@964 | 975 disabled. If one exists, but its value is <literal>disabled</literal>, then |
belaran@964 | 976 per-user directories will be disabled. Otherwise, the string after |
belaran@964 | 977 <literal>UserDir</literal> gives the name of the subdirectory that Apache will |
belaran@964 | 978 look in under your home directory, for example <filename class="directory">public_html</filename>. |
belaran@964 | 979 </para> |
belaran@964 | 980 |
belaran@964 | 981 <para>Your file access permissions may be too restrictive. The web server |
belaran@964 | 982 must be able to traverse your home directory and directories under |
belaran@964 | 983 your <filename class="directory">public_html</filename> directory, and read files under the latter |
belaran@964 | 984 too. Here's a quick recipe to help you to make your permissions more |
belaran@964 | 985 appropriate. |
belaran@964 | 986 </para> |
belaran@964 | 987 <programlisting> |
belaran@964 | 988 <para> chmod 755 |
belaran@964 | 989 find /public_html -type d -print0 | xargs -0r chmod 755 |
belaran@964 | 990 find /public_html -type f -print0 | xargs -0r chmod 644 |
belaran@964 | 991 </para> |
belaran@964 | 992 </programlisting> |
belaran@964 | 993 |
belaran@964 | 994 <para>The other possibility with permissions is that you might get a |
belaran@964 | 995 completely empty window when you try to load the script. In this |
belaran@964 | 996 case, it's likely that your access permissions are \emph{too |
belaran@964 | 997 permissive}. Apache's <literal>suexec</literal> subsystem won't execute a |
belaran@964 | 998 script that's group- or world-writable, for example. |
belaran@964 | 999 </para> |
belaran@964 | 1000 |
belaran@964 | 1001 <para>Your web server may be configured to disallow execution of CGI |
belaran@964 | 1002 programs in your per-user web directory. Here's Apache's |
belaran@964 | 1003 default per-user configuration from my Fedora system. |
belaran@964 | 1004 </para> |
belaran@964 | 1005 <programlisting> |
belaran@964 | 1006 <para> <Directory /home/*/public_html> |
belaran@964 | 1007 AllowOverride FileInfo AuthConfig Limit |
belaran@964 | 1008 Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec |
belaran@964 | 1009 <Limit GET POST OPTIONS> |
belaran@964 | 1010 Order allow,deny |
belaran@964 | 1011 Allow from all |
belaran@964 | 1012 </Limit> |
belaran@964 | 1013 <LimitExcept GET POST OPTIONS> |
belaran@964 | 1014 Order deny,allow |
belaran@964 | 1015 Deny from all |
belaran@964 | 1016 </LimitExcept> |
belaran@964 | 1017 </Directory> |
belaran@964 | 1018 </para> |
belaran@964 | 1019 </programlisting> |
belaran@964 | 1020 <para>If you find a similar-looking <literal>Directory</literal> group in your Apache |
belaran@964 | 1021 configuration, the directive to look at inside it is <literal>Options</literal>. |
belaran@964 | 1022 Add <literal>ExecCGI</literal> to the end of this list if it's missing, and |
belaran@964 | 1023 restart the web server. |
belaran@964 | 1024 </para> |
belaran@964 | 1025 |
belaran@964 | 1026 <para>If you find that Apache serves you the text of the CGI script instead |
belaran@964 | 1027 of executing it, you may need to either uncomment (if already present) |
belaran@964 | 1028 or add a directive like this. |
belaran@964 | 1029 </para> |
belaran@964 | 1030 <programlisting> |
belaran@964 | 1031 <para> AddHandler cgi-script .cgi |
belaran@964 | 1032 </para> |
belaran@964 | 1033 </programlisting> |
belaran@964 | 1034 |
belaran@964 | 1035 <para>The next possibility is that you might be served with a colourful |
belaran@964 | 1036 Python backtrace claiming that it can't import a |
belaran@964 | 1037 <literal>mercurial</literal>-related module. This is actually progress! The |
belaran@964 | 1038 server is now capable of executing your CGI script. This error is |
belaran@964 | 1039 only likely to occur if you're running a private installation of |
belaran@964 | 1040 Mercurial, instead of a system-wide version. Remember that the web |
belaran@964 | 1041 server runs the CGI program without any of the environment variables |
belaran@964 | 1042 that you take for granted in an interactive session. If this error |
belaran@964 | 1043 happens to you, edit your copy of <filename role="special">hgweb.cgi</filename> and follow the |
belaran@964 | 1044 directions inside it to correctly set your <envar>PYTHONPATH</envar> |
belaran@964 | 1045 environment variable. |
belaran@964 | 1046 </para> |
belaran@964 | 1047 |
belaran@964 | 1048 <para>Finally, you are <emphasis>certain</emphasis> to by served with another colourful |
belaran@964 | 1049 Python backtrace: this one will complain that it can't find |
belaran@964 | 1050 <filename class="directory">/path/to/repository</filename>. Edit your <filename role="special">hgweb.cgi</filename> script |
belaran@964 | 1051 and replace the <filename class="directory">/path/to/repository</filename> string with the complete |
belaran@964 | 1052 path to the repository you want to serve up. |
belaran@964 | 1053 </para> |
belaran@964 | 1054 |
belaran@964 | 1055 <para>At this point, when you try to reload the page, you should be |
belaran@964 | 1056 presented with a nice HTML view of your repository's history. Whew! |
belaran@964 | 1057 </para> |
belaran@964 | 1058 |
belaran@964 | 1059 </sect3> |
belaran@964 | 1060 <sect3> |
belaran@964 | 1061 <title>Configuring lighttpd</title> |
belaran@964 | 1062 |
belaran@964 | 1063 <para>To be exhaustive in my experiments, I tried configuring the |
belaran@964 | 1064 increasingly popular <literal>lighttpd</literal> web server to serve the same |
belaran@964 | 1065 repository as I described with Apache above. I had already overcome |
belaran@964 | 1066 all of the problems I outlined with Apache, many of which are not |
belaran@964 | 1067 server-specific. As a result, I was fairly sure that my file and |
belaran@964 | 1068 directory permissions were good, and that my <filename role="special">hgweb.cgi</filename> |
belaran@964 | 1069 script was properly edited. |
belaran@964 | 1070 </para> |
belaran@964 | 1071 |
belaran@964 | 1072 <para>Once I had Apache running, getting <literal>lighttpd</literal> to serve the |
belaran@964 | 1073 repository was a snap (in other words, even if you're trying to use |
belaran@964 | 1074 <literal>lighttpd</literal>, you should read the Apache section). I first had |
belaran@964 | 1075 to edit the <literal>mod_access</literal> section of its config file to enable |
belaran@964 | 1076 <literal>mod_cgi</literal> and <literal>mod_userdir</literal>, both of which were |
belaran@964 | 1077 disabled by default on my system. I then added a few lines to the end |
belaran@964 | 1078 of the config file, to configure these modules. |
belaran@964 | 1079 </para> |
belaran@964 | 1080 <programlisting> |
belaran@964 | 1081 <para> userdir.path = "public_html" |
belaran@964 | 1082 cgi.assign = ( ".cgi" => "" ) |
belaran@964 | 1083 </para> |
belaran@964 | 1084 </programlisting> |
belaran@964 | 1085 <para>With this done, <literal>lighttpd</literal> ran immediately for me. If I had |
belaran@964 | 1086 configured <literal>lighttpd</literal> before Apache, I'd almost certainly have |
belaran@964 | 1087 run into many of the same system-level configuration problems as I did |
belaran@964 | 1088 with Apache. However, I found <literal>lighttpd</literal> to be noticeably |
belaran@964 | 1089 easier to configure than Apache, even though I've used Apache for over |
belaran@964 | 1090 a decade, and this was my first exposure to <literal>lighttpd</literal>. |
belaran@964 | 1091 </para> |
belaran@964 | 1092 |
belaran@964 | 1093 </sect3> |
belaran@964 | 1094 </sect2> |
belaran@964 | 1095 <sect2> |
belaran@964 | 1096 <title>Sharing multiple repositories with one CGI script</title> |
belaran@964 | 1097 |
belaran@964 | 1098 <para>The <filename role="special">hgweb.cgi</filename> script only lets you publish a single |
belaran@964 | 1099 repository, which is an annoying restriction. If you want to publish |
belaran@964 | 1100 more than one without wracking yourself with multiple copies of the |
belaran@964 | 1101 same script, each with different names, a better choice is to use the |
belaran@964 | 1102 <filename role="special">hgwebdir.cgi</filename> script. |
belaran@964 | 1103 </para> |
belaran@964 | 1104 |
belaran@964 | 1105 <para>The procedure to configure <filename role="special">hgwebdir.cgi</filename> is only a little |
belaran@964 | 1106 more involved than for <filename role="special">hgweb.cgi</filename>. First, you must obtain |
belaran@964 | 1107 a copy of the script. If you don't have one handy, you can download a |
belaran@964 | 1108 copy from the master Mercurial repository at |
belaran@964 | 1109 <ulink url="http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>. |
belaran@964 | 1110 </para> |
belaran@964 | 1111 |
belaran@964 | 1112 <para>You'll need to copy this script into your <filename class="directory">public_html</filename> |
belaran@964 | 1113 directory, and ensure that it's executable. |
belaran@964 | 1114 </para> |
belaran@964 | 1115 <programlisting> |
belaran@964 | 1116 <para> cp .../hgwebdir.cgi /public_html |
belaran@964 | 1117 chmod 755 /public_html /public_html/hgwebdir.cgi |
belaran@964 | 1118 </para> |
belaran@964 | 1119 </programlisting> |
belaran@964 | 1120 <para>With basic configuration out of the way, try to visit |
belaran@964 | 1121 <ulink url="http://myhostname/ myuser/hgwebdir.cgi">http://myhostname/ myuser/hgwebdir.cgi</ulink> in your browser. It |
belaran@964 | 1122 should display an empty list of repositories. If you get a blank |
belaran@964 | 1123 window or error message, try walking through the list of potential |
belaran@964 | 1124 problems in section <xref linkend="sec:collab:wtf"/>. |
belaran@964 | 1125 </para> |
belaran@964 | 1126 |
belaran@964 | 1127 <para>The <filename role="special">hgwebdir.cgi</filename> script relies on an external |
belaran@964 | 1128 configuration file. By default, it searches for a file named |
belaran@964 | 1129 <filename role="special">hgweb.config</filename> in the same directory as itself. You'll need |
belaran@964 | 1130 to create this file, and make it world-readable. The format of the |
belaran@964 | 1131 file is similar to a Windows <quote>ini</quote> file, as understood by Python's |
belaran@964 | 1132 <literal>ConfigParser</literal> <citation>web:configparser</citation> module. |
belaran@964 | 1133 </para> |
belaran@964 | 1134 |
belaran@964 | 1135 <para>The easiest way to configure <filename role="special">hgwebdir.cgi</filename> is with a |
belaran@964 | 1136 section named <literal>collections</literal>. This will automatically publish |
belaran@964 | 1137 <emphasis>every</emphasis> repository under the directories you name. The section |
belaran@964 | 1138 should look like this: |
belaran@964 | 1139 </para> |
belaran@964 | 1140 <programlisting> |
belaran@964 | 1141 <para> [collections] |
belaran@964 | 1142 /my/root = /my/root |
belaran@964 | 1143 </para> |
belaran@964 | 1144 </programlisting> |
belaran@964 | 1145 <para>Mercurial interprets this by looking at the directory name on the |
belaran@964 | 1146 <emphasis>right</emphasis> hand side of the <quote><literal>=</literal></quote> sign; finding |
belaran@964 | 1147 repositories in that directory hierarchy; and using the text on the |
belaran@964 | 1148 <emphasis>left</emphasis> to strip off matching text from the names it will actually |
belaran@964 | 1149 list in the web interface. The remaining component of a path after |
belaran@964 | 1150 this stripping has occurred is called a <quote>virtual path</quote>. |
belaran@964 | 1151 </para> |
belaran@964 | 1152 |
belaran@964 | 1153 <para>Given the example above, if we have a repository whose local path is |
belaran@964 | 1154 <filename class="directory">/my/root/this/repo</filename>, the CGI script will strip the leading |
belaran@964 | 1155 <filename class="directory">/my/root</filename> from the name, and publish the repository with a |
belaran@964 | 1156 virtual path of <filename class="directory">this/repo</filename>. If the base URL for our CGI |
belaran@964 | 1157 script is <ulink url="http://myhostname/ myuser/hgwebdir.cgi">http://myhostname/ myuser/hgwebdir.cgi</ulink>, the complete |
belaran@964 | 1158 URL for that repository will be |
belaran@964 | 1159 <ulink url="http://myhostname/ myuser/hgwebdir.cgi/this/repo">http://myhostname/ myuser/hgwebdir.cgi/this/repo</ulink>. |
belaran@964 | 1160 </para> |
belaran@964 | 1161 |
belaran@964 | 1162 <para>If we replace <filename class="directory">/my/root</filename> on the left hand side of this example |
belaran@964 | 1163 with <filename class="directory">/my</filename>, then <filename role="special">hgwebdir.cgi</filename> will only strip off |
belaran@964 | 1164 <filename class="directory">/my</filename> from the repository name, and will give us a virtual |
belaran@964 | 1165 path of <filename class="directory">root/this/repo</filename> instead of <filename class="directory">this/repo</filename>. |
belaran@964 | 1166 </para> |
belaran@964 | 1167 |
belaran@964 | 1168 <para>The <filename role="special">hgwebdir.cgi</filename> script will recursively search each |
belaran@964 | 1169 directory listed in the <literal>collections</literal> section of its |
belaran@964 | 1170 configuration file, but it will <literal>not</literal> recurse into the |
belaran@964 | 1171 repositories it finds. |
belaran@964 | 1172 </para> |
belaran@964 | 1173 |
belaran@964 | 1174 <para>The <literal>collections</literal> mechanism makes it easy to publish many |
belaran@964 | 1175 repositories in a <quote>fire and forget</quote> manner. You only need to set up |
belaran@964 | 1176 the CGI script and configuration file one time. Afterwards, you can |
belaran@964 | 1177 publish or unpublish a repository at any time by simply moving it |
belaran@964 | 1178 into, or out of, the directory hierarchy in which you've configured |
belaran@964 | 1179 <filename role="special">hgwebdir.cgi</filename> to look. |
belaran@964 | 1180 </para> |
belaran@964 | 1181 |
belaran@964 | 1182 <sect3> |
belaran@964 | 1183 <title>Explicitly specifying which repositories to publish</title> |
belaran@964 | 1184 |
belaran@964 | 1185 <para>In addition to the <literal>collections</literal> mechanism, the |
belaran@964 | 1186 <filename role="special">hgwebdir.cgi</filename> script allows you to publish a specific list |
belaran@964 | 1187 of repositories. To do so, create a <literal>paths</literal> section, with |
belaran@964 | 1188 contents of the following form. |
belaran@964 | 1189 </para> |
belaran@964 | 1190 <programlisting> |
belaran@964 | 1191 <para> [paths] |
belaran@964 | 1192 repo1 = /my/path/to/some/repo |
belaran@964 | 1193 repo2 = /some/path/to/another |
belaran@964 | 1194 </para> |
belaran@964 | 1195 </programlisting> |
belaran@964 | 1196 <para>In this case, the virtual path (the component that will appear in a |
belaran@964 | 1197 URL) is on the left hand side of each definition, while the path to |
belaran@964 | 1198 the repository is on the right. Notice that there does not need to be |
belaran@964 | 1199 any relationship between the virtual path you choose and the location |
belaran@964 | 1200 of a repository in your filesystem. |
belaran@964 | 1201 </para> |
belaran@964 | 1202 |
belaran@964 | 1203 <para>If you wish, you can use both the <literal>collections</literal> and |
belaran@964 | 1204 <literal>paths</literal> mechanisms simultaneously in a single configuration |
belaran@964 | 1205 file. |
belaran@964 | 1206 </para> |
belaran@964 | 1207 |
belaran@964 | 1208 <note> |
belaran@964 | 1209 <para> If multiple repositories have the same virtual path, |
belaran@964 | 1210 <filename role="special">hgwebdir.cgi</filename> will not report an error. Instead, it will |
belaran@964 | 1211 behave unpredictably. |
belaran@964 | 1212 </para> |
belaran@964 | 1213 </note> |
belaran@964 | 1214 |
belaran@964 | 1215 </sect3> |
belaran@964 | 1216 </sect2> |
belaran@964 | 1217 <sect2> |
belaran@964 | 1218 <title>Downloading source archives</title> |
belaran@964 | 1219 |
belaran@964 | 1220 <para>Mercurial's web interface lets users download an archive of any |
belaran@964 | 1221 revision. This archive will contain a snapshot of the working |
belaran@964 | 1222 directory as of that revision, but it will not contain a copy of the |
belaran@964 | 1223 repository data. |
belaran@964 | 1224 </para> |
belaran@964 | 1225 |
belaran@964 | 1226 <para>By default, this feature is not enabled. To enable it, you'll need to |
belaran@964 | 1227 add an <envar role="rc-item-web">allow_archive</envar> item to the <literal role="rc-web">web</literal> |
belaran@964 | 1228 section of your <filename role="special"> /.hgrc</filename>. |
belaran@964 | 1229 </para> |
belaran@964 | 1230 |
belaran@964 | 1231 </sect2> |
belaran@964 | 1232 <sect2> |
belaran@964 | 1233 <title>Web configuration options</title> |
belaran@964 | 1234 |
belaran@964 | 1235 <para>Mercurial's web interfaces (the <command role="hg-cmd">hg serve</command> command, and the |
belaran@964 | 1236 <filename role="special">hgweb.cgi</filename> and <filename role="special">hgwebdir.cgi</filename> scripts) have a |
belaran@964 | 1237 number of configuration options that you can set. These belong in a |
belaran@964 | 1238 section named <literal role="rc-web">web</literal>. |
belaran@964 | 1239 </para> |
belaran@964 | 1240 <itemizedlist> |
belaran@964 | 1241 <listitem><para><envar role="rc-item-web">allow_archive</envar>: Determines which (if any) archive |
belaran@964 | 1242 download mechanisms Mercurial supports. If you enable this |
belaran@964 | 1243 feature, users of the web interface will be able to download an |
belaran@964 | 1244 archive of whatever revision of a repository they are viewing. |
belaran@964 | 1245 To enable the archive feature, this item must take the form of a |
belaran@964 | 1246 sequence of words drawn from the list below. |
belaran@964 | 1247 </para> |
belaran@964 | 1248 </listitem><itemizedlist> |
belaran@964 | 1249 <listitem><para> \item <literal>bz2</literal>: A <command>tar</command> archive, compressed using |
belaran@964 | 1250 <literal>bzip2</literal> compression. This has the best compression ratio, |
belaran@964 | 1251 but uses the most CPU time on the server. |
belaran@964 | 1252 \item <literal>gz</literal>: A <command>tar</command> archive, compressed using |
belaran@964 | 1253 <literal>gzip</literal> compression. |
belaran@964 | 1254 \item <literal>zip</literal>: A <command>zip</command> archive, compressed using LZW |
belaran@964 | 1255 compression. This format has the worst compression ratio, but is |
belaran@964 | 1256 widely used in the Windows world. |
belaran@964 | 1257 </para> |
belaran@964 | 1258 </listitem></itemizedlist> |
belaran@964 | 1259 <para> If you provide an empty list, or don't have an |
belaran@964 | 1260 <envar role="rc-item-web">allow_archive</envar> entry at all, this feature will be |
belaran@964 | 1261 disabled. Here is an example of how to enable all three supported |
belaran@964 | 1262 formats. |
belaran@964 | 1263 </para> |
belaran@964 | 1264 <programlisting> |
belaran@964 | 1265 <para> [web] |
belaran@964 | 1266 allow_archive = bz2 gz zip |
belaran@964 | 1267 </para> |
belaran@964 | 1268 </programlisting> |
belaran@964 | 1269 <listitem><para><envar role="rc-item-web">allowpull</envar>: Boolean. Determines whether the web |
belaran@964 | 1270 interface allows remote users to <command role="hg-cmd">hg pull</command> and <command role="hg-cmd">hg clone</command> this |
belaran@964 | 1271 repository over HTTP. If set to <literal>no</literal> or <literal>false</literal>, only |
belaran@964 | 1272 the <quote>human-oriented</quote> portion of the web interface is available. |
belaran@964 | 1273 </para> |
belaran@964 | 1274 </listitem> |
belaran@964 | 1275 <listitem><para><envar role="rc-item-web">contact</envar>: String. A free-form (but preferably |
belaran@964 | 1276 brief) string identifying the person or group in charge of the |
belaran@964 | 1277 repository. This often contains the name and email address of a |
belaran@964 | 1278 person or mailing list. It often makes sense to place this entry in |
belaran@964 | 1279 a repository's own <filename role="special">.hg/hgrc</filename> file, but it can make sense |
belaran@964 | 1280 to use in a global <filename role="special"> /.hgrc</filename>\ if every repository has a single |
belaran@964 | 1281 maintainer. |
belaran@964 | 1282 </para> |
belaran@964 | 1283 </listitem> |
belaran@964 | 1284 <listitem><para><envar role="rc-item-web">maxchanges</envar>: Integer. The default maximum number |
belaran@964 | 1285 of changesets to display in a single page of output. |
belaran@964 | 1286 </para> |
belaran@964 | 1287 </listitem> |
belaran@964 | 1288 <listitem><para><envar role="rc-item-web">maxfiles</envar>: Integer. The default maximum number |
belaran@964 | 1289 of modified files to display in a single page of output. |
belaran@964 | 1290 </para> |
belaran@964 | 1291 </listitem> |
belaran@964 | 1292 <listitem><para><envar role="rc-item-web">stripes</envar>: Integer. If the web interface displays |
belaran@964 | 1293 alternating <quote>stripes</quote> to make it easier to visually align rows |
belaran@964 | 1294 when you are looking at a table, this number controls the number of |
belaran@964 | 1295 rows in each stripe. |
belaran@964 | 1296 </para> |
belaran@964 | 1297 </listitem> |
belaran@964 | 1298 <listitem><para><envar role="rc-item-web">style</envar>: Controls the template Mercurial uses to |
belaran@964 | 1299 display the web interface. Mercurial ships with two web templates, |
belaran@964 | 1300 named <literal>default</literal> and <literal>gitweb</literal> (the latter is much more |
belaran@964 | 1301 visually attractive). You can also specify a custom template of |
belaran@964 | 1302 your own; see chapter <xref linkend="chap:template"/> for details. Here, you |
belaran@964 | 1303 can see how to enable the <literal>gitweb</literal> style. |
belaran@964 | 1304 </para> |
belaran@964 | 1305 </listitem><programlisting> |
belaran@964 | 1306 <listitem><para> [web] |
belaran@964 | 1307 style = gitweb |
belaran@964 | 1308 </para> |
belaran@964 | 1309 </listitem></programlisting> |
belaran@964 | 1310 </para> |
belaran@964 | 1311 </listitem> |
belaran@964 | 1312 <listitem><para><envar role="rc-item-web">templates</envar>: Path. The directory in which to search |
belaran@964 | 1313 for template files. By default, Mercurial searches in the directory |
belaran@964 | 1314 in which it was installed. |
belaran@964 | 1315 </para> |
belaran@964 | 1316 </listitem></itemizedlist> |
belaran@964 | 1317 <para>If you are using <filename role="special">hgwebdir.cgi</filename>, you can place a few |
belaran@964 | 1318 configuration items in a <literal role="rc-web">web</literal> section of the |
belaran@964 | 1319 <filename role="special">hgweb.config</filename> file instead of a <filename role="special"> /.hgrc</filename>\ file, for |
belaran@964 | 1320 convenience. These items are <envar role="rc-item-web">motd</envar> and |
belaran@964 | 1321 <envar role="rc-item-web">style</envar>. |
belaran@964 | 1322 </para> |
belaran@964 | 1323 |
belaran@964 | 1324 <sect3> |
belaran@964 | 1325 <title>Options specific to an individual repository</title> |
belaran@964 | 1326 |
belaran@964 | 1327 <para>A few <literal role="rc-web">web</literal> configuration items ought to be placed in a |
belaran@964 | 1328 repository's local <filename role="special">.hg/hgrc</filename>, rather than a user's or |
belaran@964 | 1329 global <filename role="special"> /.hgrc</filename>. |
belaran@964 | 1330 </para> |
belaran@964 | 1331 <itemizedlist> |
belaran@964 | 1332 <listitem><para><envar role="rc-item-web">description</envar>: String. A free-form (but preferably |
belaran@964 | 1333 brief) string that describes the contents or purpose of the |
belaran@964 | 1334 repository. |
belaran@964 | 1335 </para> |
belaran@964 | 1336 </listitem> |
belaran@964 | 1337 <listitem><para><envar role="rc-item-web">name</envar>: String. The name to use for the repository |
belaran@964 | 1338 in the web interface. This overrides the default name, which is the |
belaran@964 | 1339 last component of the repository's path. |
belaran@964 | 1340 </para> |
belaran@964 | 1341 </listitem></itemizedlist> |
belaran@964 | 1342 |
belaran@964 | 1343 </sect3> |
belaran@964 | 1344 <sect3> |
belaran@964 | 1345 <title>Options specific to the <command role="hg-cmd">hg serve</command> command</title> |
belaran@964 | 1346 |
belaran@964 | 1347 <para>Some of the items in the <literal role="rc-web">web</literal> section of a <filename role="special"> /.hgrc</filename>\ file are |
belaran@964 | 1348 only for use with the <command role="hg-cmd">hg serve</command> command. |
belaran@964 | 1349 </para> |
belaran@964 | 1350 <itemizedlist> |
belaran@964 | 1351 <listitem><para><envar role="rc-item-web">accesslog</envar>: Path. The name of a file into which to |
belaran@964 | 1352 write an access log. By default, the <command role="hg-cmd">hg serve</command> command writes |
belaran@964 | 1353 this information to standard output, not to a file. Log entries are |
belaran@964 | 1354 written in the standard <quote>combined</quote> file format used by almost all |
belaran@964 | 1355 web servers. |
belaran@964 | 1356 </para> |
belaran@964 | 1357 </listitem> |
belaran@964 | 1358 <listitem><para><envar role="rc-item-web">address</envar>: String. The local address on which the |
belaran@964 | 1359 server should listen for incoming connections. By default, the |
belaran@964 | 1360 server listens on all addresses. |
belaran@964 | 1361 </para> |
belaran@964 | 1362 </listitem> |
belaran@964 | 1363 <listitem><para><envar role="rc-item-web">errorlog</envar>: Path. The name of a file into which to |
belaran@964 | 1364 write an error log. By default, the <command role="hg-cmd">hg serve</command> command writes this |
belaran@964 | 1365 information to standard error, not to a file. |
belaran@964 | 1366 </para> |
belaran@964 | 1367 </listitem> |
belaran@964 | 1368 <listitem><para><envar role="rc-item-web">ipv6</envar>: Boolean. Whether to use the IPv6 protocol. |
belaran@964 | 1369 By default, IPv6 is not used. |
belaran@964 | 1370 </para> |
belaran@964 | 1371 </listitem> |
belaran@964 | 1372 <listitem><para><envar role="rc-item-web">port</envar>: Integer. The TCP port number on which the |
belaran@964 | 1373 server should listen. The default port number used is 8000. |
belaran@964 | 1374 </para> |
belaran@964 | 1375 </listitem></itemizedlist> |
belaran@964 | 1376 |
belaran@964 | 1377 <para>\subsubsection{Choosing the right <filename role="special"> /.hgrc</filename>\ file to add <literal role="rc-web">web</literal> |
belaran@964 | 1378 items to} |
belaran@964 | 1379 </para> |
belaran@964 | 1380 |
belaran@964 | 1381 <para>It is important to remember that a web server like Apache or |
belaran@964 | 1382 <literal>lighttpd</literal> will run under a user ID that is different to yours. |
belaran@964 | 1383 CGI scripts run by your server, such as <filename role="special">hgweb.cgi</filename>, will |
belaran@964 | 1384 usually also run under that user ID. |
belaran@964 | 1385 </para> |
belaran@964 | 1386 |
belaran@964 | 1387 <para>If you add <literal role="rc-web">web</literal> items to your own personal <filename role="special"> /.hgrc</filename>\ file, CGI |
belaran@964 | 1388 scripts won't read that <filename role="special"> /.hgrc</filename>\ file. Those settings will thus only |
belaran@964 | 1389 affect the behaviour of the <command role="hg-cmd">hg serve</command> command when you run it. To |
belaran@964 | 1390 cause CGI scripts to see your settings, either create a <filename role="special"> /.hgrc</filename>\ file in |
belaran@964 | 1391 the home directory of the user ID that runs your web server, or add |
belaran@964 | 1392 those settings to a system-wide <filename role="special"> /.hgrc</filename>\ file. |
belaran@964 | 1393 </para> |
belaran@964 | 1394 |
belaran@964 | 1395 |
belaran@964 | 1396 </sect3> |
belaran@964 | 1397 </sect2> |
belaran@964 | 1398 </sect1> |
belaran@964 | 1399 </chapter> |
belaran@964 | 1400 |
belaran@964 | 1401 <!-- |
belaran@964 | 1402 local variables: |
belaran@964 | 1403 sgml-parent-document: ("00book.xml" "book" "chapter") |
belaran@964 | 1404 end: |
belaran@964 | 1405 --> |