Mercurial > hgbook
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