Externals are a very powerful feature of Subversion, but they can cause issues if not used properly. The following sections describe best practices for ensuring that you get the most out of this feature.
Subversion allows source URLs to be specified in a number of different formats:
See URL Formats for more information on these various URL formats.
If you are referencing a dependency located in the same repository as the project declaring the external then we recommend that you use either the folder-relative or repository-relative syntax. Doing so will prevent your external from breaking when your repository is moved to a different server or you switch to a different protocol (e.g. from HTTP to HTTPS).
Whether you use folder-relative or repository-relative URLs is up to you. If your project and its dependencies are tightly coupled and are located in the same subtree of your repository then a folder-relative URL might be appropriate. If your dependencies are only loosely related to your project (and their respective locations may change independent of one another) then we recommend using repository-relative URLs.
If a revision is not specified as part of an external definition then Subversion will automatically pull in the latest version of the referenced folder whenever a working copy is checked out, updated or switched. This can have unintended side effects such as:
Required files may be removed from the external dependency causing compiler or linker errors.
Class, method or function names may be changed causing unexpected compilation errors.
Changes to the external dependency may cause subtle behavioral changes that introduce unwanted bugs and other side effects.
The referenced folder may be renamed or moved thereby causing check out, update and switch operations to fail.
To avoid such issues we recommend that you always set your externals to reference specific revisions and only update to newer revisions when you are aware of the changes associated with those versions.
Subversion allows both operative and peg revisions to be used to specify revisions in external definitions.
For example, both:
-r14990 ^/libpng/trunk deps/libpng
and
^/libpng/trunk@14990 deps/libpng
specify that revision 14,990 of /libpng/trunk
should be checked out as deps/libpng
. However, there is a subtle difference in how Subversion will locate /libpng/trunk
in the repository.
In the first version, the revision (-r14990
) is specified as an operative revision. As a result, Subversion will look for /libpng/trunk
in the repository’s HEAD revision and then check out revision 14,990 of that item.
By contrast, in the second version, the revision (@14990
) is specified as a peg revision. This specifies to Subversion to look for /libpng/trunk
in revision 14,900 and check out that version of the item.
The difference is subtle, but important. For example, if the revision is specified as an operative revision and /libpng/trunk
is moved to /libs/libpng/trunk
at some point after revision 14,900 then Subversion will no longer find /libpng/trunk
in the repository’s HEAD revision and the external will be broken. However, the peg revision continues to work because /libpng/trunk
continues to exist in revision 14,900 regardless of its current location in the repository’s HEAD revision.
Peg revisions are inherently robuster than operative revisions and are the best choice for use with external definitions.
Subversion will only let you commit changes to a folder’s property if the folder is up-to-date with the repository. Attempting to commit a property change on a folder that is out of date results in an error. This can be avoided by updating the folder before editing its svn:externals
.
Note that it is not necessary to update both the folder and its contents. Instead, you only need to update the folder itself:
svn:externals
property in the working copy browser or source list.Always update the folder that declares the property before editing its svn:externals
. This will also avoid unnecessary conflicts.