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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/feature-branches.dot	Fri Mar 30 23:05:28 2007 -0700
@@ -0,0 +1,8 @@
+digraph feature_branches {
+	master -> crypto;
+	master -> filesystems;
+	master -> ipc;
+	master -> memory;
+	master -> network;
+	master -> security;
+}