hgbook

annotate fr/ch08-branch.xml @ 980:c40dac4f63d8

merge with Jean Marie Clément
author Romain PELISSE <belaran@gmail.com>
date Fri Sep 04 18:55:53 2009 +0200 (2009-09-04)
parents
children 6f8c48362758
rev   line source
belaran@964 1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
belaran@964 2
belaran@964 3 <chapter>
belaran@964 4 <title>Managing releases and branchy development</title>
belaran@964 5 <para>\label{chap:branch}</para>
belaran@964 6
belaran@964 7 <para>Mercurial provides several mechanisms for you to manage a project that
belaran@964 8 is making progress on multiple fronts at once. To understand these
belaran@964 9 mechanisms, let's first take a brief look at a fairly normal software
belaran@964 10 project structure.</para>
belaran@964 11
belaran@964 12 <para>Many software projects issue periodic <quote>major</quote> releases that contain
belaran@964 13 substantial new features. In parallel, they may issue <quote>minor</quote>
belaran@964 14 releases. These are usually identical to the major releases off which
belaran@964 15 they're based, but with a few bugs fixed.</para>
belaran@964 16
belaran@964 17 <para>In this chapter, we'll start by talking about how to keep records of
belaran@964 18 project milestones such as releases. We'll then continue on to talk
belaran@964 19 about the flow of work between different phases of a project, and how
belaran@964 20 Mercurial can help you to isolate and manage this work.</para>
belaran@964 21
belaran@964 22 <sect1>
belaran@964 23 <title>Giving a persistent name to a revision</title>
belaran@964 24
belaran@964 25 <para>Once you decide that you'd like to call a particular revision a
belaran@964 26 <quote>release</quote>, it's a good idea to record the identity of that revision.
belaran@964 27 This will let you reproduce that release at a later date, for whatever
belaran@964 28 purpose you might need at the time (reproducing a bug, porting to a
belaran@964 29 new platform, etc).
belaran@964 30 <!-- &interaction.tag.init; --></para>
belaran@964 31
belaran@964 32 <para>Mercurial lets you give a permanent name to any revision using the
belaran@964 33 <command role="hg-cmd">hg tag</command> command. Not surprisingly, these names are called
belaran@964 34 <quote>tags</quote>.
belaran@964 35 <!-- &interaction.tag.tag; --></para>
belaran@964 36
belaran@964 37 <para>A tag is nothing more than a <quote>symbolic name</quote> for a revision. Tags
belaran@964 38 exist purely for your convenience, so that you have a handy permanent
belaran@964 39 way to refer to a revision; Mercurial doesn't interpret the tag names
belaran@964 40 you use in any way. Neither does Mercurial place any restrictions on
belaran@964 41 the name of a tag, beyond a few that are necessary to ensure that a
belaran@964 42 tag can be parsed unambiguously. A tag name cannot contain any of the
belaran@964 43 following characters:</para>
belaran@964 44 <itemizedlist>
belaran@964 45 <listitem><para>Colon (ASCII 58, <quote><literal>:</literal></quote>)</para>
belaran@964 46 </listitem>
belaran@964 47 <listitem><para>Carriage return (ASCII 13, <quote><literal>\r</literal></quote>)
belaran@964 48 </para>
belaran@964 49 </listitem>
belaran@964 50 <listitem><para>Newline (ASCII 10, <quote><literal>\n</literal></quote>)
belaran@964 51 </para>
belaran@964 52 </listitem></itemizedlist>
belaran@964 53
belaran@964 54 <para>You can use the <command role="hg-cmd">hg tags</command> command to display the tags present in
belaran@964 55 your repository. In the output, each tagged revision is identified
belaran@964 56 first by its name, then by revision number, and finally by the unique
belaran@964 57 hash of the revision.
belaran@964 58 <!-- &interaction.tag.tags; -->
belaran@964 59 Notice that <literal>tip</literal> is listed in the output of <command role="hg-cmd">hg tags</command>. The
belaran@964 60 <literal>tip</literal> tag is a special <quote>floating</quote> tag, which always
belaran@964 61 identifies the newest revision in the repository.
belaran@964 62 </para>
belaran@964 63
belaran@964 64 <para>In the output of the <command role="hg-cmd">hg tags</command> command, tags are listed in reverse
belaran@964 65 order, by revision number. This usually means that recent tags are
belaran@964 66 listed before older tags. It also means that <literal>tip</literal> is always
belaran@964 67 going to be the first tag listed in the output of <command role="hg-cmd">hg tags</command>.
belaran@964 68 </para>
belaran@964 69
belaran@964 70 <para>When you run <command role="hg-cmd">hg log</command>, if it displays a revision that has tags
belaran@964 71 associated with it, it will print those tags.
belaran@964 72 <!-- &interaction.tag.log; -->
belaran@964 73 </para>
belaran@964 74
belaran@964 75 <para>Any time you need to provide a revision ID to a Mercurial command, the
belaran@964 76 command will accept a tag name in its place. Internally, Mercurial
belaran@964 77 will translate your tag name into the corresponding revision ID, then
belaran@964 78 use that.
belaran@964 79 <!-- &interaction.tag.log.v1.0; -->
belaran@964 80 </para>
belaran@964 81
belaran@964 82 <para>There's no limit on the number of tags you can have in a repository,
belaran@964 83 or on the number of tags that a single revision can have. As a
belaran@964 84 practical matter, it's not a great idea to have <quote>too many</quote> (a number
belaran@964 85 which will vary from project to project), simply because tags are
belaran@964 86 supposed to help you to find revisions. If you have lots of tags, the
belaran@964 87 ease of using them to identify revisions diminishes rapidly.
belaran@964 88 </para>
belaran@964 89
belaran@964 90 <para>For example, if your project has milestones as frequent as every few
belaran@964 91 days, it's perfectly reasonable to tag each one of those. But if you
belaran@964 92 have a continuous build system that makes sure every revision can be
belaran@964 93 built cleanly, you'd be introducing a lot of noise if you were to tag
belaran@964 94 every clean build. Instead, you could tag failed builds (on the
belaran@964 95 assumption that they're rare!), or simply not use tags to track
belaran@964 96 buildability.
belaran@964 97 </para>
belaran@964 98
belaran@964 99 <para>If you want to remove a tag that you no longer want, use
belaran@964 100 <command role="hg-cmd">hg tag --remove</command>.
belaran@964 101 <!-- &interaction.tag.remove; -->
belaran@964 102 You can also modify a tag at any time, so that it identifies a
belaran@964 103 different revision, by simply issuing a new <command role="hg-cmd">hg tag</command> command.
belaran@964 104 You'll have to use the <option role="hg-opt-tag">-f</option> option to tell Mercurial that
belaran@964 105 you <emphasis>really</emphasis> want to update the tag.
belaran@964 106 <!-- &interaction.tag.replace; -->
belaran@964 107 There will still be a permanent record of the previous identity of the
belaran@964 108 tag, but Mercurial will no longer use it. There's thus no penalty to
belaran@964 109 tagging the wrong revision; all you have to do is turn around and tag
belaran@964 110 the correct revision once you discover your error.
belaran@964 111 </para>
belaran@964 112
belaran@964 113 <para>Mercurial stores tags in a normal revision-controlled file in your
belaran@964 114 repository. If you've created any tags, you'll find them in a file
belaran@964 115 named <filename role="special">.hgtags</filename>. When you run the <command role="hg-cmd">hg tag</command> command,
belaran@964 116 Mercurial modifies this file, then automatically commits the change to
belaran@964 117 it. This means that every time you run <command role="hg-cmd">hg tag</command>, you'll see a
belaran@964 118 corresponding changeset in the output of <command role="hg-cmd">hg log</command>.
belaran@964 119 <!-- &interaction.tag.tip; -->
belaran@964 120 </para>
belaran@964 121
belaran@964 122 <sect2>
belaran@964 123 <title>Handling tag conflicts during a merge</title>
belaran@964 124
belaran@964 125 <para>You won't often need to care about the <filename role="special">.hgtags</filename> file, but
belaran@964 126 it sometimes makes its presence known during a merge. The format of
belaran@964 127 the file is simple: it consists of a series of lines. Each line
belaran@964 128 starts with a changeset hash, followed by a space, followed by the
belaran@964 129 name of a tag.
belaran@964 130 </para>
belaran@964 131
belaran@964 132 <para>If you're resolving a conflict in the <filename role="special">.hgtags</filename> file during
belaran@964 133 a merge, there's one twist to modifying the <filename role="special">.hgtags</filename> file:
belaran@964 134 when Mercurial is parsing the tags in a repository, it <emphasis>never</emphasis>
belaran@964 135 reads the working copy of the <filename role="special">.hgtags</filename> file. Instead, it
belaran@964 136 reads the <emphasis>most recently committed</emphasis> revision of the file.
belaran@964 137 </para>
belaran@964 138
belaran@964 139 <para>An unfortunate consequence of this design is that you can't actually
belaran@964 140 verify that your merged <filename role="special">.hgtags</filename> file is correct until
belaran@964 141 <emphasis>after</emphasis> you've committed a change. So if you find yourself
belaran@964 142 resolving a conflict on <filename role="special">.hgtags</filename> during a merge, be sure to
belaran@964 143 run <command role="hg-cmd">hg tags</command> after you commit. If it finds an error in the
belaran@964 144 <filename role="special">.hgtags</filename> file, it will report the location of the error,
belaran@964 145 which you can then fix and commit. You should then run <command role="hg-cmd">hg tags</command>
belaran@964 146 again, just to be sure that your fix is correct.
belaran@964 147 </para>
belaran@964 148
belaran@964 149 </sect2>
belaran@964 150 <sect2>
belaran@964 151 <title>Tags and cloning</title>
belaran@964 152
belaran@964 153 <para>You may have noticed that the <command role="hg-cmd">hg clone</command> command has a
belaran@964 154 <option role="hg-opt-clone">-r</option> option that lets you clone an exact copy of the
belaran@964 155 repository as of a particular changeset. The new clone will not
belaran@964 156 contain any project history that comes after the revision you
belaran@964 157 specified. This has an interaction with tags that can surprise the
belaran@964 158 unwary.
belaran@964 159 </para>
belaran@964 160
belaran@964 161 <para>Recall that a tag is stored as a revision to the <filename role="special">.hgtags</filename>
belaran@964 162 file, so that when you create a tag, the changeset in which it's
belaran@964 163 recorded necessarily refers to an older changeset. When you run
belaran@964 164 <command role="hg-cmd">hg clone -r foo</command> to clone a repository as of tag
belaran@964 165 <literal>foo</literal>, the new clone \emph{will not contain the history that
belaran@964 166 created the tag} that you used to clone the repository. The result
belaran@964 167 is that you'll get exactly the right subset of the project's history
belaran@964 168 in the new repository, but <emphasis>not</emphasis> the tag you might have expected.
belaran@964 169 </para>
belaran@964 170
belaran@964 171 </sect2>
belaran@964 172 <sect2>
belaran@964 173 <title>When permanent tags are too much</title>
belaran@964 174
belaran@964 175 <para>Since Mercurial's tags are revision controlled and carried around with
belaran@964 176 a project's history, everyone you work with will see the tags you
belaran@964 177 create. But giving names to revisions has uses beyond simply noting
belaran@964 178 that revision <literal>4237e45506ee</literal> is really <literal>v2.0.2</literal>. If
belaran@964 179 you're trying to track down a subtle bug, you might want a tag to
belaran@964 180 remind you of something like <quote>Anne saw the symptoms with this
belaran@964 181 revision</quote>.
belaran@964 182 </para>
belaran@964 183
belaran@964 184 <para>For cases like this, what you might want to use are <emphasis>local</emphasis> tags.
belaran@964 185 You can create a local tag with the <option role="hg-opt-tag">-l</option> option to the
belaran@964 186 <command role="hg-cmd">hg tag</command> command. This will store the tag in a file called
belaran@964 187 <filename role="special">.hg/localtags</filename>. Unlike <filename role="special">.hgtags</filename>,
belaran@964 188 <filename role="special">.hg/localtags</filename> is not revision controlled. Any tags you
belaran@964 189 create using <option role="hg-opt-tag">-l</option> remain strictly local to the repository
belaran@964 190 you're currently working in.
belaran@964 191 </para>
belaran@964 192
belaran@964 193 </sect2>
belaran@964 194 </sect1>
belaran@964 195 <sect1>
belaran@964 196 <title>The flow of changes&emdash;big picture vs. little</title>
belaran@964 197
belaran@964 198 <para>To return to the outline I sketched at the beginning of a chapter,
belaran@964 199 let's think about a project that has multiple concurrent pieces of
belaran@964 200 work under development at once.
belaran@964 201 </para>
belaran@964 202
belaran@964 203 <para>There might be a push for a new <quote>main</quote> release; a new minor bugfix
belaran@964 204 release to the last main release; and an unexpected <quote>hot fix</quote> to an
belaran@964 205 old release that is now in maintenance mode.
belaran@964 206 </para>
belaran@964 207
belaran@964 208 <para>The usual way people refer to these different concurrent directions of
belaran@964 209 development is as <quote>branches</quote>. However, we've already seen numerous
belaran@964 210 times that Mercurial treats <emphasis>all of history</emphasis> as a series of
belaran@964 211 branches and merges. Really, what we have here is two ideas that are
belaran@964 212 peripherally related, but which happen to share a name.
belaran@964 213 </para>
belaran@964 214 <itemizedlist>
belaran@964 215 <listitem><para><quote>Big picture</quote> branches represent the sweep of a project's
belaran@964 216 evolution; people give them names, and talk about them in
belaran@964 217 conversation.
belaran@964 218 </para>
belaran@964 219 </listitem>
belaran@964 220 <listitem><para><quote>Little picture</quote> branches are artefacts of the day-to-day
belaran@964 221 activity of developing and merging changes. They expose the
belaran@964 222 narrative of how the code was developed.
belaran@964 223 </para>
belaran@964 224 </listitem></itemizedlist>
belaran@964 225
belaran@964 226 </sect1>
belaran@964 227 <sect1>
belaran@964 228 <title>Managing big-picture branches in repositories</title>
belaran@964 229
belaran@964 230 <para>The easiest way to isolate a <quote>big picture</quote> branch in Mercurial is in
belaran@964 231 a dedicated repository. If you have an existing shared
belaran@964 232 repository&emdash;let's call it <literal>myproject</literal>&emdash;that reaches a <quote>1.0</quote>
belaran@964 233 milestone, you can start to prepare for future maintenance releases on
belaran@964 234 top of version 1.0 by tagging the revision from which you prepared
belaran@964 235 the 1.0 release.
belaran@964 236 <!-- &interaction.branch-repo.tag; -->
belaran@964 237 You can then clone a new shared <literal>myproject-1.0.1</literal> repository as
belaran@964 238 of that tag.
belaran@964 239 <!-- &interaction.branch-repo.clone; -->
belaran@964 240 </para>
belaran@964 241
belaran@964 242 <para>Afterwards, if someone needs to work on a bug fix that ought to go
belaran@964 243 into an upcoming 1.0.1 minor release, they clone the
belaran@964 244 <literal>myproject-1.0.1</literal> repository, make their changes, and push them
belaran@964 245 back.
belaran@964 246 <!-- &interaction.branch-repo.bugfix; -->
belaran@964 247 Meanwhile, development for the next major release can continue,
belaran@964 248 isolated and unabated, in the <literal>myproject</literal> repository.
belaran@964 249 <!-- &interaction.branch-repo.new; -->
belaran@964 250 </para>
belaran@964 251
belaran@964 252 </sect1>
belaran@964 253 <sect1>
belaran@964 254 <title>Don't repeat yourself: merging across branches</title>
belaran@964 255
belaran@964 256 <para>In many cases, if you have a bug to fix on a maintenance branch, the
belaran@964 257 chances are good that the bug exists on your project's main branch
belaran@964 258 (and possibly other maintenance branches, too). It's a rare developer
belaran@964 259 who wants to fix the same bug multiple times, so let's look at a few
belaran@964 260 ways that Mercurial can help you to manage these bugfixes without
belaran@964 261 duplicating your work.
belaran@964 262 </para>
belaran@964 263
belaran@964 264 <para>In the simplest instance, all you need to do is pull changes from your
belaran@964 265 maintenance branch into your local clone of the target branch.
belaran@964 266 <!-- &interaction.branch-repo.pull; -->
belaran@964 267 You'll then need to merge the heads of the two branches, and push back
belaran@964 268 to the main branch.
belaran@964 269 <!-- &interaction.branch-repo.merge; -->
belaran@964 270 </para>
belaran@964 271
belaran@964 272 </sect1>
belaran@964 273 <sect1>
belaran@964 274 <title>Naming branches within one repository</title>
belaran@964 275
belaran@964 276 <para>In most instances, isolating branches in repositories is the right
belaran@964 277 approach. Its simplicity makes it easy to understand; and so it's
belaran@964 278 hard to make mistakes. There's a one-to-one relationship between
belaran@964 279 branches you're working in and directories on your system. This lets
belaran@964 280 you use normal (non-Mercurial-aware) tools to work on files within a
belaran@964 281 branch/repository.
belaran@964 282 </para>
belaran@964 283
belaran@964 284 <para>If you're more in the <quote>power user</quote> category (<emphasis>and</emphasis> your
belaran@964 285 collaborators are too), there is an alternative way of handling
belaran@964 286 branches that you can consider. I've already mentioned the
belaran@964 287 human-level distinction between <quote>small picture</quote> and <quote>big picture</quote>
belaran@964 288 branches. While Mercurial works with multiple <quote>small picture</quote>
belaran@964 289 branches in a repository all the time (for example after you pull
belaran@964 290 changes in, but before you merge them), it can <emphasis>also</emphasis> work with
belaran@964 291 multiple <quote>big picture</quote> branches.
belaran@964 292 </para>
belaran@964 293
belaran@964 294 <para>The key to working this way is that Mercurial lets you assign a
belaran@964 295 persistent <emphasis>name</emphasis> to a branch. There always exists a branch
belaran@964 296 named <literal>default</literal>. Even before you start naming branches
belaran@964 297 yourself, you can find traces of the <literal>default</literal> branch if you
belaran@964 298 look for them.
belaran@964 299 </para>
belaran@964 300
belaran@964 301 <para>As an example, when you run the <command role="hg-cmd">hg commit</command> command, and it pops up
belaran@964 302 your editor so that you can enter a commit message, look for a line
belaran@964 303 that contains the text <quote><literal>HG: branch default</literal></quote> at the bottom.
belaran@964 304 This is telling you that your commit will occur on the branch named
belaran@964 305 <literal>default</literal>.
belaran@964 306 </para>
belaran@964 307
belaran@964 308 <para>To start working with named branches, use the <command role="hg-cmd">hg branches</command>
belaran@964 309 command. This command lists the named branches already present in
belaran@964 310 your repository, telling you which changeset is the tip of each.
belaran@964 311 <!-- &interaction.branch-named.branches; -->
belaran@964 312 Since you haven't created any named branches yet, the only one that
belaran@964 313 exists is <literal>default</literal>.
belaran@964 314 </para>
belaran@964 315
belaran@964 316 <para>To find out what the <quote>current</quote> branch is, run the <command role="hg-cmd">hg branch</command>
belaran@964 317 command, giving it no arguments. This tells you what branch the
belaran@964 318 parent of the current changeset is on.
belaran@964 319 <!-- &interaction.branch-named.branch; -->
belaran@964 320 </para>
belaran@964 321
belaran@964 322 <para>To create a new branch, run the <command role="hg-cmd">hg branch</command> command again. This
belaran@964 323 time, give it one argument: the name of the branch you want to create.
belaran@964 324 <!-- &interaction.branch-named.create; -->
belaran@964 325 </para>
belaran@964 326
belaran@964 327 <para>After you've created a branch, you might wonder what effect the
belaran@964 328 <command role="hg-cmd">hg branch</command> command has had. What do the <command role="hg-cmd">hg status</command> and
belaran@964 329 <command role="hg-cmd">hg tip</command> commands report?
belaran@964 330 <!-- &interaction.branch-named.status; -->
belaran@964 331 Nothing has changed in the working directory, and there's been no new
belaran@964 332 history created. As this suggests, running the <command role="hg-cmd">hg branch</command> command
belaran@964 333 has no permanent effect; it only tells Mercurial what branch name to
belaran@964 334 use the <emphasis>next</emphasis> time you commit a changeset.
belaran@964 335 </para>
belaran@964 336
belaran@964 337 <para>When you commit a change, Mercurial records the name of the branch on
belaran@964 338 which you committed. Once you've switched from the <literal>default</literal>
belaran@964 339 branch to another and committed, you'll see the name of the new branch
belaran@964 340 show up in the output of <command role="hg-cmd">hg log</command>, <command role="hg-cmd">hg tip</command>, and other commands
belaran@964 341 that display the same kind of output.
belaran@964 342 <!-- &interaction.branch-named.commit; -->
belaran@964 343 The <command role="hg-cmd">hg log</command>-like commands will print the branch name of every
belaran@964 344 changeset that's not on the <literal>default</literal> branch. As a result, if
belaran@964 345 you never use named branches, you'll never see this information.
belaran@964 346 </para>
belaran@964 347
belaran@964 348 <para>Once you've named a branch and committed a change with that name,
belaran@964 349 every subsequent commit that descends from that change will inherit
belaran@964 350 the same branch name. You can change the name of a branch at any
belaran@964 351 time, using the <command role="hg-cmd">hg branch</command> command.
belaran@964 352 <!-- &interaction.branch-named.rebranch; -->
belaran@964 353 In practice, this is something you won't do very often, as branch
belaran@964 354 names tend to have fairly long lifetimes. (This isn't a rule, just an
belaran@964 355 observation.)
belaran@964 356 </para>
belaran@964 357
belaran@964 358 </sect1>
belaran@964 359 <sect1>
belaran@964 360 <title>Dealing with multiple named branches in a repository</title>
belaran@964 361
belaran@964 362 <para>If you have more than one named branch in a repository, Mercurial will
belaran@964 363 remember the branch that your working directory on when you start a
belaran@964 364 command like <command role="hg-cmd">hg update</command> or <command role="hg-cmd">hg pull -u</command>. It will update
belaran@964 365 the working directory to the tip of this branch, no matter what the
belaran@964 366 <quote>repo-wide</quote> tip is. To update to a revision that's on a different
belaran@964 367 named branch, you may need to use the <option role="hg-opt-update">-C</option> option to
belaran@964 368 <command role="hg-cmd">hg update</command>.
belaran@964 369 </para>
belaran@964 370
belaran@964 371 <para>This behaviour is a little subtle, so let's see it in action. First,
belaran@964 372 let's remind ourselves what branch we're currently on, and what
belaran@964 373 branches are in our repository.
belaran@964 374 <!-- &interaction.branch-named.parents; -->
belaran@964 375 We're on the <literal>bar</literal> branch, but there also exists an older
belaran@964 376 <command role="hg-cmd">hg foo</command> branch.
belaran@964 377 </para>
belaran@964 378
belaran@964 379 <para>We can <command role="hg-cmd">hg update</command> back and forth between the tips of the
belaran@964 380 <literal>foo</literal> and <literal>bar</literal> branches without needing to use the
belaran@964 381 <option role="hg-opt-update">-C</option> option, because this only involves going backwards
belaran@964 382 and forwards linearly through our change history.
belaran@964 383 <!-- &interaction.branch-named.update-switchy; -->
belaran@964 384 </para>
belaran@964 385
belaran@964 386 <para>If we go back to the <literal>foo</literal> branch and then run <command role="hg-cmd">hg update</command>,
belaran@964 387 it will keep us on <literal>foo</literal>, not move us to the tip of
belaran@964 388 <literal>bar</literal>.
belaran@964 389 <!-- &interaction.branch-named.update-nothing; -->
belaran@964 390 </para>
belaran@964 391
belaran@964 392 <para>Committing a new change on the <literal>foo</literal> branch introduces a new
belaran@964 393 head.
belaran@964 394 <!-- &interaction.branch-named.foo-commit; -->
belaran@964 395 </para>
belaran@964 396
belaran@964 397 </sect1>
belaran@964 398 <sect1>
belaran@964 399 <title>Branch names and merging</title>
belaran@964 400
belaran@964 401 <para>As you've probably noticed, merges in Mercurial are not symmetrical.
belaran@964 402 Let's say our repository has two heads, 17 and 23. If I
belaran@964 403 <command role="hg-cmd">hg update</command> to 17 and then <command role="hg-cmd">hg merge</command> with 23, Mercurial records
belaran@964 404 17 as the first parent of the merge, and 23 as the second. Whereas if
belaran@964 405 I <command role="hg-cmd">hg update</command> to 23 and then <command role="hg-cmd">hg merge</command> with 17, it records 23
belaran@964 406 as the first parent, and 17 as the second.
belaran@964 407 </para>
belaran@964 408
belaran@964 409 <para>This affects Mercurial's choice of branch name when you merge. After
belaran@964 410 a merge, Mercurial will retain the branch name of the first parent
belaran@964 411 when you commit the result of the merge. If your first parent's
belaran@964 412 branch name is <literal>foo</literal>, and you merge with <literal>bar</literal>, the
belaran@964 413 branch name will still be <literal>foo</literal> after you merge.
belaran@964 414 </para>
belaran@964 415
belaran@964 416 <para>It's not unusual for a repository to contain multiple heads, each with
belaran@964 417 the same branch name. Let's say I'm working on the <literal>foo</literal>
belaran@964 418 branch, and so are you. We commit different changes; I pull your
belaran@964 419 changes; I now have two heads, each claiming to be on the <literal>foo</literal>
belaran@964 420 branch. The result of a merge will be a single head on the
belaran@964 421 <literal>foo</literal> branch, as you might hope.
belaran@964 422 </para>
belaran@964 423
belaran@964 424 <para>But if I'm working on the <literal>bar</literal> branch, and I merge work from
belaran@964 425 the <literal>foo</literal> branch, the result will remain on the <literal>bar</literal>
belaran@964 426 branch.
belaran@964 427 <!-- &interaction.branch-named.merge; -->
belaran@964 428 </para>
belaran@964 429
belaran@964 430 <para>To give a more concrete example, if I'm working on the
belaran@964 431 <literal>bleeding-edge</literal> branch, and I want to bring in the latest fixes
belaran@964 432 from the <literal>stable</literal> branch, Mercurial will choose the <quote>right</quote>
belaran@964 433 (<literal>bleeding-edge</literal>) branch name when I pull and merge from
belaran@964 434 <literal>stable</literal>.
belaran@964 435 </para>
belaran@964 436
belaran@964 437 </sect1>
belaran@964 438 <sect1>
belaran@964 439 <title>Branch naming is generally useful</title>
belaran@964 440
belaran@964 441 <para>You shouldn't think of named branches as applicable only to situations
belaran@964 442 where you have multiple long-lived branches cohabiting in a single
belaran@964 443 repository. They're very useful even in the one-branch-per-repository
belaran@964 444 case.
belaran@964 445 </para>
belaran@964 446
belaran@964 447 <para>In the simplest case, giving a name to each branch gives you a
belaran@964 448 permanent record of which branch a changeset originated on. This
belaran@964 449 gives you more context when you're trying to follow the history of a
belaran@964 450 long-lived branchy project.
belaran@964 451 </para>
belaran@964 452
belaran@964 453 <para>If you're working with shared repositories, you can set up a
belaran@964 454 <literal role="hook">pretxnchangegroup</literal> hook on each that will block incoming changes
belaran@964 455 that have the <quote>wrong</quote> branch name. This provides a simple, but
belaran@964 456 effective, defence against people accidentally pushing changes from a
belaran@964 457 <quote>bleeding edge</quote> branch to a <quote>stable</quote> branch. Such a hook might
belaran@964 458 look like this inside the shared repo's <filename role="special"> /.hgrc</filename>.
belaran@964 459 </para>
belaran@964 460 <programlisting>
belaran@964 461 <para> [hooks]
belaran@964 462 pretxnchangegroup.branch = hg heads --template '{branches} ' | grep mybranch
belaran@964 463 </para>
belaran@964 464 </programlisting>
belaran@964 465
belaran@964 466 </sect1>
belaran@964 467 </chapter>
belaran@964 468
belaran@964 469 <!--
belaran@964 470 local variables:
belaran@964 471 sgml-parent-document: ("00book.xml" "book" "chapter")
belaran@964 472 end:
belaran@964 473 -->