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 --> |