Implementing Subversion Branching and Merging with Mergeinfo Tracking
A practical guide to Subversion branching and merging using the standard directory layout and svn:mergeinfo tracking. Covers branch creation, sync merges, reintegration to trunk, verification steps, and recovery from common failure modes.
19 Jan 2026, 09:24 UTC

Desired Outcome
Establish a reliable branching and merging workflow in Subversion that preserves history, tracks integrated revisions via svn:mergeinfo, and minimizes conflict overhead when integrating feature work back to trunk.
Prerequisites
- A Subversion repository using the standard layout:
/trunk,/branches,/tagsat the repository root. - Write access to the repository (commit permissions on
/branchesand/trunk). - A clean working copy of
/trunkwith no uncommitted changes (svn statusshows no output). - Subversion 1.5 or later on client and server (required for
svn:mergeinfosupport).
Procedure
1. Create the Feature Branch
Use svn copy to create a server-side branch. This operation is cheap—Subversion records a pointer to the trunk revision rather than duplicating data.
svn copy ^/trunk ^/branches/feature-xyz -m "Create branch for feature XYZ from trunk@HEAD"Run this from any directory with repository access. The ^ shorthand resolves to the repository root URL. The commit message documents the source revision for future reference.
2. Check Out or Switch to the Branch
Either check out a fresh working copy or switch an existing one:
# Fresh checkout
svn checkout ^/branches/feature-xyz feature-xyz-wc
# Or switch existing trunk WC
cd trunk-wc
svn switch ^/branches/feature-xyzVerify the switch with svn info—the URL line should show the branch path.
3. Develop on the Branch
Commit changes normally. Each commit increments the branch's revision history independently of trunk.
svn commit -m "Implement feature XYZ: add validation layer"4. Keep the Branch Current (Optional but Recommended)
Periodically merge trunk changes into the branch to reduce integration risk. From the branch working copy:
svn merge ^/trunk
svn commit -m "Sync trunk@1234 to branch: resolve conflicts, update dependencies"This records the merged trunk revisions in the branch's svn:mergeinfo, so future merges back to trunk know what's already integrated.
5. Merge the Branch Back to Trunk
When the feature is complete, integrate it to trunk:
- Ensure a clean trunk working copy:
cd trunk-wc && svn status(no output). - Dry-run the merge:
svn merge --dry-run ^/branches/feature-xyz. Review the listed file changes and conflict warnings. - Apply the merge:
svn merge ^/branches/feature-xyz. Subversion calculates the difference between the branch's creation point (or last merge) and its HEAD, then applies those changes to the trunk working copy. - Resolve any conflicts: Edit conflicted files, remove conflict markers, then run
svn resolve --accept=working <file>for each. - Commit the merge:
svn commit -m "Merge feature XYZ from branches/feature-xyz@HEAD: implements validation layer".
Expected Checks
Verify Branch Creation
Confirm the branch inherits trunk history:
svn log ^/branches/feature-xyz --limit 5The log should show the copy commit and, before that, trunk history.
Inspect Mergeinfo
After merging to trunk, check the recorded revision ranges:
svn propget svn:mergeinfo ^/trunkOutput example: /branches/feature-xyz:1200-1250 indicates revisions 1200 through 1250 from that branch are integrated. If the property is missing or incomplete, the merge commit may have been made without proper merge tracking (e.g., using a plain svn copy of files instead of svn merge).
Dry-Run Validation
Before any merge, run:
svn merge --dry-run ^/branches/feature-xyzThis prints the files that would change, flagging conflicts (C) and tree conflicts (T) without touching the filesystem. Use it to estimate merge complexity.
Recovery Options
Abort a Merge in Progress
If a merge introduces unexpected conflicts or wrong changes, revert the working copy to pre-merge state:
svn revert -R .This discards all local modifications from the merge attempt. The repository remains unchanged.
Undo a Committed Merge (Rollback)
If a bad merge was committed to trunk, reverse-merge the specific revision range:
svn merge -c -1255 ^/trunk
svn commit -m "Revert r1255: faulty merge of feature XYZ"Replace 1255 with the merge commit's revision. This creates a new commit that undoes the changes while preserving history.
Recover from Manual File Copies
If files were copied manually (breaking mergeinfo), the only reliable fix is to re-create the branch from trunk and re-apply changes via patches or a fresh merge. Attempting to repair svn:mergeinfo by hand is error-prone and not recommended.
Limitations and Practical Notes
- Mergeinfo bloat: Repeated merges across many revisions can make the
svn:mergeinfoproperty large and fragmented, slowing subsequent merges. Periodicsvn merge --reintegrate(for feature branches) or squashing intermediate sync merges can mitigate this. - Tree conflicts: Renames, moves, or deletions on both branches often produce tree conflicts requiring manual resolution.
svn statusmarks these withT; usesvn resolve --accept=workingafter verifying the correct tree structure. - Branch deletion: After a successful reintegrate merge, delete the branch (
svn delete ^/branches/feature-xyz -m "Remove merged feature branch") to reduce clutter. The history remains accessible via the merge commit. - Client version mismatch: Pre-1.5 clients cannot read or write
svn:mergeinfo, causing silent tracking failures. Enforce a minimum client version policy.
Quick Reference: Essential Commands
| Task | Command |
|---|---|
| Create branch | svn copy ^/trunk ^/branches/name -m "msg" |
| Switch WC to branch | svn switch ^/branches/name |
| Sync trunk to branch | svn merge ^/trunk |
| Dry-run merge to trunk | svn merge --dry-run ^/branches/name |
| Merge branch to trunk | svn merge ^/branches/name |
| View mergeinfo | svn propget svn:mergeinfo [path] |
| Abort local merge | svn revert -R . |
| Rollback committed merge | svn merge -c -REV ^/trunk |
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.