changeset 206:6519f3b983b4

More material about named branches.
author Bryan O'Sullivan <bos@serpentine.com>
date Mon, 23 Apr 2007 15:28:13 -0700
parents c76a3e2a600c
children 54ca4e00e569
files en/branch.tex en/examples/branch-named en/examples/branch-named.branch.out en/examples/branch-named.branches.out en/examples/branch-named.commit.out en/examples/branch-named.create.out en/examples/branch-named.foo-commit.out en/examples/branch-named.merge.out en/examples/branch-named.parents.out en/examples/branch-named.rebranch.out en/examples/branch-named.status.out en/examples/branch-named.update-bar.out en/examples/branch-named.update-foo.out en/examples/branch-named.update-nothing.out en/examples/branch-named.update-switchy.out en/examples/branch-named.update.out
diffstat 16 files changed, 268 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/en/branch.tex	Mon Apr 23 13:52:15 2007 -0700
+++ b/en/branch.tex	Mon Apr 23 15:28:13 2007 -0700
@@ -291,7 +291,48 @@
 
 Once you've named a branch and committed a change with that name,
 every subsequent commit that descends from that change will inherit
-the same branch name.
+the same branch name.  You can change the name of a branch at any
+time, using the \hgcmd{branch} command.  
+\interaction{branch-named.rebranch}
+In practice, this is something you won't do very often, as branch
+names tend to have fairly long lifetimes.  (This isn't a rule, just an
+observation.)
+
+\section{Dealing with multiple named branches in a repository}
+
+If you have more than one named branch in a repository, Mercurial will
+remember the branch that your working directory on when you start a
+command like \hgcmd{update} or \hgcmdargs{pull}{-u}.  It will update
+the working directory to the tip of this branch, no matter what the
+``repo-wide'' tip is.  To update to a revision that's on a different
+named branch, you may need to use the \hgopt{update}{-C} option to
+\hgcmd{update}.
+
+This behaviour is a little subtle, so let's see it in action.  First,
+let's remind ourselves what branch we're currently on, and what
+branches are in our repository.
+\interaction{branch-named.parents}
+We're on the \texttt{bar} branch, but there also exists an older
+\hgcmd{foo} branch.
+
+We can \hgcmd{update} back and forth between the tips of the
+\texttt{foo} and \texttt{bar} branches without needing to use the
+\hgopt{update}{-C} option, because this only involves going backwards
+and forwards linearly through our change history.
+\interaction{branch-named.update-switchy}
+
+If we go back to the \texttt{foo} branch and then run \hgcmd{update},
+it will keep us on \texttt{foo}, not move us to the tip of
+\texttt{bar}.
+\interaction{branch-named.update-nothing}
+
+Committing a new change on the \texttt{foo} branch introduces a new
+head.
+\interaction{branch-named.foo-commit}
+We can no longer update from \texttt{foo} to \texttt{bar} without
+going ``sideways'' in history, so Mercurial forces us to provide the
+\hgopt{update}{-C} option to \hgcmd{update}.
+\interaction{branch-named.update-bar}
 
 \section{Branch names and merging}
 
@@ -302,10 +343,47 @@
 I \hgcmd{update} to 23 and then \hgcmd{merge} with 17, it records 23
 as the first parent, and 17 as the second.
 
-This behaviour affects Mercurial's choice of branch name when you
-merge.  During a merge, Mercurial will by default use the name of the
-first parent.
+This affects Mercurial's choice of branch name when you merge.  After
+a merge, Mercurial will retain the branch name of the first parent
+when you commit the result of the merge.  If your first parent's
+branch name is \texttt{foo}, and you merge with \texttt{bar}, the
+branch name will still be \texttt{foo} after you merge.
+
+It's not unusual for a repository to contain multiple heads, each with
+the same branch name.  Let's say I'm working on the \texttt{foo}
+branch, and so are you.  We commit different changes; I pull your
+changes; I now have two heads, each claiming to be on the \texttt{foo}
+branch.  The result of a merge will be a single head on the
+\texttt{foo} branch, as you might hope.
+
+But if I'm working on the \texttt{bar} branch, and I merge work from
+the \texttt{foo} branch, the result will remain on the \texttt{bar}
+branch.
+\interaction{branch-named.merge}
 
+To give a more concrete example, if I'm working on the
+\texttt{bleeding-edge} branch, and I want to bring in the latest fixes
+from the \texttt{stable} branch, Mercurial will choose the ``right''
+(\texttt{bleeding-edge}) branch name when I pull and merge from
+\texttt{stable}.
+
+\section{Branch naming is generally useful}
+
+You shouldn't think of named branches as applicable only to situations
+where you have multiple long-lived branches cohabiting in a single
+repository.  They're very useful even in the one-branch-per-repository
+case.  
+
+In the simplest case, giving a name to each branch gives you a
+permanent record of which branch a changeset originated on.  This
+gives you a more context when you're trying to follow the history of a
+long-lived branchy project.
+
+If you're working with multiple shared repositories, you can set up a
+hook on each that will block incoming changes that have the ``wrong''
+branch name.  This provides a simple, but effective, defence against
+people accidentally pushing changes from a ``bleeding edge'' branch to
+a ``stable'' branch.
 
 %%% Local Variables: 
 %%% mode: latex
--- a/en/examples/branch-named	Mon Apr 23 13:52:15 2007 -0700
+++ b/en/examples/branch-named	Mon Apr 23 15:28:13 2007 -0700
@@ -29,3 +29,46 @@
 echo 'hello again' >> myfile
 hg commit -m 'Second commit'
 hg tip
+
+#$ name: rebranch
+
+hg branch
+hg branch bar
+echo new file > newfile
+hg commit -A -m 'Third commit'
+hg tip
+
+#$ name: parents
+
+hg parents
+hg branches
+
+#$ name: update-switchy
+
+hg update foo
+hg parents
+hg update bar
+hg parents
+
+#$ name: update-nothing
+
+hg update foo
+hg update
+
+#$ name: foo-commit
+
+echo something > somefile
+hg commit -A -m 'New file'
+hg heads
+
+#$ name: update-bar
+
+hg update bar
+hg update -C bar
+
+#$ name: merge
+
+hg branch
+hg merge
+hg commit -m 'Merge'
+hg tip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.branch.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,2 @@
+$ \textbf{hg branch}
+default
--- a/en/examples/branch-named.branches.out	Mon Apr 23 13:52:15 2007 -0700
+++ b/en/examples/branch-named.branches.out	Mon Apr 23 15:28:13 2007 -0700
@@ -1,2 +1,9 @@
+$ \textbf{hg tip}
+changeset:   
+tag:         tip
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Initial commit
+
 $ \textbf{hg branches}
 default                        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.commit.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,10 @@
+$ \textbf{echo 'hello again' >> myfile}
+$ \textbf{hg commit -m 'Second commit'}
+$ \textbf{hg tip}
+changeset:   
+branch:      foo
+tag:         tip
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Second commit
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.create.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,3 @@
+$ \textbf{hg branch foo}
+$ \textbf{hg branch}
+foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.foo-commit.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,18 @@
+$ \textbf{echo something > somefile}
+$ \textbf{hg commit -A -m 'New file'}
+adding somefile
+$ \textbf{hg heads}
+changeset:   
+branch:      foo
+tag:         tip
+parent:      
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     New file
+
+changeset:   
+branch:      bar
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Third commit
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.merge.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,16 @@
+$ \textbf{hg branch}
+bar
+$ \textbf{hg merge}
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+$ \textbf{hg commit -m 'Merge'}
+$ \textbf{hg tip}
+changeset:   
+branch:      bar
+tag:         tip
+parent:      
+parent:      
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Merge
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.parents.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,12 @@
+$ \textbf{hg parents}
+changeset:   
+branch:      bar
+tag:         tip
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Third commit
+
+$ \textbf{hg branches}
+bar                            
+foo                            
+default                        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.rebranch.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,14 @@
+$ \textbf{hg branch}
+foo
+$ \textbf{hg branch bar}
+$ \textbf{echo new file > newfile}
+$ \textbf{hg commit -A -m 'Third commit'}
+adding newfile
+$ \textbf{hg tip}
+changeset:   
+branch:      bar
+tag:         tip
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Third commit
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.status.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,8 @@
+$ \textbf{hg status}
+$ \textbf{hg tip}
+changeset:   
+tag:         tip
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Initial commit
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.update-bar.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,4 @@
+$ \textbf{hg update bar}
+abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
+$ \textbf{hg update -C bar}
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.update-foo.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,13 @@
+$ \textbf{hg update foo}
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+$ \textbf{hg update}
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ \textbf{hg parents}
+changeset:   
+branch:      foo
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Second commit
+
+$ \textbf{hg update bar}
+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/branch-named.update-nothing.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,4 @@
+$ \textbf{hg update foo}
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+$ \textbf{hg update}
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.update-switchy.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,19 @@
+$ \textbf{hg update foo}
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+$ \textbf{hg parents}
+changeset:   
+branch:      foo
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Second commit
+
+$ \textbf{hg update bar}
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ \textbf{hg parents}
+changeset:   
+branch:      bar
+tag:         tip
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Third commit
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/examples/branch-named.update.out	Mon Apr 23 15:28:13 2007 -0700
@@ -0,0 +1,13 @@
+$ \textbf{hg update foo}
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+$ \textbf{hg update}
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+$ \textbf{hg parent}
+changeset:   
+branch:      foo
+user:        Bryan O'Sullivan <bos@serpentine.com>
+
+summary:     Second commit
+
+$ \textbf{hg update bar}
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved