OpenSAF Developer's Guide

1 Introduction

The OpenSAF project uses the  Mercurial distributed revision control system. This document aims to introduce developers to the concepts of distributed revision control, and to clarify the branching and tagging conventions specific to the OpenSAF project.

I will assume that the reader is familiar with the basic concepts of revision control, perhaps with a tool such as Subversion. Where the concepts differ, I will provide examples to illustrate them.

This document is not meant to be a reference for Mercurial. For a very good introduction to Mercurial (and to the concepts of distributed revision control), please read Bryan O'Sullivan's book  Distributed revision control with Mercurial.

2 Getting started

2.1 Required software

You can download Mercurial from  http://www.selenic.com/mercurial/. It is also packaged in many Linux distributions.

2.2 Setting a user name for Mercurial

A username is recorded with each commit to a Mercurial repository. The value of the username is free-form, but it is typically in the form John Doe <email@example.com>. To set this, either set the HGUSER environment variable, or set it in the file .hgrc in your home directory. For example, mine has these contents:

[ui]
username = John Wright <john.wright@hp.com>

2.3 Checking out the source

With distributed revision control systems like Mercurial, your working copy of the source actually contains the full revision history of the project, rather than just the most recent revision. This, as well as some smart merging algorithms, allows you to make changes and commit them without being online. When you're ready for your changes to go public, you push them to an appropriate location. Each OpenSAF developer with SSH access has a web directory set up with a CGI script for simple publishing of Mercurial repositories.

The most common way to create a branch with Mercurial is with the hg clone command. These branches could be short-lived—for example, a temporary clone to pull in changes from an external repository and make sure they merge cleanly—or long-lived—such as a branch for updates to a previously released version. Since cloning is "cheap" in Mercurial—it is fast, and the clone can last for as short or as long a time as you like—you will see it used very frequently. I will often use the terms "branch," "clone," and "repository" interchangeably in this document. (Note, recent versions of Mercurial have support for multiple "named branches in the same repository, with a branch command for dealing with them. This document does not make use of this feature, so this shouldn't cause any ambiguity. For more information, see  Chapter 8, Section 6 of Distributed revision control with Mercurial.)

Note that "master repository" term used throughout this document equals the "trunk" term used in  OpenSAF Development Process. To get a copy of the master repository, use the hg clone command. The first argument to clone is the URL or filesystem path to the repository, and the second (optional) argument is the destination directory. Without a second argument, Mercurial uses the last part of the URL as the destination directory. So, to put a copy of hg:opensaf in a directory called opensaf in the current working directory, execute the following command:

~/opensaf$ hg clone http://devel.opensaf.org/hg/opensaf
destination directory: opensaf
requesting all changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 2368 changes to 2367 files
2367 files updated, 0 files merged, 0 files removed, 0 files unresolved

3 Working on OpenSAF

3.1 Making a simple change

It's often handy to have a "pristine" copy of the master repository, so let's clone the copy we just made:

~/opensaf$ hg clone opensaf opensaf-scratch
2367 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now, suppose we need to add a file to the project. After creating the file, we just use hg add:

~/opensaf$ cd opensaf-scratch
~/opensaf/opensaf-scratch$ echo "bar" > foo
~/opensaf/opensaf-scratch$ hg add foo

Before committing a change, it's good to see what we have changed:

~/opensaf/opensaf-scratch$ hg status
A foo
~/opensaf/opensaf-scratch$ hg diff
diff -r cb8e59469658 foo
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/foo       Mon Jan 07 14:45:37 2008 -0700
@@ -0,0 +1,1 @@
+bar

The output from the status command indicates that we have added a file, and the diff command outputs a unified diff representation of the changes.

Now we're ready to commit. There are three parts to the short commit message

<component>: <message> (#ticket number)

<component> is the last part of the component (after the /) from the component pull down list in trac. For example avsv, clmsv etc

<message> explains the change and is desired to be short, and includes a verb with appropriate tense(present/past) as applicable.
Examples of short messages with different 'tenses' would be:

Example1 avsv: respond to admin ops when SG is STABLE (#2660)

Example2 avsv: do not setup references to other objs in su_new (#2635)

Example3 safimm: fixed regression in immlist (#2009)

Example4 avsv: improved SAF logging for CCB and admin ops (#2660)

(ticket number) should be within brackets and prepended with a "#"

~/opensaf/opensaf-scratch$ hg commit -m 'logsv: Added the foo file (#9999)'
~/opensaf/opensaf-scratch$ hg log
changeset:   3:b67adc860aba
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 14:46:16 2008 -0700
summary:     logsv: Added the foo file (#9999)

changeset:   2:cb8e59469658
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 14:37:03 2008 -0700
summary:     Naming scheme changed: 1.0-5 => 1.0.5 .  Update .hgtags to reflect.

changeset:   1:88cd878f6f8c
user:        john.wright@hp.com
date:        Thu Jan 03 12:57:51 2008 -0700
summary:     Added tag 1.0-5 for changeset 1c7624641cfa

changeset:   0:1c7624641cfa
tag:         1.0.5
user:        john.wright@hp.com
date:        Thu Jan 03 11:47:11 2008 -0700
summary:     Initial import of OpenSAF source

We can view just the tip revision (the latest changeset in the repository) and get some more information:

~/opensaf/opensaf-scratch$ hg tip -v --patch
changeset:   3:b67adc860aba
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 14:46:16 2008 -0700
files:       foo
description:
Added the foo file


diff -r cb8e59469658 -r b67adc860aba foo
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/foo       Mon Jan 07 14:46:16 2008 -0700
@@ -0,0 +1,1 @@
+bar

As you can see, if you are familiar with Subversion, Mercurial's commands are pretty similar. If you need help with a particular command, you can use the help command:

~/opensaf/opensaf-scratch$ hg help log
hg log [OPTION]... [FILE]

show revision history of entire repository or files

    Print the revision history of the specified files or the entire
    project.

    File history is shown without following rename or copy history of
    files.  Use -f/--follow with a file name to follow history across
    renames and copies. --follow without a file name will only show
    ancestors or descendants of the starting revision. --follow-first
    only follows the first parent of merge revisions.

    If no revision range is specified, the default is tip:0 unless
    --follow is set, in which case the working directory parent is
    used as the starting revision.

    By default this command outputs: changeset id and hash, tags,
    non-trivial parents, user, date and time, and a summary for each
    commit. When the -v/--verbose switch is used, the list of changed
    files and full commit message is shown.

    NOTE: log -p may generate unexpected diff output for merge
    changesets, as it will compare the merge changeset against its
    first parent only. Also, the files: list will only reflect files
    that are different from BOTH parents.

aliases: history

options:

 -f --follow        follow changeset history, or file history across copies and renames
    --follow-first  only follow the first parent of merge changesets
 -d --date          show revs matching date spec
 -C --copies        show copied files
 -k --keyword       do case-insensitive search for a keyword
 -l --limit         limit number of changes displayed
 -r --rev           show the specified revision or range
    --removed       include revs where files were removed
 -M --no-merges     do not show merges
    --style         display using template map file
 -m --only-merges   show only merges
 -p --patch         show patch
 -P --prune         do not display revision or any of its ancestors
    --template      display with template
 -I --include       include names matching the given patterns
 -X --exclude       exclude names matching the given patterns

use "hg -v help log" to show global options

3.2 Publishing your changes

So that other people can view and pull from our repository, we need to push it to a publicly accessible location. In order to facilitate web-based browsing of a repository and fast operations over HTTP, Mercurial uses a CGI script (hgweb.cgi or hgwebdir.cgi) for hosting repositories. The webserver on devel.opensaf.org is configured so that any repository pushed to a user's public_html/hg directory will be accessible to browse and to pull from via http://devel.opensaf.org/~user/hg/repo.

Suppose we wish to publish the changes we just made. First, we need to initialize a repository on devel. One way is to use the init command:

~/opensaf/opensaf-scratch$ ssh devel.opensaf.org hg init \
    public_html/hg/opensaf-scratch

However, since the OpenSAF Mercurial repository is pretty large, it would be better to make a clone of the master repository and then push our much smaller changes to it. Since the repository might have changed since we cloned our copy, we need to clone it at the tip revision of our clone.

~/opensaf/opensaf-scratch$ cd ../opensaf
~/opensaf/opensaf$ hg tip
changeset:   2:cb8e59469658
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 14:37:03 2008 -0700
summary:     Naming scheme changed: 1.0-5 => 1.0.5 .  Update .hgtags to reflect.

In Mercurial (and other distributed revision control systems), the sequential revision number for a particular changeset will vary between repositories. To identify a changeset between repositories, we use a hexadecimal identifier (which, behind the scenes, is a hash of the changeset). Here, the last changeset we pulled was cb8e59469658. To clone it into public_html/hg/opensaf-scratch:

~/opensaf/opensaf$ ssh devel.opensaf.org hg clone -U -r cb8e59469658 \
    /var/www/hg/opensaf public_html/hg/opensaf-scratch
requesting all changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 2368 changes to 2367 files

The -U option to the clone command tells Mercurial not to update the working directory. Since all we need is the .hg directory in the clone, this saves some time and space. Now we can push our changes:

~/opensaf/opensaf$ cd ../opensaf-scratch
~/opensaf/opensaf-scratch$ hg push \
    ssh://devel.opensaf.org/public_html/hg/opensaf-scratch
pushing to ssh://devel.opensaf.org/public_html/hg/opensaf-scratch
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files

Note, the path given in the ssh protocol is relative to your home directory; to give an absolute path, use two slashes after the hostname, e.g. ssh://devel.opensaf.org//var/www/hg/opensaf-staging.

3.3 Pulling from published branches

When you clone a repository, Mercurial keeps track of where it was cloned from so that it's easy to track upstream changes. Back in our pristine clone, we can issue the incoming command to see what has changed in the upstream branch:

~/opensaf/opensaf-scratch$ cd ../opensaf
~/opensaf/opensaf$ hg incoming
comparing with http://devel.opensaf.org/hg/opensaf
searching for changes
no changes found

Nothing has changed since we cloned the master repository. Now, suppose a developer has published some changes, and we want to review and potentially merge those changes. First, let's make another clone of our pristine repository for the merge:

~/opensaf/opensaf$ cd ..
~/opensaf$ hg clone opensaf opensaf-merge
2367 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now, suppose the developer has published his changes to http://devel.opensaf.org/~jswright/hg/opensaf-scratch. Let's see what changes have been made to that branch:

~/opensaf$ cd opensaf-merge
~/opensaf/opensaf-merge$ hg incoming -v --patch \
    http://devel.opensaf.org/~jswright/hg/opensaf-scratch
comparing with http://devel.opensaf.org/~jswright/hg/opensaf-scratch
searching for changes
changeset:   3:b67adc860aba
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 14:46:16 2008 -0700
files:       foo
description:
Added the foo file


diff -r cb8e59469658 -r b67adc860aba foo
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/foo       Mon Jan 07 14:46:16 2008 -0700
@@ -0,0 +1,1 @@
+bar

To pull changes from another repository, use the pull command.

~/opensaf/opensaf-merge$ hg pull \
    http://devel.opensaf.org/~jswright/hg/opensaf-scratch
pulling from http://devel.opensaf.org/~jswright/hg/opensaf-scratch
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)

Mercurial does not by default automatically update the working copy when you pull from another repository, but it helpfully reminds us that we need to run hg update. (You can also specify the -u option to hg pull, to automatically update the working copy.) Let's update it:

~/opensaf/opensaf-merge$ hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now, we could publish this repository in the same manner as we published the hg:/~jswright:opensaf-scratch repository.

4 Maintainer actions

Now that I have discussed some of the basics of Mercurial, we can discuss some common actions a feature maintainer or release manager might perform. Many of the examples here are pertinent to non-maintainers as well, especially since there are some real-life examples instead of just contrived ones.

4.1 Accepting changes from a developer

The preferred way for a developer to submit changes is by publishing a Mercurial branch as mentioned in Publishing your changes above. For these changes to make their way into the master hg:opensaf repository, a maintainer must perform the following steps:

  1. Clone (or update their clone of) the hg:opensaf-staging repository
  2. Pull the changes from the developer's tree into the opensaf-staging clone
  3. Perform a merge (often this will be trivial)
  4. Push to  ssh://devel.opensaf.org/hg/www/opensaf-staging

(I'll describe these steps in detail below.) After each push to the hg:opensaf-staging repository, a build is triggered on several different architectures, with some different configuration options. (See http://devel.opensaf.org/buildbot/ and the BuildBot? page for more details.) If the build succeeds on all configurations, the change is pushed to the master hg:opensaf repository. This ensures that the master repository ("trunk") will always build.

4.1.1 Cloning the hg:opensaf-staging repository

Developers will typically branch from the master repository rather than the staging one, but since we will be pushing to the staging repository, we need to ensure we have all the changesets in that repository. (The only reason hg:opensaf-staging should differ from hg:opensaf is if the staging repository doesn't build, or if the push to the master repository simply hasn't happened yet.)

~/opensaf$ hg clone http://devel.opensaf.org/hg/opensaf-staging
destination directory: opensaf-staging
requesting all changes
adding changesets
adding manifests
adding file changes
added 29 changesets with 3975 changes to 2535 files
2496 files updated, 0 files merged, 0 files removed, 0 files unresolved

In the future, if you already have an clone of hg:opensaf-staging, you can simply pull and update your tree:

~/opensaf/opensaf-staging$ hg pull -u
pulling from http://devel.opensaf.org/hg/opensaf-staging
searching for changes
no changes found

(In this case, there were no changes on the staging repository since I made my clone.)

4.1.2 Pulling changes from a developer's tree

Hans Feldt has submitted a tree with some changes to the UML simulated environment for inclusion into the master repository. He has published it at http://devel.opensaf.org/~hafe/hg/opensaf-uml (we can refer to this inside of Trac as hg:/~hafe:opensaf-uml). Our first task is to pull the changes from his branch. It's a good idea first to take a look at what would be pulled:

~/opensaf/opensaf-staging$ hg incoming http://devel.opensaf.org/~hafe/hg/opensaf-uml
comparing with http://devel.opensaf.org/~hafe/hg/opensaf-uml
searching for changes
changeset:   29:2372d20f9445
parent:      25:6556b700c674
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Fri Feb 29 15:06:55 2008 +0100
summary:     Updated with latest versions of kernel & busybox. 64 bit support.

changeset:   30:a1a612fef365
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 09:39:44 2008 +0100
summary:     Added lib64 in root template

changeset:   31:7c91bc121b0d
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 09:41:27 2008 +0100
summary:     added mdev.conf in root template

changeset:   32:ed8bc706778d
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:14:03 2008 +0100
summary:     Changed from make system to batch script

changeset:   33:1708b7a0b970
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:18:29 2008 +0100
summary:     some missing files

changeset:   34:63d46a2b638e
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:21:02 2008 +0100
summary:     remove

changeset:   35:88031930b749
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:55:24 2008 +0100
summary:     fix

changeset:   36:8f434f6c5a3c
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 17:08:02 2008 +0100
summary:     added missing dir

changeset:   37:0c7f57042981
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 17:17:58 2008 +0100
summary:     robuster wgets

changeset:   38:1772ee36adc2
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 17:23:33 2008 +0100
summary:     robust wgets again

changeset:   39:9314051074ca
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 18:13:39 2008 +0100
summary:     Created new function and removed some

changeset:   40:a488737e0428
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 18:16:06 2008 +0100
summary:     removed sed of inittime

changeset:   41:e244cc59be54
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 14:08:06 2008 +0100
summary:     unused file removed, faster rde start, always rebuild root fs

changeset:   42:88ee2aff36d3
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 14:55:09 2008 +0100
summary:     Bad cleaning

changeset:   43:44942b5499f0
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 20:03:13 2008 +0100
summary:     extract gz and bz2 files differently

changeset:   44:e835f607f17d
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 21:35:24 2008 +0100
summary:     more cleaning

changeset:   45:484fc21ccffe
tag:         tip
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Fri Mar 07 11:52:43 2008 +0100
summary:     use default NCSSystemBOM.xml

(If there were fewer changesets, I would probably add the -v option, which will show the names of the files changed, and possibly the --patch option. The --patch option is especially useful for code review.)

Now to actually pull the changes

~/opensaf/opensaf-staging$ hg pull -u http://devel.opensaf.org/~hafe/hg/opensaf-uml
pulling from http://devel.opensaf.org/~hafe/hg/opensaf-uml
searching for changes
adding changesets
adding manifests
adding file changes
added 17 changesets with 44 changes to 27 files (+1 heads)
not updating, since new heads added
(run 'hg heads' to see heads, 'hg merge' to merge)

Notice, Mercurial complained about there being new heads. This happens if there were changes on hg:opensaf-staging since the changeset that the developer branched at. This is usually not a problem, since Mercurial has very smart merge tracking; however, it can lead to a conflict, particularly if the same point in a particular file was edited in different ways on the divergent branches.

4.1.3 Merging the changes

This step is necessary if, as above, the staging repository receives new revisions after the developer branches. You can always perform these steps, though—if a merge is not needed, Mercurial simply won't do anything.

First, let's see what the two heads of our repository are:

~/opensaf/opensaf-staging$ hg heads
changeset:   45:484fc21ccffe
tag:         tip
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Fri Mar 07 11:52:43 2008 +0100
summary:     use default NCSSystemBOM.xml

changeset:   28:061f43513e87
user:        Mahesh <mahesh.alla@emerson.com>
date:        Fri Feb 29 17:06:47 2008 +0530
summary:     Fix for Ticket #10 - clean_up nis_scxb nis_snmpd_clean.sh

This makes sense: the first head, which happens to be the tip of this repository, is the tip of the developer branch. The other head is the tip of hg:opensaf-staging. As you may have guessed, the hg merge command will merge the divergent heads:

~/opensaf/opensaf-staging$ hg merge
22 files updated, 0 files merged, 7 files removed, 0 files unresolved
(branch merge, don't forget to commit)

That was easy—no conflicts this time. Now, let's follow Mercurial's reminder and commit the new merge changeset:

~/opensaf/opensaf-staging$ hg commit -m "Merge changes from Hans Feldt's opensaf-uml branch"

Just to verify:

~/opensaf/opensaf-staging$ hg tip
changeset:   46:e04ad9ac167d
tag:         tip
parent:      28:061f43513e87
parent:      45:484fc21ccffe
user:        John Wright <john@johnwright.org>
date:        Mon Mar 10 20:47:14 2008 -0600
summary:     Merge changes from Hans Feldt's opensaf-uml branch

4.1.4 Pushing to hg:opensaf-staging

Now we push the repository, after taking another look at what we're actually sending up:

~/opensaf/opensaf-staging$ hg outgoing http://devel.opensaf.org/hg/opensaf-staging
comparing with http://devel.opensaf.org/hg/opensaf-staging
searching for changes
changeset:   29:2372d20f9445
parent:      25:6556b700c674
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Fri Feb 29 15:06:55 2008 +0100
summary:     Updated with latest versions of kernel & busybox. 64 bit support.

changeset:   30:a1a612fef365
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 09:39:44 2008 +0100
summary:     Added lib64 in root template

changeset:   31:7c91bc121b0d
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 09:41:27 2008 +0100
summary:     added mdev.conf in root template

changeset:   32:ed8bc706778d
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:14:03 2008 +0100
summary:     Changed from make system to batch script

changeset:   33:1708b7a0b970
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:18:29 2008 +0100
summary:     some missing files

changeset:   34:63d46a2b638e
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:21:02 2008 +0100
summary:     remove

changeset:   35:88031930b749
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 16:55:24 2008 +0100
summary:     fix

changeset:   36:8f434f6c5a3c
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 17:08:02 2008 +0100
summary:     added missing dir

changeset:   37:0c7f57042981
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 17:17:58 2008 +0100
summary:     robuster wgets

changeset:   38:1772ee36adc2
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 17:23:33 2008 +0100
summary:     robust wgets again

changeset:   39:9314051074ca
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 18:13:39 2008 +0100
summary:     Created new function and removed some

changeset:   40:a488737e0428
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Mon Mar 03 18:16:06 2008 +0100
summary:     removed sed of inittime

changeset:   41:e244cc59be54
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 14:08:06 2008 +0100
summary:     unused file removed, faster rde start, always rebuild root fs

changeset:   42:88ee2aff36d3
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 14:55:09 2008 +0100
summary:     Bad cleaning

changeset:   43:44942b5499f0
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 20:03:13 2008 +0100
summary:     extract gz and bz2 files differently

changeset:   44:e835f607f17d
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Thu Mar 06 21:35:24 2008 +0100
summary:     more cleaning

changeset:   45:484fc21ccffe
user:        Hans Feldt <hans.feldt@ericsson.com>
date:        Fri Mar 07 11:52:43 2008 +0100
summary:     use default NCSSystemBOM.xml

changeset:   46:e04ad9ac167d
tag:         tip
parent:      28:061f43513e87
parent:      45:484fc21ccffe
user:        John Wright <john@johnwright.org>
date:        Mon Mar 10 20:47:14 2008 -0600
summary:     Merge changes from Hans Feldt's opensaf-uml branch

~/opensaf/opensaf-staging$ hg push ssh://devel.opensaf.org//var/www/hg/opensaf-staging
pushing to ssh://devel.opensaf.org//var/www/hg/opensaf-staging
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 18 changesets with 44 changes to 27 files

Now, you should be able to verify that the changes exist on hg:opensaf-staging.

4.2 Creating a release

Typically, a developer who is not a maintainer (one who doesn't have write access to the master repository) should not perform these steps.

With each release of OpenSAF, for example, version 1.0.5, there is some associated changeset in the Mercurial repository. Mercurial stores this information in a file called .hgtags. Most of the time, you won't ever need to worry about this file—the tag command will create tags for you—but it occasionally shows up in merges.

To see a list of tags in a repository, issue the tags command:

~/opensaf/opensaf-merge$ hg tags
tip                                3:b67adc860aba
1.0.5                              0:1c7624641cfa

The tag for tip is special: it always points to the most recently added changeset. The 1.0.5 tag points to the changeset that matches the release of 1.0.5 of OpenSAF. Mercurial lets you refer to tags just like any other revision.

Suppose we want to release version 1.2.1, which contains the changes currently up to tip of the opensaf-staging repository. First, we need to update our copy of the repository:

~/opensaf/opensaf-staging$ hg pull
pulling from http://devel.opensaf.org/hg/opensaf-staging
searching for changes
adding changesets
adding manifests
adding file changes
added 32 changesets with 108 changes to 76 files
(run 'hg update' to get a working copy)
~/opensaf/opensaf-staging$ hg update
76 files updated, 0 files merged, 4 files removed, 0 files unresolved

We need to update the confgure.ac file to contain the new version:

~/opensaf/opensaf-staging$ sed -r -I -e 's/(AC_INIT..opensaf.,) [^,]*/\1 [1.2.1]/' configure.ac
~/opensaf/opensaf-staging$ hg diff
diff -r 6b0e67b08dba configure.ac
--- a/configure.ac      Wed Oct 14 07:04:41 2009 -0600
+++ b/configure.ac      Wed Oct 14 07:25:16 2009 -0600
@@ -15,7 +15,7 @@
 #

 AC_PREREQ([2.59])
-AC_INIT([opensaf], [1.1.0], [devel@list.opensaf.org])
+AC_INIT([opensaf], [1.2.1], [devel@list.opensaf.org])
 AC_CANONICAL_SYSTEM
 AC_CONFIG_SRCDIR([OpenSAFCopyRights])
 AC_CONFIG_HEADER([config.h])

~/opensaf/opensaf-staging$ hg commit \
    -m "Update configure.ac file for version 1.2.1"

Now, let's add the tag:

~/opensaf/opensaf-staging$ hg tag 1.2.1
~/opensaf/opensaf-staging$ hg tip -vp
changeset:   93:f22c0dbb9c1b
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Wed Jun 25 16:53:41 2008 -0600
files:       .hgtags
description:
Added tag 1.2.1 for changeset d3cdb58ef131


diff -r d3cdb58ef131 -r f22c0dbb9c1b .hgtags
--- a/.hgtags	Wed Jun 25 16:52:42 2008 -0600
+++ b/.hgtags	Wed Jun 25 16:53:41 2008 -0600
@@ -4,3 +4,4 @@
 7c21c38a8880a3444bc37471f798ab85b7a3616d 1.0.9
 3319e81bd954cfced21794c82c604002e62d9c49 1.1.0
 3319e81bd954cfced21794c82c604002e62d9c49 Release_2_FC
+d3cdb58ef1312a87b100f71ad678cf6a8400dcda 1.2.1

We can also add more "human readable" tags if we like, referring to the same changeset. For instance, if we want the changeset we just tagged as 1.2.1 to also be known as Release_2_RC1, we can do

~/opensaf/opensaf-staging$ hg tag -r 1.2.1 Release_2_RC1
~/opensaf/opensaf-staging$ hg tip -vp
changeset:   94:14da920916d3
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Wed Jun 25 16:54:25 2008 -0600
files:       .hgtags
description:
Added tag Release_2_RC1 for changeset d3cdb58ef131


diff -r f22c0dbb9c1b -r 14da920916d3 .hgtags
--- a/.hgtags	Wed Jun 25 16:53:41 2008 -0600
+++ b/.hgtags	Wed Jun 25 16:54:25 2008 -0600
@@ -5,3 +5,4 @@
 3319e81bd954cfced21794c82c604002e62d9c49 1.1.0
 3319e81bd954cfced21794c82c604002e62d9c49 Release_2_FC
 d3cdb58ef1312a87b100f71ad678cf6a8400dcda 1.2.1
+d3cdb58ef1312a87b100f71ad678cf6a8400dcda Release_2_RC1

(The -r option tells Mercurial to tag a particular revision, rather than tip. Note in the .hgtags file how the changeset ids before 1.2.1 and Release_2_RC1 are identical.)

Now, we need to push the changes up to the hg:opensaf-staging repository. To see what's about to be pushed:

~/opensaf/opensaf-staging$ hg outgoing \
    ssh://devel.opensaf.org//var/www/hg/opensaf-staging
comparing with ssh://devel.opensaf.org//var/www/hg/opensaf-staging
searching for changes
changeset:   92:d3cdb58ef131
tag:         Release_2_RC1
tag:         1.2.1
user:        John Wright <john.wright@hp.com>
date:        Wed Jun 25 16:52:42 2008 -0600
summary:     Update configure.ac spec files for version 1.2.1

changeset:   93:f22c0dbb9c1b
user:        John Wright <john.wright@hp.com>
date:        Wed Jun 25 16:53:41 2008 -0600
summary:     Added tag 1.2.1 for changeset d3cdb58ef131

changeset:   94:14da920916d3
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Wed Jun 25 16:54:25 2008 -0600
summary:     Added tag Release_2_RC1 for changeset d3cdb58ef131

To actually push, replace the outgoing command with push.

Now we can make a release tarball:

~/opensaf/opensaf-staging$ ./bootstrap.sh
~/opensaf/opensaf-staging$ ./configure
~/opensaf/opensaf-staging$ make dist
~/opensaf/opensaf-staging$ tar ztvf opensaf-1.2.1.tar.gz | head
-rw-r--r-- user/group       94 2008-06-25 16:52 opensaf-1.2.1/.hg_archival.txt
-rw-r--r-- user/group      289 2008-06-25 16:52 opensaf-1.2.1/.hgtags
-rw-r--r-- user/group        0 2008-06-25 16:52 opensaf-1.2.1/AUTHORS
-rw-r--r-- user/group    26250 2008-06-25 16:52 opensaf-1.2.1/COPYING
-rw-r--r-- user/group     6965 2008-06-25 16:52 opensaf-1.2.1/ChangeLog
-rw-r--r-- user/group    35224 2008-06-25 16:52 opensaf-1.2.1/INSTALL
-rw-r--r-- user/group     2750 2008-06-25 16:52 opensaf-1.2.1/Makefile.am
-rw-r--r-- user/group        0 2008-06-25 16:52 opensaf-1.2.1/NEWS
-rw-r--r-- user/group     8990 2008-06-25 16:52 opensaf-1.2.1/README
-rwxr-xr-x user/group       31 2008-06-25 16:52 opensaf-1.2.1/bootstrap.sh

That tarball needs to be uploaded to bohr.linux.hp.com, which hosts download.opensaf.org:

~/opensaf/opensaf-staging$ scp ../opensaf-1.2.1.tar.gz \
    devel.opensaf.org:/var/www/download.opensaf.org/releases

Now, once the changes make their way into the master hg:opensaf repository (soon, this will be automatic; for now, I manually update it about once a day, and I'll send you an email if there are new tags), don't forget to update the downloads page.

4.3 Checking out a previous release or revision

Sometimes it is useful to check out a previous revison in your current repository. (This is especially important with the hg bisect command—please see  Chapter 9, Section 5 of Distributed revision control with Mercurial.) We've seen the hg update command before—but it can be used to check out any revision, not only the tip. So, back in our opensaf-merge repository, we can check out the revision with the 1.0.5 tag:

~/opensaf/opensaf-merge$ hg update 1.0.5
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
~/opensaf/opensaf-merge$ ls
AUTHORS       config        include  Makefile.am  README   scripts
bootstrap.sh  configure.ac  INSTALL  mibs         rpms     services
ChangeLog     COPYING       lib      NEWS         samples  tools

The update command works with any changeset identifier: you can give it a revision number (not generally recommended, since the revision number for a particular changeset will vary between repositories), a hexadecimal identifier, or a tag.

4.4 Making updates to a previous release

If a bug is found in an earlier release of OpenSAF, and the decision is made to update that version with only the bug fix (so that users need not upgrade to the latest version with many other changes), we will use a clone of the master repository made at the tag for that release. Typically, this should be created at the release time (see the end of section on creating a release).

For a contrived example, suppose there was a missing file in the 1.0.5 release. First, let's clone the opensaf-1.0.5 repository:

~/opensaf$ hg clone http://devel.opensaf.org/hg/opensaf-1.0.5 \
    opensaf-1.0.5-bugfix
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 2366 changes to 2366 files
2366 files updated, 0 files merged, 0 files removed, 0 files unresolved
~/opensaf$ cd opensaf-1.0.5-bugfix

Now, let's make the required fix:

~/opensaf/opensaf-1.0.5-bugfix$ echo baz > bar
~/opensaf/opensaf-1.0.5-bugfix$ hg add bar
~/opensaf/opensaf-1.0.5-bugfix$ hg commit -m 'Add a missing file, bar'
~/opensaf/opensaf-1.0.5-bugfix$ hg tip -vp
changeset:   1:f391fb3ea67d
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:21:07 2008 -0700
files:       bar
description:
Add a missing file, bar


diff -r 1c7624641cfa -r f391fb3ea67d bar
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/bar       Mon Jan 07 15:21:07 2008 -0700
@@ -0,0 +1,1 @@
+baz

Now, we publish our changes somewhere that a maintainer can pick them up:

~/opensaf/opensaf-1.0.5-bugfix$ ssh devel.opensaf.org hg clone -U \
    /var/www/hg/opensaf-1.0.5 public_html/hg/opensaf-1.0.5-bugfix
~/opensaf/opensaf-1.0.5-bugfix$ hg push \
    ssh://devel.opensaf.org/public_html/hg/opensaf-1.0.5-bugfix
pushing to ssh://devel.opensaf.org/public_html/hg/opensaf-1.0.5-bugfix
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files

(If a change has happened on the opensaf-1.0.5 master repository between when you originally clone and when you push, Mercurial will complain and force you to pull and merge before pushing. Some documentation about that should go here—for now, please see  Chapter 3 of Distributed revision control with Mercurial.) The repository is now available at http://devel.opensaf.org/~jswright/hg/opensaf-1.0.5-bugfix. (You can refer to this repository anywhere in Trac by using hg:/~jswright:opensaf-1.0.5-bugfix.)

4.5 Updating the master repository for a release branch

This section is intended for maintainers with write access to the master repository for a particular release branch, but the bits about merging should be useful to anybody who wishes to pull changes from other published repositories.

Suppose we wish to merge in the changes from hg:/~jswright:opensaf-1.0.5-bugfix to the hg:opensaf-1.0.5 master repository. First, let's clone the master repository:

~/opensaf$ hg clone http://devel.opensaf.org/hg/opensaf-1.0.5
destination directory: opensaf-1.0.5
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 2366 changes to 2366 files
2366 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now, let's clone that repository to get a temporary repository for merging in the new changes:

~/opensaf$ hg clone opensaf-1.0.5 opensaf-1.0.5-merge
2366 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now, we can pull the new changes:

~/opensaf$ cd opensaf-1.0.5-merge
~/opensaf/opensaf-1.0.5-merge$ hg incoming -vp \
    http://devel.opensaf.org/~jswright/hg/opensaf-1.0.5-bugfix
comparing with http://devel.opensaf.org/~jswright/hg/opensaf-1.0.5-bugfix
searching for changes
changeset:   1:f391fb3ea67d
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:21:07 2008 -0700
files:       bar
description:
Add a missing file, bar


diff -r 1c7624641cfa -r f391fb3ea67d bar
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/bar       Mon Jan 07 15:21:07 2008 -0700
@@ -0,0 +1,1 @@
+baz

~/opensaf/opensaf-1.0.5-merge$ hg pull -u \
    http://devel.opensaf.org/~jswright/hg/opensaf-1.0.5-bugfix
pulling from http://devel.opensaf.org/~jswright/hg/opensaf-1.0.5-bugfix
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
~/opensaf/opensaf-1.0.5-merge$ hg tip
changeset:   1:f391fb3ea67d
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:21:07 2008 -0700
summary:     Add a missing file, bar

Now, we would push the changes to the master repository:

~/opensaf/opensaf-1.0.5-merge$ hg push \
    ssh://devel.opensaf.org//var/www/hg/opensaf-1.0.5

I'm not showing the output, because I didn't actually run this command (these particular changes shouldn't really go there). For now, let's just push to our original clone of hg:opensaf-1.0.5, and update its working copy:

~/opensaf/opensaf-1.0.5-merge$ hg push ../opensaf-1.0.5
pushing to ../opensaf-1.0.5
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
~/opensaf/opensaf-1.0.5-merge$ cd ../opensaf-1.0.5
~/opensaf/opensaf-1.0.5$ hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

4.6 Making an update release

This section is intended for maintainers with write access to the master repository for a particular release branch.

Suppose we are ready to create a 1.0.5.1 release of OpenSAF, using the tip of the hg:opensaf-1.0.5 repository. First, let's update our local clone of hg:opensaf-1.0.5:

~/opensaf/opensaf-1.0.5$ hg pull -u
pulling from http://devel.opensaf.org/hg/opensaf-1.0.5
searching for changes
no changes found

There were no changes this time, but it is always a good idea to make sure you have the latest updates before making a release.

Now, we need to make a tag for our new release:

~/opensaf/opensaf-1.0.5$ hg tag 1.0.5.1
~/opensaf/opensaf-1.0.5$ hg tip
changeset:   2:4653c22303e8
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:38:59 2008 -0700
summary:     Added tag 1.0.5.1 for changeset f391fb3ea67d

Normally, we would push these changes:

~/opensaf/opensaf-1.0.5$ hg push \
    ssh://devel.opensaf.org//var/www/hg/opensaf-1.0.5

Now we can create a tarball for the release:

~/opensaf/opensaf-1.0.5$ hg archive -t tgz -r 1.0.5.1 \
    ../opensaf-1.0.5.1.tar.gz

4.7 Forward-porting changes in release branches

Often, a bug in an older release will also apply to the current development branch. Typically, we'll merge any changes in the release branches into the main repository. Let's update our clone of the hg:opensaf repository:

~/opensaf/opensaf$ hg pull -u
pulling from http://devel.opensaf.org/hg/opensaf
searching for changes
no changes found

Now, let's make a clone for merging in the 1.0.5 fixes:

~/opensaf/opensaf$ cd ..
~/opensaf$ hg clone opensaf opensaf+1.0.5-updates
2368 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now, we can pull in the changes from the hg:opensaf-1.0.5 repository. In practice, the URL for this will be http://devel.opensaf.org/hg/opensaf-1.0.5; for now, we'll pull in from our local opensaf-1.0.5 repository, since I didn't actually push these changes to the master repository.

~/opensaf$ cd opensaf+1.0.5-updates/
~/opensaf/opensaf+1.0.5-updates$ hg pull ../opensaf-1.0.5
pulling from ../opensaf-1.0.5
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
~/opensaf/opensaf+1.0.5-updates$ hg heads
changeset:   6:4653c22303e8
tag:         tip
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:38:59 2008 -0700
summary:     Added tag 1.0.5.1 for changeset f391fb3ea67d

changeset:   4:73e6fd9f4e53
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:05:56 2008 -0700
summary:     Added tag 1.0.6 for changeset b67adc860aba

There are two heads (changesets without any children) in the new repository. We need to merge them.

~/opensaf/opensaf+1.0.5-updates$ hg merge
merging .hgtags
conflicts detected in /home/jswright.local/opensaf/opensaf+1.0.5-updates/.hgtags

Now, Mercurial opens an editor to resolve the merge conflict. The editor has the following text in it:

<<<<<<< /home/jswright.local/opensaf/opensaf+1.0.5-updates/.hgtags.orig.2484129268
1c7624641cfa9ab65635326316add7d72516f759 1.0.5
b67adc860abad8819f415abd5a8de8fcb425b306 1.0.6
||||||| /tmp/.hgtags~base.WBTtag
=======
f391fb3ea67d8dcfd8e371ed22009ead4834480b 1.0.5.1
>>>>>>> /tmp/.hgtags~other.-mJNN1

We'll want all the tags visible, so let's just remove all the conflict markers and leave all the lines intact:

1c7624641cfa9ab65635326316add7d72516f759 1.0.5
b67adc860abad8819f415abd5a8de8fcb425b306 1.0.6
f391fb3ea67d8dcfd8e371ed22009ead4834480b 1.0.5.1

After saving the file and exiting the editor, Mercurial gives us a little more information:

1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

It reminds us that merges aren't automatically committed. It's a good idea now to run hg diff to see what changed:

~/opensaf/opensaf+1.0.5-updates$ hg diff
diff -r 73e6fd9f4e53 .hgtags
--- a/.hgtags   Mon Jan 07 15:05:56 2008 -0700
+++ b/.hgtags   Mon Jan 07 15:45:12 2008 -0700
@@ -1,2 +1,3 @@ 1c7624641cfa9ab65635326316add7d72516f759
 1c7624641cfa9ab65635326316add7d72516f759 1.0.5
 b67adc860abad8819f415abd5a8de8fcb425b306 1.0.6
+f391fb3ea67d8dcfd8e371ed22009ead4834480b 1.0.5.1
diff -r 73e6fd9f4e53 bar
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/bar       Mon Jan 07 15:45:12 2008 -0700
@@ -0,0 +1,1 @@
+baz

Everything looks good—we see just the added tag and the new bar file. Now we can commit:

~/opensaf/opensaf+1.0.5-updates$ hg commit -m \
    "Merge changes from the 1.0.5 branch"
~/opensaf/opensaf+1.0.5-updates$ hg tip
changeset:   7:7be895547eac
tag:         tip
parent:      4:73e6fd9f4e53
parent:      6:4653c22303e8
user:        John Wright <john.wright@hp.com>
date:        Mon Jan 07 15:45:48 2008 -0700
summary:     Merge changes from the 1.0.5 branch

Normally, we'd now push these changes to the master hg:opensaf repository:

~/opensaf/opensaf+1.0.5-updates$ hg push \
    ssh://devel.opensaf.org//var/www/hg/opensaf

Since these are contrived changes, I'll just push them to my copy of the opensaf repository:

~/opensaf/opensaf+1.0.5-updates$ hg push ../opensaf
pushing to ../opensaf
searching for changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 3 changes to 2 files

For more information on merging, please read  Chapter 3 of Distributed revision control with Mercurial.

5 Closing words

This document is a work in progress. There is much that needs to be added about working with Trac, and the existing Mercurial parts could use better examples. If you have any suggestions, please send email to me at john.wright@…. Or, now that it's on the wiki, you can make changes yourself!

Last modified by mathi, 06/28/12 02:17:06 (22 months ago)