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