This document describes how projects configured under FCM can be distributed externally. Particular attention is given to collaborative distributions - where the external user regularly returns code for consolidation into the central repositories which hold the master copies of the code.
Note: This document assumes that the repositories are inaccessible to the external user, due to issues of security and practicality.
A system configured under FCM can be distributed by packaging a known revision (usually corresponding to a stable release) into an archive (e.g. a tarball) of directories and files. Various issues need to be considered:
Although we would encourage all collaborators to make use of the FCM system for version control, we recognise that they may already have their own preferred systems in place. There is no particular problem with this. The main requirement is that any proposed changes are provided as a modification relative to the provided distribution. The changeset could be provided in the form of a modified project tree or as a patchfile (refer to the later section Exchanging Changesets using Patchfiles for further discussion). If the change involves any renaming or removal of files or directories then special instructions should be provided plus a script to perform the changes.
At the central repository, the changeset should be applied to a branch created from the repository revision which formed the basis of the changeset (possibly making use of the Subversion utility svn_load_dirs.pl). Note that extra care is needed with changesets provided as modified project trees if there are any files in the project which are excluded from the distribution. Once imported, the changeset should then undergo any necessary testing or review before being merged into the trunk.
There are a number of advantages if the FCM system is used for version control by the collaborator. In particular it means that:
This section explains the recommended way of using FCM in a collaboration.
The collaborator needs to set up a repository and import each of the projects. Please see the section Creating a repository in the FCM user guide for advice. Collaborators may wish to use separate repositories and Trac systems for each project or they may prefer to use a single repository for all projects and use a single Trac system. Either option should be fine so long as the same set of projects is retained.
After completing the initial import, the collaborator should have the required set of projects available in Subversion where the initial version of the trunk of each project corresponds with the initial stable release provided in the distribution.
The recommended way of preparing changes is illustrated in Figure 1a:
Figure 1a: working at the collaborator's site
The collaborator will create a shared package branch from the latest stable release on the trunk. This branch will contain all the changes that will eventually be fed back to the central repository. Developers will also create their own development branches. These may be branched from the latest stable release on the trunk. Alternatively, if the change needs to build on other changes then a branch can be created from the shared package branch. When the changes are ready (i.e. tested, documented, reviewed, etc) then they are merged into the shared package branch. The trunk is not used for the shared changes as it is reserved for changes received from the central repository.
Should it be required, a second shared package branch can be created from the same point to contain any local modifications that will not be fed back to the central repository. A configuration branch can then be used to combine the local changes with those destined to be fed back. This is illustrated in Figure 1b:
Figure 1b: managing local changes
Eventually, a series of changesets will exist on the first package branch.
These changes will be fed back to the central repository via an FCM
patch. This contains a series of differences associated with changesets
in a given branch of development, created by the fcm mkpatch
command. For further information about the command, please refer to its
command
reference in the FCM user guide.
At the central repository, the changeset will be applied to a branch created from the repository revision which formed the basis of the changeset. This is illustrated in Figure 2:
Figure 2: feeding back changes
Patches will usually be exchanged in the form of a tarball. To apply the
patch it must first be extracted to a directory. In this directory there
should be a shell script called fcm-import-patch
. A TARGET needs
to be specified when invoking the script. The TARGET must either be a URL or
a working copy of a valid project tree that can accept the import of the
patches. It is essential that this target matches the version of the project
from which the patch was created (usually this means a particular stable
release). The script contains a series of cp
and
svn
commands to import the changesets one by one. Note that the
changesets are committed automatically with no user interaction. It is worth
ensuring that an up to date backup of the repository is available in case of
problems.
Once the changes have undergone any necessary testing or review they can be merged into the trunk. There are three ways of approaching this:
Figure 3a: merging a patch in a single changeset
Figure 3b: merging a patch in multiple changesets
Once a new stable release is available it will be supplied in the form of a distribution tarball as described earlier. However, collaborators will also be supplied with an FCM patch (as described earlier) for each project containing all the changes made since the previous stable release. Note that this assumes that stable releases are prepared on the trunk and not in branches.
Each patch should be applied to the trunk of the collaborator's repository. This means that the collaborator's trunk will always be mirroring that of the central repository. This is illustrated in Figure 4:
Figure 4: mirroring the trunk at the collaborator's site
In order to be certain that the patch has worked correctly, we recommend that a check is performed to ensure that the new stable release on the trunk matches the files provided in the distribution (preferably using a copy of the repository for testing purposes before applying the patch to the live repository).
Old branches that are still active at the collaborators site should be updated to the latest stable release when it becomes available. Developers should create a new branch from the latest stable release and then merge the changes from the old branch to the new branch. The old branch should be deleted once it is no longer required. This is illustrated in Figure 5a:
Figure 5a: updating a branch to the latest stable release
Note that the merge will be easiest if the old branch was created from the previous stable release. If it was created from the shared package branch then a custom merge will be required to achieve the desired result (a normal FCM merge command would choose the wrong base for comparison). This is illustrated in Figure 5b:
Figure 5b: updating a branch of the shared package branch
The previous sections have only considered how developments on the trunk of a central repository can be shared with a single collaborator. However, the same techniques can be applied to more complex situations.
We have described the branching strategy we believe will work best for collaborators. However, this is by no means the only branching strategy that can be used. In particular, some collaborators may prefer to keep the latest copies of the code they are using on the trunk. This effectively means getting rid of the shared package branches for shared and local changes and merging all changes on to the trunk. A separate branch would be used for keeping a pristine copy of the main site and merging changes from new stable builds on to the trunk.
This approach is certainly possible and has the advantage that developers at the collaborator's site may find it easier to work with. However there are two disadvantages that need to be considered:
In some cases, an FCM patch may not be the best way of exchanging
changesets. For instance, when distributing code changes which have not yet
been finalised, you probably wouldn't want to send a patch containing all the
individual commits to the branch on which the change is being developed. What
you want is a summary of the changes in a single changeset. In this case you
will often be better to use a patchfile (which can be applied using the Unix
command patch
). A patchfile is simply the output from an
fcm diff
command. For example:
fcm diff --branch fcm:myproj-br/dev/frdm/r2134_my_branch > my_patchfile
The patchfile must be applied to a working copy of the project which
corresponds to the same revision from which the patchfile was generated. The
option -p0
must be used with the patch
command. For
example:
patch -p0 < my_patchfile
Patchfiles have the advantage that they are simple to generate and exchange and that they can combine the changes from a number of changsets into one. However, they have a number of limitations such as:
Fortunately these limitations will not be an issue for the majority of changes and, where they are a problem, there are various options such as providing additional instructions with the patchfile, using an FCM patch, or exchanging a modified project tree.
The previous sections have only considered the version control aspects of a collaboration. This section lists some other aspects of the collaboration which will need to be considered.