Using svn:externals to Pin Shared Libraries in Subversion
Learn how to use Subversion's svn:externals property to automatically check out shared libraries at a fixed revision, ensuring reproducible builds while keeping the dependency declaration versioned.
04 Aug 2026, 05:18 UTC

Problem: Keeping a shared library in sync across multiple projects
When several Subversion projects rely on the same utility code, manually copying the library into each working copy leads to drift and extra maintenance. Teams need a way to declare that a directory inside a project should always contain a specific version of another repository, and have that declaration versioned alongside the project itself.
Thesis: svn:externals gives a version‑controlled, declarative way to compose repositories while letting teams choose between tracking HEAD or a fixed revision for stability.
How svn:externals works
The svn:externals property is set on any directory. Its value is a list of lines, each line containing a local directory name, an optional revision flag, and a URL pointing to another repository (or a subdirectory inside it). When a working copy is checked out or updated, Subversion automatically checks out the external at the specified revision and places it under the given local name.
Worked example: pinning a library to a specific revision
- Create two repositories (run on a machine with filesystem access to the repos):
# Repository for the shared library svnadmin create /srv/svn/lib svn mkdir file:///srv/svn/lib/trunk -m "Create trunk" # Add a simple header file printf '/* lib.h */\nint add(int a, int b);\n' > lib.h svn import lib.h file:///srv/svn/lib/trunk/lib.h -m "Add lib.h" # Repository for the consuming project svnadmin create /srv/svn/app svn mkdir file:///srv/svn/app/trunk -m "Create trunk" svn checkout file:///srv/svn/app/trunk app-wc cd app-wc printf '/* main.c */\n#include "lib.h"\nint main(){return add(2,3);}\n' > main.c svn add main.c svn commit -m "Initial main.c" - Set svn:externals to point to a fixed revision of the library
# Determine the revision where lib.h lives (assume 10) svn propset svn:externals "lib -r10 file:///srv/svn/lib/trunk" . svn commit -m "Pin external library to revision 10" - Check out the project and verify the external appears
svn checkout file:///srv/svn/app/trunk app-wc2 cd app-wc2 ls -l # Expect to see a directory named 'lib' containing lib.h - Update the external to a newer library revision
# Suppose a new version of lib.h is committed as revision 12 svn propset svn:externals "lib -r12 file:///srv/svn/lib/trunk" . svn commit -m "Update external to library revision 12" # In existing working copies, pull the change svn update # The lib directory should now be at revision 12
Trade‑off: HEAD tracking vs. fixed revision
- Tracking HEAD (
svn:externals lib file:///srv/svn/lib/trunk) gives automatic access to the latest fixes, but a breaking change in the library can cause a build to fail without any explicit version bump. - Pinning to a revision (
-r12) guarantees reproducibility, which is ideal for CI pipelines and release branches. The downside is that you must manually update the property when you want to adopt a new library version, adding a small operational overhead.
Many teams adopt a hybrid strategy: development branches track HEAD to get rapid feedback, while mainline and release branches use pinned revisions.
Limitations and verification
Subversion records the svn:externals as a versioned property, so the exact configuration is visible in svn log -v. However, committing changes *inside* an external directory works only if you have write access to the external repository; otherwise the commit will be rejected with an error like "Authorization failed". This separation of histories means you cannot create a mixed‑revision commit that touches both the parent and the external in a single atomic operation.
To verify that your externals are behaving as expected:
- Check the property:
svn propget svn:externals. - Confirm the checked‑out revision:
svn info libshows "Revision: 12" (or whatever you pinned). - Attempt a commit inside
lib; if you have rights, it will succeed and affect only the external repository’s history.
Actionable closing
If your goal is stable, repeatable builds, pin svn:externals to a specific revision and treat updates to that property as a deliberate dependency upgrade. Use a CI step that runs svn update and then checks the revision of each external directory to detect drift. Periodically review pinned revisions to incorporate security fixes or new features, updating the property and committing the change as you would any other version‑controlled configuration.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.