Mercurial_ The Definitive Guide - Bryan O'Sullivan [41]
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 into the stable branch.
Here’s an example of how this can work in practice. Let’s say you have one “main branch” on a central server.
$ hg init main
$ cd main
$ echo 'This is a boring feature.' > myfile
$ hg commit -A -m 'We have reached an important milestone!'
adding myfile
People clone it, make changes locally, test them, and push them back.
Once the main branch reaches a release milestone, you can use the hg tag command to give a permanent name to the milestone revision.
$ hg tag v1.0
$ hg tip
changeset: 1:50a91fd70908
tag: tip
user: Bryan O'Sullivan date: Tue May 05 06:44:27 2009 +0000 summary: Added tag v1.0 for changeset 1af137d00325 $ hg tags tip 1:50a91fd70908 v1.0 0:1af137d00325 Let’s say some ongoing development occurs on the main branch. $ cd ../main $ echo 'This is exciting and new!' >> myfile $ hg commit -m 'Add a new feature' $ cat myfile This is a boring feature. This is exciting and new! Using the tag that was recorded at the milestone, people who clone that repository at any time in the future can use hg update to get a copy of the working directory exactly as it was when that tagged revision was committed. $ cd .. $ hg clone -U main main-old $ cd main-old $ hg update v1.0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat myfile This is a boring feature. In addition, immediately after the main branch is tagged, we can then clone the main branch on the server to a new “stable” branch, also on the server. $ cd .. $ 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 updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved If we need to make a change to the stable branch, we can then clone that repository, make our changes, commit, and push our changes back there. $ hg clone stable stable-fix updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd stable-fix $ echo 'This is a fix to a boring feature.' > myfile $ hg commit -m 'Fix a bug' $ hg push pushing to /tmp/branchingOreYcT/stable searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files Because Mercurial repositories are independent, and Mercurial doesn’t move changes around automatically, the stable and main branches are isolated from each other. The changes that we made on the main branch don’t “leak” to the stable branch, and vice versa. We’ll often want all of our bug fixes on the stable branch to show up on the main branch, too. Rather than rewrite a bug fix on the main branch, we can simply pull and merge changes from the stable to the main branch, and Mercurial will bring those bug fixes in for us. $ cd ../main $ 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) $ hg merge merging myfile 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg commit -m 'Bring in bugfix from stable branch' $ cat myfile This is a fix to a boring feature. This is exciting and new! The main branch will still contain changes that are not on the stable branch, but it will also contain all of the bug fixes from the stable branch. The stable branch remains unaffected by these changes, since