Why Subversion’s Cheap Copies Make Branching Painless
Subversion implements branches and tags as cheap directory copies, letting you create and merge feature branches in seconds without duplicating data. A step‑by‑step demo shows the workflow, while a trade‑off table highlights binary bloat and latency concerns.
05 Jul 2026, 21:59 UTC

The problem: branching feels heavy in many VCS tools
Developers often avoid branching because creating a branch means copying gigabytes of history or waiting for a server to duplicate data. Subversion solves this with a different model: branches and tags are just cheap directory copies inside the same repository. The takeaway is that you can spin up a feature branch in seconds, merge it back atomically, and keep the repository size predictable—provided you watch binary assets.
How cheap copies work
Subversion stores every revision as a tree of nodes. When you run svn copy (or the higher‑level svn mkdir + svn commit), the server records a new directory entry that points to the existing node‑revision IDs. No file contents are duplicated; only a tiny metadata record is added. The revision number increments once, so the branch appears at a single, traceable point in history.
Key terms:
- Revision – a globally monotonically increasing integer that identifies a committed tree state.
- Node‑revision ID – an internal pointer to a specific version of a file or directory.
- Cheap copy – a directory entry that references existing node‑revision IDs instead of copying data.
Worked example: creating and merging a feature branch
Run the commands on a workstation that has network access to the Subversion server and write permission on the target repository path.
# 1. Verify client version (run locally)
svn --version
# Expected: output shows something like "svn, version 1.14.2 (r1234567)"
# 2. Create a temporary repository for the demo (run on the server or a VM with svnadmin)
svnadmin create /srv/svn/demo-repo
# 3. Import a minimal trunk layout
svn mkdir -m "Initial layout" \
file:///srv/svn/demo-repo/trunk \
file:///srv/svn/demo-repo/branches \
file:///srv/svn/demo-repo/tags
# 4. Checkout trunk
svn checkout file:///srv/svn/demo-repo/trunk demo-trunk
cd demo-trunk
# 5. Add a sample file and commit
printf 'int main() { return 0; }' > hello.c
svn add hello.c
svn commit -m "Add hello.c on trunk"
# Revision 2 created
# 6. Create a feature branch (cheap copy)
svn copy ^/trunk ^/branches/feature-xyz -m "Branch for feature XYZ"
# Revision 3 – only a new directory entry added
# 7. Switch working copy to the branch
svn switch ^/branches/feature-xyz
# 8. Make changes on the branch
printf 'int main() { printf("Feature XYZ\n"); return 0; }' > hello.c
svn commit -m "Implement feature XYZ"
# Revision 4
# 9. Merge back to trunk
cd ..
svn checkout file:///srv/svn/demo-repo/trunk demo-trunk-merge
cd demo-trunk-merge
svn merge ^/branches/feature-xyz
svn commit -m "Merge feature XYZ into trunk"
# Revision 5 – atomic commit of all merged changes
After step 9 the trunk contains the feature work, and the branch directory still exists for history. You can delete it with svn delete ^/branches/feature-xyz -m "Remove merged branch" (revision 6).
Trade‑offs and limitations
| Aspect | Benefit | Cost / Risk |
|---|---|---|
| Repository size | Cheap copies keep growth linear with text changes. | Large binary files (e.g., compiled artifacts, media) are stored as full copies per revision, causing bloat. |
| Network latency | Operations are simple HTTP/HTTPS or svnserve requests. | High latency makes svn update and svn commit noticeably slower than local DVCS operations. |
| Merge tracking | Subversion 1.5+ records mergeinfo, so repeated merges are safe. | Complex merge scenarios (re‑integrate, cherry‑pick) still require manual svn merge range specification. |
If your project ships large binaries, consider storing them outside Subversion (e.g., an artifact repository) and only version‑control build scripts.
Actionable closing
- Run
svn --versionon your build agents to confirm a supported 1.14+ client. - Create a throwaway repo with
svnadmin createand walk through the example above; it takes < 5 minutes. - Monitor repository size after a few binary commits (
du -sh /srv/svn/your-repo) to see the bloat effect first‑hand. - Adopt a branching policy: short‑lived feature branches, delete after merge, and keep binary assets out of version control.
With cheap copies, branching becomes a low‑cost, high‑visibility operation—exactly what a continuous‑integration pipeline needs.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.