Introduction

I’ve been using Mercurial since the middle of 2020 (I think). I’d always stayed at beginner level mainly because I didn’t really need any “advanced” features.

You’ve probably noticed that there a lots of tutorials for Mercurial, but most were either written at least ten years ago (which makes you wonder if they’re still applicable), or they’re quite hard to follow and seem to be aimed at coders with extensive experience of other version control systems such as CVS, Git or Subversion.

There are also plenty of helpful tutorials to get you to a point where you’re a beginner level, or a user level, and then there you stay. There’s nothing wrong with that, but you may be missing on out on some functionality that can save you time and make your coding life a bit easier.

Assumptions

  • You know that Mercurial and hg are the same thing
  • You already know at least a bit about hg
  • You have, or are prepared to, install it on your own
  • You want to get a bit more skilled at using hg

Beginner Workflow

This is how the beginner should use hg.

We start a new project and tell Mercurial to add all files currently in our working directory:

hg init
hg add

Do some work

hg commit -m 'Did some work'

More work

hg commit -m 'More work!'

And like this we continue. This is a perfectly reasonable way to use Mercurial. At a bare minimum, we should push our code to a remote server as a backup. This is as simple as putting the following in your .hg/hgrc:

[paths]
default = ssh://you@yourserver//home/you/hg/your-repo

And then whenever we want to save our work offsite

hg push

This is how I was working until very recently.

Tags, Bookmarks and Branches

For the purposes of this tutorial, I found this old Jekyll folder which I never used. Perfect for us to muck around with!

NOTE — whenever you want to play around, I advise you to use some directory you don’t care about at all. Just in case, you know…

Anyway, our directory we don’t care about looks like this

simon@computer:~/web/demo$ tree
.
├── about.md
├── _config.yml
├── css
│   └── main.scss
├── feed.xml
├── Gemfile
├── Gemfile.lock
├── index.html
├── _posts
│   └── 2016-08-28-welcome-to-jekyll.markdown
└── _site
    ├── about
    │   └── index.html
    ├── css
    │   └── main.css
    ├── feed.xml
    ├── Gemfile
    ├── Gemfile.lock
    ├── index.html
    └── jekyll
        └── update
            └── 2016
                └── 08
                    └── 28
                        └── welcome-to-jekyll.html

Let’s fire up Mercurial:

simon@computer:~/web/demo$ hg init
simon@computer:~/web/demo$ hg status
? .gitignore
? .sass-cache/12a8045a6b922bf16bdd78391fafb023df590261/minima.scssc
? .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_base.scssc
? .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_layout.scssc
? .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_syntax-highlighting.scssc
? Gemfile
? Gemfile.lock
? _config.yml
? _posts/2016-08-28-welcome-to-jekyll.markdown
? _site/Gemfile
? _site/Gemfile.lock
? _site/about/index.html
? _site/css/main.css
? _site/feed.xml
? _site/index.html
? _site/jekyll/update/2016/08/28/welcome-to-jekyll.html
? about.md
? css/main.scss
? feed.xml
? index.html

Add all those existing files:

simon@computer:~/web/demo$ hg add
adding .gitignore
adding .sass-cache/12a8045a6b922bf16bdd78391fafb023df590261/minima.scssc
adding .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_base.scssc
adding .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_layout.scssc
adding .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_syntax-highlighting.scssc
adding Gemfile
adding Gemfile.lock
adding _config.yml
adding _posts/2016-08-28-welcome-to-jekyll.markdown
adding _site/Gemfile
adding _site/Gemfile.lock
adding _site/about/index.html
adding _site/css/main.css
adding _site/feed.xml
adding _site/index.html
adding _site/jekyll/update/2016/08/28/welcome-to-jekyll.html
adding about.md
adding css/main.scss
adding feed.xml
adding index.html
simon@computer:~/web/demo$ hg status
A .gitignore
A .sass-cache/12a8045a6b922bf16bdd78391fafb023df590261/minima.scssc
A .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_base.scssc
A .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_layout.scssc
A .sass-cache/2052c9c59f454d7831e9ef98b764455a8fd0eedd/_syntax-highlighting.scssc
A Gemfile
A Gemfile.lock
A _config.yml
A _posts/2016-08-28-welcome-to-jekyll.markdown
A _site/Gemfile
A _site/Gemfile.lock
A _site/about/index.html
A _site/css/main.css
A _site/feed.xml
A _site/index.html
A _site/jekyll/update/2016/08/28/welcome-to-jekyll.html
A about.md
A css/main.scss
A feed.xml
A index.html

Great. We’ve added everything, so let’s now commit and see what we can do

simon@computer:~/web/demo$ hg commit -m 'Initial commit'
simon@computer:~/web/demo$ hg stat
simon@computer:~/web/demo$ hg log
changeset:   0:df066dc32fd1
tag:         tip
user:        Simon Harrison <me@myemail.com>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Tags

Snippet from running hg help tag

Tags are used to name particular revisions of the repository and are very useful to compare different revisions, to go back to significant earlier versions or to mark branch points as releases, etc. Changing an existing tag is normally disallowed; use -f/—force to override.

We haven’t done anything or changed anything, but let’s create tag, just for the hell of it:

simon@computer:~/web/demo$ hg tag begin
simon@computer:~/web/demo$ hg stat
simon@computer:~/web/demo$ hg log
changeset:   1:84402e47c830
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Ok, so what’s happened here? I create a tag hg tag begin run hg stat (short for status) and nothing seems to have changed. Then I run hg log and we can see that a changeset was created which points to the first changeset (0) which now has a tag called begin. changeset (1), now has a tag called tip which is the default tag if you don’t create any.

Let’s run a diff between the two changesets:

simon@computer:~/web/demo$ hg diff -r0 -r1
diff --git a/.hgtags b/.hgtags
new file mode 100644
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1,1 @@
+df066dc32fd1a5deeb9424d79c1d19f7fcf847ca begin

If we run hg help tag Mercurial tells us that it tracks tags using .hgtags in our working directory. So far, so good.

Let’s create a new file with some content:

simon@computer:~/web/demo$ echo "hey there" >  new_file
simon@computer:~/web/demo$ hg stat
? new_file
simon@computer:~/web/demo$ hg add
adding new_file
simon@computer:~/web/demo$ hg commit -m 'add first new file'
simon@computer:~/web/demo$ hg log
changeset:   2:879d1c6dcebe
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Let’s pretend I’ve done a load of work in new_file

simon@computer:~/web/demo$ hg stat
M new_file
simon@computer:~/web/demo$ hg diff
diff --git a/new_file b/new_file
--- a/new_file
+++ b/new_file
@@ -1,1 +1,3 @@
 hey there
+
+I've done loads of work in this file, so it's time to commit. 

Which I do, of course.

simon@computer:~/web/demo$ hg log
changeset:   3:2b7d44c9402b
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:27:24 2021 +0100
summary:     Lots of work on new_file

changeset:   2:879d1c6dcebe
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Tags, essentially give a name, or label, to a changeset. As you can see above, we have four changesets (revisions) and only two tags. tip is the latest changeset, begin is the one we created after the first commit. So by using tags, we can use semantic names instead of revision numbers:

simon@computer:~/web/demo$ hg diff -r tip -r begin
diff --git a/.hgtags b/.hgtags
deleted file mode 100644
--- a/.hgtags
+++ /dev/null
@@ -1,1 +0,0 @@
-df066dc32fd1a5deeb9424d79c1d19f7fcf847ca begin
diff --git a/new_file b/new_file
deleted file mode 100644
--- a/new_file
+++ /dev/null
@@ -1,3 +0,0 @@
-hey there
-
-I've done loads of work in this file, so it's time to commit.

We can also rollback to a tag (or can we???):

simon@computer:~/web/demo$ hg up begin
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
simon@computer:~/web/demo$ tree
.
├── about.md
├── _config.yml
├── css
│   └── main.scss
├── feed.xml
├── Gemfile
├── Gemfile.lock
├── index.html
├── _posts
│   └── 2016-08-28-welcome-to-jekyll.markdown
└── _site
    ├── about
    │   └── index.html
    ├── css
    │   └── main.css
    ├── feed.xml
    ├── Gemfile
    ├── Gemfile.lock
    ├── index.html
    └── jekyll
        └── update
            └── 2016
                └── 08
                    └── 28
                        └── welcome-to-jekyll.html

10 directories, 15 files

On the second line, hg informs us that 2 files removed which are new_file and .hgtags

Let’s run hg log

simon@computer:~/web/demo$ hg log
changeset:   3:2b7d44c9402b
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:27:24 2021 +0100
summary:     Lots of work on new_file

changeset:   2:879d1c6dcebe
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

So, what will happen if we create a new file: new_file2 and work on that? Bearing in mind we updated back to our begin tag, before we created new_file Let’s find out:

simon@computer:~/web/demo$ echo "another file" > new_file2                                                                                                                                                                                     
simon@computer:~/web/demo$ hg stat
? new_file2
simon@computer:~/web/demo$ hg commit -m 'Add new_file2' 
nothing changed
simon@computer:~/web/demo$ hg add
adding new_file2
simon@computer:~/web/demo$ hg commit -m 'Add new_file2' 
simon@computer:~/web/demo$ hg log
changeset:   4:e4d5c6b8f90b
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:47:34 2021 +0100
summary:     Add new_file2

changeset:   3:2b7d44c9402b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:27:24 2021 +0100
summary:     Lots of work on new_file

changeset:   2:879d1c6dcebe
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Magically, new_file has been brought back to life!

simon@computer:~/web/demo$ tree
.
├── about.md
├── _config.yml
├── css
│   └── main.scss
├── feed.xml
├── Gemfile
├── Gemfile.lock
├── index.html
├── new_file
├── new_file2
├── _posts
│   └── 2016-08-28-welcome-to-jekyll.markdown
└── _site
    ├── about
    │   └── index.html
    ├── css
    │   └── main.css
    ├── feed.xml
    ├── Gemfile
    ├── Gemfile.lock
    ├── index.html
    └── jekyll
        └── update
            └── 2016
                └── 08
                    └── 28
                        └── welcome-to-jekyll.html

10 directories, 17 files

So, we can conclude that tags just give names to changesets and don’t actually change anything. When we run hg commit we automatically go right to the top (tip) and everything gets put back to it’s correct state.

Bookmarks

Snippet from running hg help bookmark

Bookmarks are labels on changesets to help track lines of development. Bookmarks are unversioned and can be moved, renamed and deleted. Deleting or moving a bookmark has no effect on the associated changesets.

So, we are told that bookmarks are also a form of label. Let’s give it a whirl

simon@computer:~/web/demo$ echo "third file" > new_file3  
simon@computer:~/web/demo$ hg stat                                                                                                                                                                                                             
? new_file3                                                                                                                                                                                                                                   
simon@computer:~/web/demo$ hg add                                                                                                                                                                                                              
adding new_file3                                                                                                                                                                                                                              
simon@computer:~/web/demo$ hg book three                                                                                                                                                                                                       
simon@computer:~/web/demo$ hg stat                                                                                                                                                                                                             
A new_file3                                                                                                                                                                                                                                   
simon@computer:~/web/demo$ hg commit -m 'Add third new file'                                                                                                                                                                                                               
simon@computer:~/web/demo$ hg log
changeset:   5:57493ab661f6
bookmark:    three
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 20:16:06 2021 +0100
summary:     Add third new file

changeset:   4:e4d5c6b8f90b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:47:34 2021 +0100
summary:     Add new_file2

changeset:   3:2b7d44c9402b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:27:24 2021 +0100
summary:     Lots of work on new_file

changeset:   2:879d1c6dcebe
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Interesting. Looking at changeset (5) we see we now have a bookmark called three and as always, a tag of tip but what happens if we change something?

Well, we’ve been working hard on new_file3

simon@computer:~/web/demo$ hg stat
M new_file3
simon@computer:~/web/demo$ hg diff
diff --git a/new_file3 b/new_file3
--- a/new_file3
+++ b/new_file3
@@ -1,1 +1,3 @@
 third file
+
+this is a new thing, right here!

and now we commit our changes

simon@computer:~/web/demo$ hg commit -m 'Worked on new_file3'
simon@computer:~/web/demo$ hg log
changeset:   6:755546c87c27
bookmark:    three
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 20:30:31 2021 +0100
summary:     Worked on new_file3

changeset:   5:57493ab661f6
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 20:16:06 2021 +0100
summary:     Add third new file

changeset:   4:e4d5c6b8f90b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:47:34 2021 +0100
summary:     Add new_file2

changeset:   3:2b7d44c9402b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:27:24 2021 +0100
summary:     Lots of work on new_file

changeset:   2:879d1c6dcebe
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

As you can see, and as promised (if you read the help), bookmarks replace tip, like a physical bookmark, hg puts that bookmark in place when we’ve finished reading / working, so we know where we are. Furthermore, it keeps that bookmark moving as tip moves, using our new bookmark instead of tip. Think of it like a tag that gets stamped on each revision until we give it a new one.

Consider the default alternative; you just use tip (the default bookmark)

  • You start work
  • You finish work

No tags, no bookmarks, just a beginning and an end with loads of commits in between.

Tags and bookmarks let you search your history semantically

Show me all changes between when I started and initial upload to my server hg diff -r begin -r upload-to-server instead of hg diff -r0 -r48

I think that’s the idea with tags.

Branches

Snippet from hg help branch

With no argument, show the current branch name. With one argument, set the working directory branch name (the branch will not exist in the repository until the next commit). Standard practice recommends that primary development take place on the ‘default’ branch.

Let’s see what branches we’ve got right now

simon@computer:~/web/demo$ hg branch
default
simon@computer:~/web/demo$ hg branches
default                        6:755546c87c27

Ok, just the default branch. We’ll now create a new branch and we’ll call it production

simon@computer:~/web/demo$ hg branch production                                                                                                                                                                                                
marked working directory as branch production                                                                                                                                                                                                 
(branches are permanent and global, did you want a bookmark?)                                                                                                                                                                                 
simon@computer:~/web/demo$ hg log
changeset:   6:755546c87c27
bookmark:    three
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 20:30:31 2021 +0100
summary:     Worked on new_file3

changeset:   5:57493ab661f6
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 20:16:06 2021 +0100
summary:     Add third new file

changeset:   4:e4d5c6b8f90b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:47:34 2021 +0100
summary:     Add new_file2

changeset:   3:2b7d44c9402b
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:27:24 2021 +0100
summary:     Lots of work on new_file

changeset:   2:879d1c6dcebe
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 19:11:04 2021 +0100
summary:     add first new file

changeset:   1:84402e47c830
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:38:50 2021 +0100
summary:     Added tag begin for changeset df066dc32fd1

changeset:   0:df066dc32fd1
tag:         begin
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 18:34:51 2021 +0100
summary:     Initial commit

Notice that we got a warning from Mercurial, suggesting we may have wanted a bookmark. Also notice that until we commit, we don’t get our new branch

simon@computer:~/web/demo$ hg stat                                               
simon@computer:~/web/demo$ hg c 'Created production branch'                      
simon@computer:~/web/demo$ hg log                                                
changeset:   7:3fdc76221e4e                                                     
branch:      production
bookmark:    three
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Fri May 07 07:37:32 2021 +0100
summary:     Created production branch

We’ll stay in our production branch and add a feature

simon@computer:~/web/demo$ echo "new feature 1" > feature1                       
simon@computer:~/web/demo$ hg stat                                               
? feature1                                                                      
simon@computer:~/web/demo$ hg add                                                
adding feature1                                                                 
simon@computer:~/web/demo$ hg commit -m 'add feature 1'                          
simon@computer:~/web/demo$ hg log                                                
changeset:   8:d2c43579ccbd                                                     
branch:      production
bookmark:    three
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Fri May 07 07:41:45 2021 +0100
summary:     add feature 1

Let’s run hg branches

simon@computer:~/web/demo$ hg branches
production                     8:d2c43579ccbd
default                        6:755546c87c27 (inactive)

Remembering the warning we got from Mercurial eariler, we want to go back to our default branch as our normal development line and merge back into production when we need to

simon@computer:~/web/demo$ hg merge
abort: no matching bookmark to merge - please merge with an explicit rev or bookmark
(run 'hg heads' to see all heads, specify rev with -r)
simon@computer:~/web/demo$ hg heads
changeset:   8:d2c43579ccbd
branch:      production
bookmark:    three
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Fri May 07 07:41:45 2021 +0100
summary:     add feature 1

changeset:   6:755546c87c27
user:        Simon Harrison <simon@myemail>
date:        Thu May 06 20:30:31 2021 +0100
summary:     Worked on new_file3

As you can see, Mercurial is very helpfully telling us it doesn’t know what we want to do.

Our new production branch has a feature we want to graft on to default. In fact, we really want to move back to the default branch and merge fixes and features to production when we need to.

simon@computer:~/web/demo$ hg up default                                         
0 files updated, 0 files merged, 1 files removed, 0 files unresolved            
(leaving bookmark three)                                                        
simon@computer:~/web/demo$ hg merge production                                   
1 files updated, 0 files merged, 0 files removed, 0 files unresolved            
(branch merge, don't forget to commit)                                          
simon@computer:~/web/demo$ hg commit -m 'Add new feature from production branch' 
simon@computer:~/web/demo$ hg log                                                
changeset:   9:0c6a046dbffa                                                     
tag:         tip                                                                
parent:      6:755546c87c27                                                     
parent:      8:d2c43579ccbd                                                     
user:        Simon Harrison <simon@myemail>                           
date:        Fri May 07 07:56:05 2021 +0100                                     
summary:     Add new feature from production branch    

Now we can run hg log -G to see a graph of our changesets.

simon@computer:~/web/demo$ hg log -G
@    changeset:   9:0c6a046dbffa
|\   tag:         tip
| |  parent:      6:755546c87c27
| |  parent:      8:d2c43579ccbd
| |  user:        Simon Harrison <simon@myemail>
| |  date:        Fri May 07 07:56:05 2021 +0100
| |  summary:     Add new feature from production branch
| |
| o  changeset:   8:d2c43579ccbd
| |  branch:      production
| |  bookmark:    three
| |  user:        Simon Harrison <simon@myemail>
| |  date:        Fri May 07 07:41:45 2021 +0100
| |  summary:     add feature 1
| |
| o  changeset:   7:3fdc76221e4e
|/   branch:      production
|    user:        Simon Harrison <simon@myemail>
|    date:        Fri May 07 07:37:32 2021 +0100
|    summary:     Created production branch
|
o  changeset:   6:755546c87c27
|  user:        Simon Harrison <simon@myemail>
|  date:        Thu May 06 20:30:31 2021 +0100
|  summary:     Worked on new_file3

The line on the left is the default branch and we created the production branch and then merged it back into default

There’s nothing scary going on at all. Let’s quickly check our files are all in order.

simon@computer:~/web/demo$ ll
total 76K
drwxrwxrwx  7 simon simon 4.0K May  7 07:55 .
drwxrwxrwx 34 simon simon 4.0K Feb  1 16:12 ..
-rwxrwxrwx  1 simon simon  524 Aug 28  2016 about.md
-rwxrwxrwx  1 simon simon 1.3K Aug 28  2016 _config.yml
drwxrwxrwx  2 simon simon 4.0K Sep 13  2017 css
-rw-rw-r--  1 simon simon   14 May  7 07:55 feature1
-rwxrwxrwx  1 simon simon 1.3K Aug 28  2016 feed.xml
-rwxrwxrwx  1 simon simon  817 Aug 28  2016 Gemfile
-rwxrwxrwx  1 simon simon  950 Aug 28  2016 Gemfile.lock
-rwxrwxrwx  1 simon simon   35 Aug 28  2016 .gitignore
drwxrwxr-x  5 simon simon 4.0K May  7 07:56 .hg
-rw-rw-r--  1 simon simon   47 May  6 19:41 .hgtags
-rwxrwxrwx  1 simon simon  515 Aug 28  2016 index.html
-rw-rw-r--  1 simon simon   73 May  6 19:41 new_file
-rw-rw-r--  1 simon simon   13 May  6 19:46 new_file2
-rw-rw-r--  1 simon simon   45 May  6 20:29 new_file3
drwxrwxrwx  2 simon simon 4.0K Sep 13  2017 _posts
drwxrwxrwx  4 simon simon 4.0K Sep 13  2017 .sass-cache
drwxrwxrwx  5 simon simon 4.0K Sep 13  2017 _site

As you can see feature1 is there from the production branch. Running hg branches shows us we’re back to the default branch as we wanted and production is still there, but inactive

simon@computer:~/web/demo$ hg branches
default                        9:0c6a046dbffa
production                     8:d2c43579ccbd (inactive)

We now do some work to feature1

simon@computer:~/web/demo$ hg stat
M feature1
simon@computer:~/web/demo$ hg diff
diff --git a/feature1 b/feature1
--- a/feature1
+++ b/feature1
@@ -1,1 +1,2 @@
 new feature 1
+added more stuff to this file

So we’ll now commit all this work.

simon@computer:~/web/demo$ hg commit -m 'Add more features to feature1'          
simon@computer:~/web/demo$ hg log                                                
changeset:   10:0492f32f1ced                                                    
tag:         tip
user:        Simon Harrison <simon@myemail>
date:        Fri May 07 08:07:58 2021 +0100
summary:     Add more features to feature1

We’ve tested everythind and we’re happy, so now we want these new features in our production branch. The workflow is easy.

  • hg up production
  • hg merge default
  • hg commit -m "your change message"
simon@computer:~/web/demo$ hg up production
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
simon@computer:~/web/demo$ hg merge default                                      
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
simon@computer:~/web/demo$ hg commit -m 'Add feature from default'               
simon@computer:~/web/demo$ hg log -G                                             
@    changeset:   11:7f10b349e381                                               
|\   branch:      production
| |  tag:         tip
| |  parent:      8:d2c43579ccbd
| |  parent:      10:0492f32f1ced
| |  user:        Simon Harrison <simon@myemail>
| |  date:        Fri May 07 08:15:06 2021 +0100
| |  summary:     Add feature from default
| |
| o  changeset:   10:0492f32f1ced
| |  user:        Simon Harrison <simon@myemail>
| |  date:        Fri May 07 08:07:58 2021 +0100
| |  summary:     Add more features to feature1
| |

Let’s check where we are

simon@computer:~/web/demo$ hg branch
production

Let’s head back to our main development line

simon@computer:~/web/demo$ hg up default
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
simon@computer:~/web/demo$ hg branch
default

Lots of projects use a simple development model like this. dev and stable or default and production

In the next post, we’ll look at some slightly more advanced techniques using branches.