L'article de Steve Losh A Guide to Branching in Mercurial permet de se faire une bonne idée du fonctionnement et des possibilités offertes par Mercurial pour gérer des "branches" (afin d'avoir des lignes de développement distinctes).

L'article Mercurial Workflows: Stable & Default quant à lui présente plus précisément la solution "branches nommées" (named branches).

Mais il manque d'exemples pratiques à mon goût, et comme je devais l'expliquer en détail à des amis, voici ma tentative de guide pratique appliqué à la théorie expliquée dans l'article sus-cité.

On commence par initialiser un projet, à créer quelques fichiers et à les committer séparément

$ hg init projet
$ cat > a
hello a
^D
$ hg add a
$ hg commit -m 'ajout a'
$ hg glog --style compact
@  0[tip]   a82264640870   2010-06-05 23:39 +0200   eric
     a

$ cat > b
hello b
^D
$ hg add b
$ hg commit -m 'ajout b'
$ hg glog --style compact
@  1[tip]   39bf03acf954   2010-06-05 23:41 +0200   eric
|    ajout b
|
o  0   a82264640870   2010-06-05 23:39 +0200   eric
     ajout a


On a pour l'instant une seule branche

$ hg branches
default                        1:39bf03acf954


On en crée une sous le nom stable. Elle sera utilisée pour gérer les corrections de bugs de la version stable, tandis que le développement courant aura lieu dans la branche default

$ hg branch stable
marked working directory as branch stable
$ hg commit -m 'stable branch'
$ hg branches
stable                         2:97c9284f569c
default                        1:39bf03acf954 (inactive)


Pour l'instant, l'historique des révisions reste linéaire

$ hg glog --style compact
@  2[tip]   97c9284f569c   2010-06-05 23:42 +0200   eric
|    stable branch
|
o  1   39bf03acf954   2010-06-05 23:41 +0200   eric
|    ajout b
|
o  0   a82264640870   2010-06-05 23:39 +0200   eric
     ajout a


On met à jour le dépôt pour utiliser la branche default et on modifie à nouveau des fichiers

$ hg update default
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg branches
stable                         2:97c9284f569c
default                        1:39bf03acf954 (inactive)
$ cat >> a
bye a
^D
$ cat a
hello a
bye a


Quand on committe notre code, une nouvelle "tête" (head) est créée et l'historique n'est alors plus linéaire, ce qui montre que la branche default diverge de la branche stable, celle-ci étant un sous-ensemble de la première

$ hg commit -m 'bye a'
created new head
$ hg heads --style compact
3[tip]:1   bc970099e4f8   2010-06-05 23:53 +0200   eric
  bye a

2   97c9284f569c   2010-06-05 23:42 +0200   eric
  stable branch
$ hg glog --style compact
@  3[tip]:1   bc970099e4f8   2010-06-05 23:53 +0200   eric
|    bye a
|
| o  2   97c9284f569c   2010-06-05 23:42 +0200   eric
|/     stable branch
|
o  1   39bf03acf954   2010-06-05 23:41 +0200   eric
|    ajout b
|
o  0   a82264640870   2010-06-05 23:39 +0200   eric
     ajout a


Faisons de nouvelles modifications dans la branche de développement principal

$ cat > c
hello c
^D
$ hg add c
$ hg commit -m 'ajout c'
$ hg glog --style compact
@  4[tip]   290b943b61d5   2010-06-05 23:54 +0200   eric
|    ajout c
|
o  3:1   bc970099e4f8   2010-06-05 23:53 +0200   eric
|    bye a
|
| o  2   97c9284f569c   2010-06-05 23:42 +0200   eric
|/     stable branch
|
o  1   39bf03acf954   2010-06-05 23:41 +0200   eric
|    ajout b
|
o  0   a82264640870   2010-06-05 23:39 +0200   eric
     ajout a


Et retournons dans la branche stable pour corriger quelques bugs

$ hg update stable
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ cat >> a
fix a
$ hg commit -m 'fix a'
hg glog --style compact
@  5[tip]:2   26c5f5e23509   2010-06-05 23:55 +0200   eric
|    fix a
|
| o  4   290b943b61d5   2010-06-05 23:54 +0200   eric
| |    ajout c
| |
| o  3:1   bc970099e4f8   2010-06-05 23:53 +0200   eric
| |    bye a
| |
o |  2   97c9284f569c   2010-06-05 23:42 +0200   eric
|/     stable branch
|
o  1   39bf03acf954   2010-06-05 23:41 +0200   eric
|    ajout b
|
o  0   a82264640870   2010-06-05 23:39 +0200   eric
     ajout a


Maintenant il faut bien évidemment que ces corrections de bugs se retrouvent également dans la branche de dev default

$ hg update default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 26c5f5e23509
merging a
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m 'merge with 26c5f5e23509 (stable branch)'
$ hg glog --style compact
@  6[tip]:4,5   fb323a167af1   2010-06-05 23:57 +0200   eric
|\     merge with 26c5f5e23509 (stable branch)
| |
| o  5:2   26c5f5e23509   2010-06-05 23:55 +0200   eric
| |   fix a
| |
o |  4   290b943b61d5   2010-06-05 23:54 +0200   eric
| |    ajout c
| |
o |  3:1   bc970099e4f8   2010-06-05 23:53 +0200   eric
| |    bye a
| |
| o  2   97c9284f569c   2010-06-05 23:42 +0200   eric
|/     stable branch
|
o  1   39bf03acf954   2010-06-05 23:41 +0200   eric
|    ajout b
|
o  0   a82264640870   2010-06-05 23:39 +0200   eric
     ajout a


On voit bien que le fichier a contient le code venant des deux branches (même si ça se joue au moment du merge)

$ cat a
hello a
fix a
bye a


Quand vous voulez remplacer la branche stable il suffit de merger avec default

$ hg update stable
$ hg merge 290b943b61d5
$ hg commit -m 'merge with 290b943b61d5'


Pour fermer définitivement la branche, utiliser l'option --close-branch à hg commit.

et voili...

note : l'article a été écrit rapidement donc n'hésitez pas à signaler toute erreur