hgbook

annotate en/collab.tex @ 179:5fc4a45c069f

Continue documentation of collaboration models.
author Bryan O'Sullivan <bos@serpentine.com>
date Fri Mar 30 23:05:28 2007 -0700 (2007-03-30)
parents 7355af913937
children 7b812c428074
rev   line source
bos@159 1 \chapter{Collaborating with other people}
bos@159 2 \label{cha:collab}
bos@159 3
bos@159 4 As a completely decentralised tool, Mercurial doesn't impose any
bos@159 5 policy on how people ought to work with each other. However, if
bos@159 6 you're new to distributed revision control, it helps to have some
bos@159 7 tools and examples in mind when you're thinking about possible
bos@159 8 workflow models.
bos@159 9
bos@159 10 \section{Collaboration models}
bos@159 11
bos@159 12 With a suitably flexible tool, making decisions about workflow is much
bos@159 13 more of a social engineering challenge than a technical one.
bos@159 14 Mercurial imposes few limitations on how you can structure the flow of
bos@159 15 work in a project, so it's up to you and your group to set up and live
bos@159 16 with a model that matches your own particular needs.
bos@159 17
bos@159 18 \subsection{Factors to keep in mind}
bos@159 19
bos@159 20 The most important aspect of any model that you must keep in mind is
bos@159 21 how well it matches the needs and capabilities of the people who will
bos@159 22 be using it. This might seem self-evident; even so, you still can't
bos@159 23 afford to forget it for a moment.
bos@159 24
bos@159 25 I once put together a workflow model that seemed to make perfect sense
bos@159 26 to me, but that caused a considerable amount of consternation and
bos@159 27 strife within my development team. In spite of my attempts to explain
bos@159 28 why we needed a complex set of branches, and how changes ought to flow
bos@159 29 between them, a few team members revolted. Even though they were
bos@159 30 smart people, they didn't want to pay attention to the constraints we
bos@159 31 were operating under, or face the consequences of those constraints in
bos@159 32 the details of the model that I was advocating.
bos@159 33
bos@159 34 Don't sweep foreseeable social or technical problems under the rug.
bos@159 35 Whatever scheme you put into effect, you should plan for mistakes and
bos@159 36 problem scenarios. Consider adding automated machinery to prevent, or
bos@159 37 quickly recover from, trouble that you can anticipate. As an example,
bos@159 38 if you intend to have a branch with not-for-release changes in it,
bos@159 39 you'd do well to think early about the possibility that someone might
bos@159 40 accidentally merge those changes into a release branch. You could
bos@159 41 avoid this particular problem by writing a hook that prevents changes
bos@159 42 from being merged from an inappropriate branch.
bos@159 43
bos@159 44 \subsection{Informal anarchy}
bos@159 45
bos@159 46 I wouldn't suggest an ``anything goes'' approach as something
bos@159 47 sustainable, but it's a model that's easy to grasp, and it works
bos@159 48 perfectly well in a few unusual situations.
bos@159 49
bos@159 50 As one example, many projects have a loose-knit group of collaborators
bos@159 51 who rarely physically meet each other. Some groups like to overcome
bos@159 52 the isolation of working at a distance by organising occasional
bos@159 53 ``sprints''. In a sprint, a number of people get together in a single
bos@159 54 location (a company's conference room, a hotel meeting room, that kind
bos@159 55 of place) and spend several days more or less locked in there, hacking
bos@159 56 intensely on a handful of projects.
bos@159 57
bos@159 58 A sprint is the perfect place to use the \hgcmd{serve} command, since
bos@159 59 \hgcmd{serve} does not requires any fancy server infrastructure. You
bos@159 60 can get started with \hgcmd{serve} in moments, by reading
bos@159 61 section~\ref{sec:collab:serve} below. Then simply tell the person
bos@159 62 next to you that you're running a server, send the URL to them in an
bos@159 63 instant message, and you immediately have a quick-turnaround way to
bos@159 64 work together. They can type your URL into their web browser and
bos@159 65 quickly review your changes; or they can pull a bugfix from you and
bos@159 66 verify it; or they can clone a branch containing a new feature and try
bos@159 67 it out.
bos@159 68
bos@159 69 The charm, and the problem, with doing things in an ad hoc fashion
bos@159 70 like this is that only people who know about your changes, and where
bos@159 71 they are, can see them. Such an informal approach simply doesn't
bos@159 72 scale beyond a handful people, because each individual needs to know
bos@159 73 about $n$ different repositories to pull from.
bos@159 74
bos@159 75 \subsection{A single central repository}
bos@159 76
bos@179 77 For smaller projects migrating from a centralised revision control
bos@159 78 tool, perhaps the easiest way to get started is to have changes flow
bos@159 79 through a single shared central repository. This is also the
bos@159 80 most common ``building block'' for more ambitious workflow schemes.
bos@159 81
bos@159 82 Contributors start by cloning a copy of this repository. They can
bos@159 83 pull changes from it whenever they need to, and some (perhaps all)
bos@159 84 developers have permission to push a change back when they're ready
bos@159 85 for other people to see it.
bos@159 86
bos@179 87 Under this model, it can still often make sense for people to pull
bos@159 88 changes directly from each other, without going through the central
bos@159 89 repository. Consider a case in which I have a tentative bug fix, but
bos@159 90 I am worried that if I were to publish it to the central repository,
bos@159 91 it might subsequently break everyone else's trees as they pull it. To
bos@159 92 reduce the potential for damage, I can ask you to clone my repository
bos@159 93 into a temporary repository of your own and test it. This lets us put
bos@159 94 off publishing the potentially unsafe change until it has had a little
bos@159 95 testing.
bos@159 96
bos@159 97 In this kind of scenario, people usually use the \command{ssh}
bos@159 98 protocol to securely push changes to the central repository, as
bos@159 99 documented in section~\ref{sec:collab:ssh}. It's also usual to
bos@159 100 publish a read-only copy of the repository over HTTP using CGI, as in
bos@159 101 section~\ref{sec:collab:cgi}. Publishing over HTTP satisfies the
bos@159 102 needs of people who don't have push access, and those who want to use
bos@159 103 web browsers to browse the repository's history.
bos@159 104
bos@179 105 \subsection{Working with multiple branches}
bos@179 106
bos@179 107 Projects of any significant size naturally tend to make progress on
bos@179 108 several fronts simultaneously. In the case of software, it's common
bos@179 109 for a project to go through periodic official releases. A release
bos@179 110 might then go into ``maintenance mode'' for a while after its first
bos@179 111 publication; maintenance releases tend to contain only bug fixes, not
bos@179 112 new features. In parallel with these maintenance releases, one or
bos@179 113 more future releases may be under development. People normally use
bos@179 114 the word ``branch'' to refer to one of these many slightly different
bos@179 115 directions in which development is proceeding.
bos@179 116
bos@179 117 Mercurial is particularly well suited to managing a number of
bos@179 118 simultaneous, but not identical, branches. Each ``development
bos@179 119 direction'' can live in its own central repository, and you can merge
bos@179 120 changes from one to another as the need arises. Because repositories
bos@179 121 are independent of each other, unstable changes in a development
bos@179 122 branch will never affect a stable branch unless someone explicitly
bos@179 123 merges those changes in.
bos@179 124
bos@179 125 Here's an example of how this can work in practice. Let's say you
bos@179 126 have one ``main branch'' on a central server.
bos@179 127 \interaction{branching.init}
bos@179 128 People clone it, make changes locally, test them, and push them back.
bos@179 129
bos@179 130 Once the main branch reaches a release milestone, you can use the
bos@179 131 \hgcmd{tag} command to give a permanent name to the milestone
bos@179 132 revision.
bos@179 133 \interaction{branching.tag}
bos@179 134 Let's say some ongoing development occurs on the main branch.
bos@179 135 \interaction{branching.main}
bos@179 136 Using the tag that was recorded at the milestone, people who clone
bos@179 137 that repository at any time in the future can use \hgcmd{update} to
bos@179 138 get a copy of the working directory exactly as it was when that tagged
bos@179 139 revision was committed.
bos@179 140 \interaction{branching.update}
bos@179 141
bos@179 142 In addition, immediately after the main branch is tagged, someone can
bos@179 143 then clone the main branch on the server to a new ``stable'' branch,
bos@179 144 also on the server.
bos@179 145 \interaction{branching.clone}
bos@179 146
bos@179 147 Someone who needs to make a change to the stable branch can then clone
bos@179 148 \emph{that} repository, make their changes, commit, and push their
bos@179 149 changes back there.
bos@179 150 \interaction{branching.stable}
bos@179 151 Because Mercurial repositories are independent, and Mercurial doesn't
bos@179 152 move changes around automatically, the stable and main branches are
bos@179 153 \emph{isolated} from each other. The changes that you made on the
bos@179 154 main branch don't ``leak'' to the stable branch, and vice versa.
bos@179 155
bos@179 156 You'll often want all of your bugfixes on the stable branch to show up
bos@179 157 on the main branch, too. Rather than rewrite a bugfix on the main
bos@179 158 branch, you can simply pull and merge changes from the stable to the
bos@179 159 main branch, and Mercurial will bring those bugfixes in for you.
bos@179 160 \interaction{branching.merge}
bos@179 161 The main branch will still contain changes that are not on the stable
bos@179 162 branch, but it will also contain all of the bugfixes from the stable
bos@179 163 branch. The stable branch remains unaffected by these changes.
bos@179 164
bos@179 165 \subsection{Feature branches}
bos@179 166
bos@179 167 For larger projects, an effective way to manage change is to break up
bos@179 168 a team into smaller groups. Each group has a shared branch of its
bos@179 169 own, cloned from a single ``master'' branch used by the entire
bos@179 170 project. People working on an individual branch are typically quite
bos@179 171 isolated from developments on other branches.
bos@179 172
bos@179 173 \begin{figure}[ht]
bos@179 174 \centering
bos@179 175 \grafix{feature-branches}
bos@179 176 \caption{Feature branches}
bos@179 177 \label{fig:collab:feature-branches}
bos@179 178 \end{figure}
bos@179 179
bos@179 180 When a particular feature is deemed to be in suitable shape, someone
bos@179 181 on that feature team pulls and merges from the master branch into the
bos@179 182 feature branch, then pushes back up to the master branch.
bos@179 183
bos@179 184 \subsection{The release train}
bos@179 185
bos@179 186 Some projects are organised on a ``train'' basis: a release is
bos@179 187 scheduled to happen every few months, and whatever features are ready
bos@179 188 when the ``train'' is ready to leave are allowed in.
bos@179 189
bos@179 190 This model resembles working with feature branches. The difference is
bos@179 191 that when a feature branch misses a train, someone on the feature team
bos@179 192 pulls and merges the changes that went out on that train release, and
bos@179 193 the team continues its work on top of that release so that their
bos@179 194 feature can make the next release.
bos@179 195
bos@159 196 \subsection{The Linux kernel model}
bos@159 197
bos@159 198 The development of the Linux kernel has a shallow hierarchical
bos@159 199 structure, surrounded by a cloud of apparent chaos. Because most
bos@159 200 Linux developers use \command{git}, a distributed revision control
bos@159 201 tool with capabilities similar to Mercurial, it's useful to describe
bos@159 202 the way work flows in that environment; if you like the ideas, the
bos@159 203 approach translates well across tools.
bos@159 204
bos@159 205 At the center of the community sits Linus Torvalds, the creator of
bos@159 206 Linux. He publishes a single source repository that is considered the
bos@159 207 ``authoritative'' current tree by the entire developer community.
bos@159 208 Anyone can clone Linus's tree, but he is very choosy about whose trees
bos@159 209 he pulls from.
bos@159 210
bos@159 211 Linus has a number of ``trusted lieutenants''. As a general rule, he
bos@159 212 pulls whatever changes they publish, in most cases without even
bos@159 213 reviewing those changes. Some of those lieutenants are generally
bos@159 214 agreed to be ``maintainers'', responsible for specific subsystems
bos@159 215 within the kernel. If a random kernel hacker wants to make a change
bos@159 216 to a subsystem that they want to end up in Linus's tree, they must
bos@159 217 find out who the subsystem's maintainer is, and ask that maintainer to
bos@159 218 take their change. If the maintainer reviews their changes and agrees
bos@159 219 to take them, they'll pass them along to Linus in due course.
bos@159 220
bos@159 221 Individual lieutenants have their own approaches to reviewing,
bos@159 222 accepting, and publishing changes; and for deciding when to feed them
bos@159 223 to Linus. In addition, there are several well known branches that
bos@159 224 people use for different purposes. For example, a few people maintain
bos@159 225 ``stable'' repositories of older versions of the kernel, to which they
bos@159 226 apply critical fixes as needed.
bos@159 227
bos@159 228 This model has two notable features. The first is that it's ``pull
bos@159 229 only''. You have to ask, convince, or beg another developer to take a
bos@159 230 change from you, because there are no shared trees, and there's no way
bos@159 231 to push changes into a tree that someone else controls.
bos@159 232
bos@159 233 The second is that it's based on reputation and acclaim. If you're an
bos@159 234 unknown, Linus will probably ignore changes from you without even
bos@159 235 responding. But a subsystem maintainer will probably review them, and
bos@159 236 will likely take them if they pass their criteria for suitability.
bos@159 237 The more ``good'' changes you contribute to a maintainer, the more
bos@159 238 likely they are to trust your judgment and accept your changes. If
bos@159 239 you're well-known and maintain a long-lived branch for something Linus
bos@159 240 hasn't yet accepted, people with similar interests may pull your
bos@159 241 changes regularly to keep up with your work.
bos@159 242
bos@159 243 Reputation and acclaim don't necessarily cross subsystem or ``people''
bos@159 244 boundaries. If you're a respected but specialised storage hacker, and
bos@159 245 you try to fix a networking bug, that change will receive a level of
bos@159 246 scrutiny from a network maintainer comparable to a change from a
bos@159 247 complete stranger.
bos@159 248
bos@159 249 To people who come from more orderly project backgrounds, the
bos@159 250 comparatively chaotic Linux kernel development process often seems
bos@159 251 completely insane. It's subject to the whims of individuals; people
bos@159 252 make sweeping changes whenever they deem it appropriate; and the pace
bos@159 253 of development is astounding. And yet Linux is a highly successful,
bos@159 254 well-regarded piece of software.
bos@159 255
bos@159 256 \section{The technical side of sharing}
bos@159 257
bos@159 258 \subsection{Informal sharing with \hgcmd{serve}}
bos@159 259 \label{sec:collab:serve}
bos@159 260
bos@159 261 Mercurial's \hgcmd{serve} command is wonderfully suited to small,
bos@159 262 tight-knit, and fast-paced group environments. It also provides a
bos@159 263 great way to get a feel for using Mercurial commands over a network.
bos@159 264
bos@159 265 Run \hgcmd{serve} inside a repository, and in under a second it will
bos@159 266 bring up a specialised HTTP server; this will accept connections from
bos@159 267 any client, and serve up data for that repository until you terminate
bos@159 268 it. Anyone who knows the URL of the server you just started, and can
bos@159 269 talk to your computer over the network, can then use a web browser or
bos@159 270 Mercurial to read data from that repository. A URL for a
bos@159 271 \hgcmd{serve} instance running on a laptop is likely to look something
bos@159 272 like \Verb|http://my-laptop.local:8000/|.
bos@159 273
bos@159 274 The \hgcmd{serve} command is \emph{not} a general-purpose web server.
bos@159 275 It can do only two things:
bos@159 276 \begin{itemize}
bos@159 277 \item Allow people to browse the history of the repository it's
bos@159 278 serving, from their normal web browsers.
bos@159 279 \item Speak Mercurial's wire protocol, so that people can
bos@159 280 \hgcmd{clone} or \hgcmd{pull} changes from that repository.
bos@159 281 \end{itemize}
bos@159 282 In particular, \hgcmd{serve} won't allow remote users to \emph{modify}
bos@159 283 your repository. It's intended for read-only use.
bos@159 284
bos@159 285 If you're getting started with Mercurial, there's nothing to prevent
bos@159 286 you from using \hgcmd{serve} to serve up a repository on your own
bos@159 287 computer, then use commands like \hgcmd{clone}, \hgcmd{incoming}, and
bos@159 288 so on to talk to that server as if the repository was hosted remotely.
bos@159 289 This can help you to quickly get acquainted with using commands on
bos@159 290 network-hosted repositories.
bos@159 291
bos@159 292 \subsubsection{A few things to keep in mind}
bos@159 293
bos@159 294 Because it provides unauthenticated read access to all clients, you
bos@159 295 should only use \hgcmd{serve} in an environment where you either don't
bos@159 296 care, or have complete control over, who can access your network and
bos@159 297 pull data from your repository.
bos@159 298
bos@159 299 The \hgcmd{serve} command knows nothing about any firewall software
bos@159 300 you might have installed on your system or network. It cannot detect
bos@159 301 or control your firewall software. If other people are unable to talk
bos@159 302 to a running \hgcmd{serve} instance, the second thing you should do
bos@159 303 (\emph{after} you make sure that they're using the correct URL) is
bos@159 304 check your firewall configuration.
bos@159 305
bos@159 306 By default, \hgcmd{serve} listens for incoming connections on
bos@159 307 port~8000. If another process is already listening on the port you
bos@159 308 want to use, you can specify a different port to listen on using the
bos@159 309 \hgopt{serve}{-p} option.
bos@159 310
bos@159 311 Normally, when \hgcmd{serve} starts, it prints no output, which can be
bos@159 312 a bit unnerving. If you'd like to confirm that it is indeed running
bos@159 313 correctly, and find out what URL you should send to your
bos@159 314 collaborators, start it with the \hggopt{-v} option.
bos@159 315
bos@159 316 \subsection{Using \command{ssh} as a tunnel}
bos@159 317 \label{sec:collab:ssh}
bos@159 318
bos@159 319 \subsection{Serving HTTP with a CGI script}
bos@159 320 \label{sec:collab:cgi}
bos@159 321
bos@159 322
bos@159 323
bos@159 324 %%% Local Variables:
bos@159 325 %%% mode: latex
bos@159 326 %%% TeX-master: "00book"
bos@159 327 %%% End: