Mercurial > hgbook
changeset 179:5fc4a45c069f
Continue documentation of collaboration models.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Fri, 30 Mar 2007 23:05:28 -0700 |
parents | 1b55292716a4 |
children | 6413f88338df |
files | en/Makefile en/collab.tex en/examples/backout en/examples/backout.manual.merge.out en/examples/backout.non-tip.cat.out en/examples/branching en/examples/branching.clone.out en/examples/branching.init.out en/examples/branching.main.out en/examples/branching.merge.out en/examples/branching.stable.out en/examples/branching.tag.out en/examples/branching.update.out en/feature-branches.dot |
diffstat | 14 files changed, 234 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/en/Makefile Thu Mar 29 19:55:18 2007 +0100 +++ b/en/Makefile Fri Mar 30 23:05:28 2007 -0700 @@ -24,6 +24,7 @@ undo.tex image-sources := \ + feature-branches.dot \ filelog.svg \ kdiff3.png \ metadata.svg \ @@ -53,6 +54,7 @@ example-sources := \ backout \ bisect \ + branching \ cmdref \ daily.copy \ daily.files \
--- a/en/collab.tex Thu Mar 29 19:55:18 2007 +0100 +++ b/en/collab.tex Fri Mar 30 23:05:28 2007 -0700 @@ -74,7 +74,7 @@ \subsection{A single central repository} -For smaller projects, migrating from a centralised revision control +For smaller projects migrating from a centralised revision control tool, perhaps the easiest way to get started is to have changes flow through a single shared central repository. This is also the most common ``building block'' for more ambitious workflow schemes. @@ -84,7 +84,7 @@ developers have permission to push a change back when they're ready for other people to see it. -Under this model, it can still sometimes make sense for people to pull +Under this model, it can still often make sense for people to pull changes directly from each other, without going through the central repository. Consider a case in which I have a tentative bug fix, but I am worried that if I were to publish it to the central repository, @@ -102,6 +102,97 @@ needs of people who don't have push access, and those who want to use web browsers to browse the repository's history. +\subsection{Working with multiple branches} + +Projects of any significant size naturally tend to make progress on +several fronts simultaneously. In the case of software, it's common +for a project to go through periodic official releases. A release +might then go into ``maintenance mode'' for a while after its first +publication; maintenance releases tend to contain only bug fixes, not +new features. In parallel with these maintenance releases, one or +more future releases may be under development. People normally use +the word ``branch'' to refer to one of these many slightly different +directions in which development is proceeding. + +Mercurial is particularly well suited to managing a number of +simultaneous, but not identical, branches. Each ``development +direction'' can live in its own central repository, and you can merge +changes from one to another as the need arises. Because repositories +are independent of each other, unstable changes in a development +branch will never affect a stable branch unless someone explicitly +merges those changes in. + +Here's an example of how this can work in practice. Let's say you +have one ``main branch'' on a central server. +\interaction{branching.init} +People clone it, make changes locally, test them, and push them back. + +Once the main branch reaches a release milestone, you can use the +\hgcmd{tag} command to give a permanent name to the milestone +revision. +\interaction{branching.tag} +Let's say some ongoing development occurs on the main branch. +\interaction{branching.main} +Using the tag that was recorded at the milestone, people who clone +that repository at any time in the future can use \hgcmd{update} to +get a copy of the working directory exactly as it was when that tagged +revision was committed. +\interaction{branching.update} + +In addition, immediately after the main branch is tagged, someone can +then clone the main branch on the server to a new ``stable'' branch, +also on the server. +\interaction{branching.clone} + +Someone who needs to make a change to the stable branch can then clone +\emph{that} repository, make their changes, commit, and push their +changes back there. +\interaction{branching.stable} +Because Mercurial repositories are independent, and Mercurial doesn't +move changes around automatically, the stable and main branches are +\emph{isolated} from each other. The changes that you made on the +main branch don't ``leak'' to the stable branch, and vice versa. + +You'll often want all of your bugfixes on the stable branch to show up +on the main branch, too. Rather than rewrite a bugfix on the main +branch, you can simply pull and merge changes from the stable to the +main branch, and Mercurial will bring those bugfixes in for you. +\interaction{branching.merge} +The main branch will still contain changes that are not on the stable +branch, but it will also contain all of the bugfixes from the stable +branch. The stable branch remains unaffected by these changes. + +\subsection{Feature branches} + +For larger projects, an effective way to manage change is to break up +a team into smaller groups. Each group has a shared branch of its +own, cloned from a single ``master'' branch used by the entire +project. People working on an individual branch are typically quite +isolated from developments on other branches. + +\begin{figure}[ht] + \centering + \grafix{feature-branches} + \caption{Feature branches} + \label{fig:collab:feature-branches} +\end{figure} + +When a particular feature is deemed to be in suitable shape, someone +on that feature team pulls and merges from the master branch into the +feature branch, then pushes back up to the master branch. + +\subsection{The release train} + +Some projects are organised on a ``train'' basis: a release is +scheduled to happen every few months, and whatever features are ready +when the ``train'' is ready to leave are allowed in. + +This model resembles working with feature branches. The difference is +that when a feature branch misses a train, someone on the feature team +pulls and merges the changes that went out on that train release, and +the team continues its work on top of that release so that their +feature can make the next release. + \subsection{The Linux kernel model} The development of the Linux kernel has a shallow hierarchical
--- a/en/examples/backout Thu Mar 29 19:55:18 2007 +0100 +++ b/en/examples/backout Fri Mar 30 23:05:28 2007 -0700 @@ -6,7 +6,7 @@ export HGMERGE=$(mktemp) echo '#!/bin/sh' >> $HGMERGE echo 'echo first change > "$1"' >> $HGMERGE -echo 'echo third change > "$1"' >> $HGMERGE +echo 'echo third change >> "$1"' >> $HGMERGE chmod 700 $HGMERGE #$ name: init
--- a/en/examples/backout.manual.merge.out Thu Mar 29 19:55:18 2007 +0100 +++ b/en/examples/backout.manual.merge.out Fri Mar 30 23:05:28 2007 -0700 @@ -4,4 +4,5 @@ (branch merge, don't forget to commit) $ \textbf{hg commit -m 'merged backout with previous tip'} $ \textbf{cat myfile} +first change third change
--- a/en/examples/backout.non-tip.cat.out Thu Mar 29 19:55:18 2007 +0100 +++ b/en/examples/backout.non-tip.cat.out Fri Mar 30 23:05:28 2007 -0700 @@ -1,2 +1,3 @@ $ \textbf{cat myfile} +first change third change
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,62 @@ +#!/bin/bash + +#$ name: init + +hg init main +cd main +echo 'This is a boring feature.' > myfile +hg commit -A -m 'We have reached an important milestone!' + +#$ name: tag + +hg tag v1.0 +hg tip +hg tags + +#$ name: main + +cd ../main +echo 'This is exciting and new!' >> myfile +hg commit -m 'Add a new feature' +cat myfile + +#$ name: update + +cd .. +hg clone -U main main-old +cd main-old +hg update v1.0 +cat myfile + +#$ name: clone + +cd .. +hg clone -rv1.0 main stable + +#$ name: stable + +hg clone stable stable-fix +cd stable-fix +echo 'This is a fix to a boring feature.' > myfile +hg commit -m 'Fix a bug' +hg push + +#$ name: + +export HGMERGE=$(mktemp) +echo '#!/bin/sh' > $HGMERGE +echo 'echo "This is a fix to a boring feature." > "$1"' >> $HGMERGE +echo 'echo "This is exciting and new!" >> "$1"' >> $HGMERGE +chmod 700 $HGMERGE + +#$ name: merge + +cd ../main +hg pull ../stable +hg merge +hg commit -m 'Bring in bugfix from stable branch' +cat myfile + +#$ name: + +rm $HGMERGE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.clone.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,8 @@ +$ \textbf{cd ..} +$ \textbf{hg clone -rv1.0 main stable} +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.init.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,5 @@ +$ \textbf{hg init main} +$ \textbf{cd main} +$ \textbf{echo 'This is a boring feature.' > myfile} +$ \textbf{hg commit -A -m 'We have reached an important milestone!'} +adding myfile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.main.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,6 @@ +$ \textbf{cd ../main} +$ \textbf{echo 'This is exciting and new!' >> myfile} +$ \textbf{hg commit -m 'Add a new feature'} +$ \textbf{cat myfile} +This is a boring feature. +This is exciting and new!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.merge.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,17 @@ +$ \textbf{cd ../main} +$ \textbf{hg pull ../stable} +pulling from ../stable +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files (+1 heads) +(run 'hg heads' to see heads, 'hg merge' to merge) +$ \textbf{hg merge} +merging myfile +0 files updated, 1 files merged, 0 files removed, 0 files unresolved +(branch merge, don't forget to commit) +$ \textbf{hg commit -m 'Bring in bugfix from stable branch'} +$ \textbf{cat myfile} +This is a fix to a boring feature. +This is exciting and new!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.stable.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,12 @@ +$ \textbf{hg clone stable stable-fix} +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +$ \textbf{cd stable-fix} +$ \textbf{echo 'This is a fix to a boring feature.' > myfile} +$ \textbf{hg commit -m 'Fix a bug'} +$ \textbf{hg push} +pushing to /tmp/branchingfJgZac/stable +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.tag.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,11 @@ +$ \textbf{hg tag v1.0} +$ \textbf{hg tip} +changeset: +tag: tip +user: Bryan O'Sullivan <bos@serpentine.com> + +summary: Added tag v1.0 for changeset + +$ \textbf{hg tags} +tip +v1.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/branching.update.out Fri Mar 30 23:05:28 2007 -0700 @@ -0,0 +1,7 @@ +$ \textbf{cd ..} +$ \textbf{hg clone -U main main-old} +$ \textbf{cd main-old} +$ \textbf{hg update v1.0} +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +$ \textbf{cat myfile} +This is a boring feature.