Introduction
The previous chapter described how to use the various parts of the FCM
code management system. They also described aspects of working practices
which are enforced by the system. This section discusses other recommended
working practices. 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 practices to adopt (although we expect most projects/systems
using FCM to adopt similar practices).
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:
- Before work starts on any coding you should make sure that there is a
Trac ticket open which explains the purpose of the change.
- Make sure that you set the ticket milestone to indicate which
release of the system you are aiming to include your change in.
- Accept the ticket to indicate that you are working on the
change.
- For further advice on using tickets see Trac
Tickets later in this section.
- Create a branch
- For very simple changes you may be happy to prepare your changes
directly on the trunk. For further details see When to Branch later in this section.
- Create your branch either from the latest revision or from a stable
release (see Where to Branch From later
in this section).
- Prepare your code changes on the branch
- Commit interim versions to your branch on a regular basis as you
develop your change. This makes it much easier to keep track of what
you're changing and to revert changes if necessary.
- You may wish to merge in changes from the trunk. For further
details see Merging From the Trunk
later in this section.
- Make sure that you always commit any local changes to your
branch before doing a merge. Otherwise it becomes impossible to
distinguish your changes from those you have merged in. It is also
impossible to revert the merge without losing your local
changes.
- Likewise, always commit the merge to your branch (after
resolving any conflicts) before making any further changes.
- Don't include unrelated changes. If you want to make some changes
which aren't really associated with your other changes then use a
separate ticket and branch for these changes.
- Once your changes are ready for review, update the Trac ticket to
record which revision of the branch is to be reviewed and assign the ticket
to your reviewer.
- 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.
- The reviewer can use the command
fcm branch-diff
<branch_name> to examine all of the changes on the
branch.
- If changes are necessary then these should be prepared and then the
ticket updated to refer to the new revision under review.
- Once the change is approved it can be merged back to the trunk
- If you have been merging the latest changes from the trunk onto
your branch then the merge should be automatic. If not you may have
conflicts to resolve.
- Make sure that each merge is a separate commit to the trunk. i.e.
Don't combine changes from several branches in one commit. This makes
it easier to reverse changes if necessary. It also makes the changeset
easier to understand.
- Make sure that you use a good log message to describe your change.
For further details see Commit Log Messages
later in this section.
- Once the changes are commited, update the ticket to refer to the
changeset. Then the ticket can be closed.
- Once you are finished with the branch it should be deleted.
Working Copies
Some points to consider regarding working copies:
- 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.
- If you have a large project then you may prefer to work on a sub-tree
of your project.
Pros:
- Subversion operations on your working copy are faster.
- Your working copies use up less disk space. Remember that you may
be working on several changes at once on separate branches so you may
wish to have several working copies.
Cons:
- You cannot always perform merge operations in sub-trees (if the
changes which need to be merged include files outside of your
sub-tree). To handle this we suggest that if you need to perform a
merge using a complete copy of your project you check it out in your
$LOCALDATA area (local disk space which is not backed up) to
be used purely for doing the merge.
- You may find that your change involves more files than you
originally thought and that some of the files to be changed lie outside
of your working copy. You then have to make sure that you have
committed any changes before checking out a larger working copy.
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.
- You can commit intermediate versions to the branch.
- If you need to merge in changes from the trunk then you have a record
of your files prior to the merge.
- The version of the code which gets reviewed is recorded. If subsequent
changes are required then only those changes will need reviewing.
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:
- Always Branch
-
ALL coding changes are prepared on branches.
Pros: Same process is followed in all cases.
Cons: The extra work required to create the branch and
merge it back to the trunk may seem unnecessary for a very small
change.
- Branch When Needed
-
Small changes can be committed directly to the trunk (after testing
and code review).
Pros: Avoids the overhead of using branches.
Cons: Danger of underestimating the size of a change. What
you thought was a small change may turn out to be larger than you thought
(although you can always move it onto a branch if this happens).
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:
- The latest revision of the trunk
-
This is the preferred choice where possible. It minimised the chances
of conflicts when you need to incorporate your changes back onto the
trunk.
- An older revision of the trunk
-
There are a number of reasons why you may need to do this. For
example:
- You are using a stable version to act as your control
data.
- You need to know that your baseline is well tested (e.g. scientific
changes).
- Your change may need to be merged with other changes relative to a
stable version for testing purposes or for use in a package (see
Creating Packages later in this section).
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.
- Regularly merging from the trunk minimises the work involved when you
are ready to merge back to the trunk. You deal with any merge issues as you
go along rather than all at the end (by which time your branch and the
trunk could have diverged significantly).
- One downside of merging from the trunk is that the baseline for your
changes is a moving target. This may not be what you want if you have some
control results that you have generated.
- Another downside of merging from the trunk is that it may introduce
bugs. Although any code on the trunk should have been tested and reviewed
it is unlikely to be as well tested as code from a stable release.
- Unless you originally created your branch from the latest revision of
the trunk it is unlikely that you are going to want to merge in changes
from the trunk. The exception to this is once your change is complete when
it may make sense to merge all the changes on the trunk into your branch as
a final step. This is discussed in Merging Back
to the Trunk below.
So, there are basically three methods of working:
- Branch from a stable version and prepare all your changes in
isolation
- Necessary if you need to make your change relative to a well tested
release.
- Branch from the latest code but then prepare all your changes in
isolation
- Necessary if you need a stable baseline for your control
data.
- Branch from the latest code and then update your branch from the trunk
on a regular basis
- This is considered best practice for parallel working and
should be used where possible.
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:
- Test and review your changes in isolation, then merge to the trunk and
deal with any conflicts
-
This may be the best method if:
- Your changes have already been tested against a stable baseline and
re-testing after merging would be impracticable.
- Your branch needs to be available for others to merge in its
changes in isolation.
- 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:
- Use locking to prevent it happening. The danger with this is that
you may prevent others from being able to get their change tested and
reviewed, hence inhibiting parallel devlopment.
- Insist that th