FCM System User Guide > Code Management Working Practices

Code Management Working Practices

The previous chapter described how to use the various parts of the FCM code management system. They also described aspects of working practises which are enforced by the system. This section discusses other recommended working practises. They are optional in the sense that you don't have to follow them to use FCM. It is a matter for individual projects to decide which working practises to adopt (although we expect most projects/systems at the Met Office to adopt similar practises).

Making Changes

This sub-section gives an overview of the recommended approach for preparing changes. Particular topics are discussed in more detail in later sub-sections where appropriate.

The recommended process for making a change is as follows:

  1. Before work starts on any coding you should make sure that there is a Trac ticket open which explains the purpose of the change.
  2. Create a branch
  3. Prepare your code changes on the branch
  4. Once your changes are ready for review, update the Trac ticket to record which version of the branch is to be reviewed and assign the ticket to your reviewer.
  5. If the reviewer is happy with the change then he/she should update the ticket to record that the change is approved and assign the ticket back to you.
  6. Once the change is approved it can be merged back to the trunk
  7. Once you are finished with the branch it should be deleted.

Working Copies

Some points to consider regarding working copies:
  1. In general we recommend that you keep your working copies in your home directory. This ensures that any local changes which you accidently delete can be recovered via the snapshot facility (on Met Office Exeter and Reading based systems).
  2. If the size of your project is small then you will probably find it easiest to work with a complete copy of the project (either the trunk or your branch). This means that you always have immediate access to all the files and that you are always able to perform merges using your normal working copy.
  3. If you have a large project then you may prefer to work on a sub-tree of your project.

Branching & Merging

When to Branch

If you are making a reasonably large change which will take more than a hour or two to prepare then there are clear advantages to doing this work on a branch.

However, if you are only making a small change (maybe only one line) should you create a branch for this? There are two possible approaches:

  1. The Always Branch system
  2. The Branch When Needed system

This is a matter for project policy although, in general, we would recommend the Branch When Needed approach.

Where to Branch From

When you create a new branch you have two choices for which revision to create the branch from:

  1. The latest version of the trunk.
  2. An older version of the trunk. There are a number of reasons why you may need to do this. For example:

Merging From the Trunk

Once you've created your branch you need to decide whether you now work in isolation or whether you periodically merge in the latest changes from the trunk.

So, there are basically three methods of working:

  1. Branch from a stable version and prepare all your changes in isolation.
  2. Branch from the latest code but then prepare all your changes in isolation.
  3. Branch from the latest code and then update your branch from the trunk on a regular basis.

Merging Back to the Trunk

Before merging your change back to the trunk you will need to test your change and get it reviewed. There are two options for what code to test and review:

  1. Test and review your changes in isolation. Then merge to the trunk and deal with any conflicts at this stage. This may be the best method if:
  2. Merge in the latest code from the trunk before your final test and review. This has the advantage that you are testing and reviewing the actual code which will be committed to the trunk. However, it is possible that other changes could get committed to the trunk whilst you are completing your testing and review. There are several ways of dealing with this: You should also consider what can be done to minimise the time taken for testing and review.

Most projects will require the developer who prepared the change to merge it back to the trunk once it is complete. However, larger projects may wish to consider restricting this to a number of experienced / trusted developers.

When to Delete Branches

Once you are finished with your branch it is best to delete it to avoid cluttering up the directory tree (remember that the branch and all its history will still be available). There are two obvious approaches to deleting branches.

  1. Delete the branch as soon as it has been merged back to the trunk (prior to closing any associated Trac ticket).
  2. Delete the branch once a stable version of the system has been released which incorporates your change.

Working with Binary Files

The fcm conflicts command and xxdiff can only help you resolve conflicts in text files. If you have binary files in your repository you need to consider whether conflicts in these files would cause a problem.

Resolving Conflicts in Binary Files

Conflicts in some types of binary files can be resolved manually. When you are satisfied that the conflicts are resolved, issue the fcm resolved command on the file to remove the conflict status. (You will be prevented from committing if you have a conflicting file in your working copy.)

If you have a conflicting MS Office 2003 document, you may be able to take advantage of the "Compare and Merge Documents" facility under the "Tools" menu in a MS Office application. Consider a working copy, which you have just updated from revision 100 to revision 101, and someone else has committed some changes to a file doument.doc you are editing, you will get:

Conflicts in a binary file
(SHELL PROMPT)$ fcm conflicts
Conflicts in file: document.doc
document.doc: ignoring binary file, please resolve conflicts manually.
(SHELL PROMPT)$ fcm status
=> svn st
?      document.doc.r100
?      document.doc.r101
C      document.doc

Open document.doc.r101 with MS Word. In Tools > Compare and Merge Documents..., open document.doc. You will be in Track Changes mode automatically. Go through the document to accept, reject or merge any changes. Save the document and exit MS Word when you are ready. Finally, issue the fcm resolved command to remove the conflict status:

Resolved conflicts in a binary file
(SHELL PROMPT)$ fcm resolved document.doc
=> svn resolved document.doc
Resolved conflicted state of 'document.doc'
(SHELL PROMPT)$ fcm status
=> svn st
M      document.doc

Another type of conflict that you may be able to resolve manually is where the binary file is generated from another file which can be merged. For instance, some people who use LaTeX also store a PDF version of the document in the repository. In such cases it is easy to resolve the conflict by re-generating the PDF file from the merged LaTeX file and then issuing the fcm resolved command to remove the conflict status. Note that, in this particular case, a better approach might be to automate the generation of the PDF file outside of the repository.

Using Locking

For files with binary formats, such as artwork or sound, it is often impossible to merge conflicting changes. In these situations, it is necessary for users to take strict turns when changing the file in order to prevent time wasted on changes that are ultimately discarded.

Subversion supports locking to allow you to prevent other users from modifying a file while you are preparing changes. For details please refer to the chapter Locking from the Subversion book. Note that:

Commit Log Messages

Certain guidelines should be adhered to when writing log messages for code changes when committing to the trunk:

There are two possible approaches to recording the changes to individual files:

  1. Maintain history entries in file headers.
  2. Record which files have changed in the commit log message.

When you're committing to your own branch then you can be much more relaxed about log messages. Use whatever level of detail you find helpful. However, if you follow similar guidelines then this will help when it comes to preparing the log message when your change is merged back to the trunk.

Trac Tickets

Creating Tickets

There are two different approaches to using the issue tracker within Trac:

  1. All problems should be reported using Trac tickets.
  2. A Trac ticket shouldn't be created until the issue has been agreed.

Using Tickets

This sub-section provides advice on the best way of using tickets:

  1. In general, mature systems will require that there is a Trac ticket related to every changeset made to the trunk. However this doesn't mean that there should be a separate ticket for each change.
  2. Whenever you refer to source files/directories in tickets, make sure that you refer to particular versions of the files. This ensures that the links will work in the future, even if those files are no longer in the latest version. For example:
    Changes now ready for review: source:/OPS/branches/dev/frdm/r123_MyBranch@234
  3. For some types of information, simply appending to the ticket may not be the best way of working. For example, design notes or test results may be best recorded elsewhere, preferably in a wiki page. If using wiki pages we recommend using a naming convention to identify the wiki page with the associated ticket, for example:
    Please refer to [wiki:ticket/123/Design design notes]
    See separate [wiki:ticket/123/TestResults test results]
    Note that the square brackets have to be used since a page name containing numbers is not recognised automatically.

Creating Packages

Sometimes you may need to combine the changes from several different branches. For example:

We refer to this as creating a package.

To create a package you simply create a new branch as normal. The type should be a package or possibly a configuration branch to help you distinguish it from your other branches. You then simply merge in all of the branches that you want to combine using fcm merge.

The fcm branch --info command is very useful for maintaining packages. It tells you all of the branches which have been merged into your package and whether there are any more recent changes on those branches.

Preparing System Releases

There are two ways of preparing system releases:
  1. A system release is simply a particular version of the trunk. In order to do this it will be necessary to restrict changes on the trunk whilst the release is being prepared.
  2. Create a release branch where the release is finalised.

Rapid vs Staged Development Practises

Most of this section on working practises has focussed on projects/systems which are quite mature. Such systems are likely to have regular releases and will, for example, insist that all changes to the trunk are reviewed and tested.

If your system is still undergoing rapid development and has not yet reached any sort of formal release then you will probably want to adopt a much more relaxed set of working practises. For example:

We have tried to avoid building too many assumptions about working practises into the FCM system. This gives projects the flexibility to decide which working practises are appropriate for their system. Hopefully this means that FCM can be used for large or small systems and for rapidly evolving or very stable systems.