Automating Merge Tracking with Subversion svn:mergeinfo
Use svn:mergeinfo to automate pending-merge detection in Subversion, with CI-controlled updates, pre-commit guards, and drift checks between recorded and actual merges.
11 Aug 2026, 14:12 UTC

Problem and takeaway
In a large Subversion repository, teams often lose track of which revisions have already been merged from a feature branch to trunk. A developer may re-merge changes that are already present, or skip revisions that were never applied, producing conflicts and regression risk. Subversion addresses this with the svn:mergeinfo property: a versioned property on each path that records which source revision ranges have been merged into it. The property only helps, however, if it stays accurate and is consulted before every merge.
The practical takeaway is a small automation layer: CI jobs record merges with svn merge --record-only, a nightly scan lists pending merges with svn mergeinfo --show-revs eligible, and a pre-commit hook guards against commits that delete or corrupt mergeinfo. This removes manual tracking without requiring a new merge-tracking service.
Requirements
- The repository uses a standard
trunk/,branches/,tags/layout so mergeinfo stays localized to integration paths. - All merges to trunk or release branches are performed through CI or a designated merge script, not ad hoc working-copy commits.
- The team must be able to answer "which revisions are still pending on trunk?" without inspecting commit messages by hand.
- Mergeinfo must survive repository maintenance such as
svnadmin dumpandsvnadmin load.
Smallest suitable design
The design has three parts: a recorder, an eligibility reader, and a guard.
Recorder. When a feature branch is merged to trunk, the CI job applies the merge in a working copy and commits the result, including the updated svn:mergeinfo property. If changes were applied outside Subversion's normal merge flow, the job runs svn merge --record-only for the same revision range so the property reflects reality without reapplying content.
Eligibility reader. A scheduled job or on-demand command queries the target path to see what remains:
svn mergeinfo --show-revs eligible \
https://svn.example.com/repo/trunk
Where: any machine with the Subversion client and network access to the repository URL. Permissions: read access to the target URL. Placeholders: replace the URL with your trunk path. Expected check: the command prints revision ranges that have not been merged; empty output means trunk is current relative to the source branches it knows about. Risk: none, this is read-only.
Guard. A pre-commit hook on the repository server inspects each transaction and rejects commits that remove existing svn:mergeinfo ranges or modify the property on integration paths without authorization. The hook runs as the repository server user and can use svnlook to read transaction properties before they are committed.
Trust and data boundaries
svn:mergeinfo is a versioned property, so anyone with commit access to a path can edit or delete it. That makes the property itself a trust boundary.
- Write boundary. Limit commits that change
svn:mergeinfoontrunk/and release branches to the CI service account and a small group of release engineers. Developers should merge through CI rather than committing mergeinfo edits directly. - Read boundary. Reading mergeinfo is safe and unrestricted; eligibility queries do not modify the repository.
- Property boundary. The hook should treat
svn:mergeinfoontags/as immutable. Tags should never receive mergeinfo updates after creation.
Operational checks
Run these checks on a schedule or after major merge windows.
1. Pending-merge scan
svn mergeinfo --show-revs eligible https://svn.example.com/repo/trunk
Review the list weekly. If it contains revisions that were merged manually but not recorded, run the recorder step for those ranges.
2. Recorded-versus-actual drift check
Compare what mergeinfo claims against what the trees actually contain. For a recently merged range:
svn diff --summarize -r4000:4050 \
https://svn.example.com/repo/branches/feature-123 \
https://svn.example.com/repo/trunk
Where: client with read access to both URLs. Permissions: read access. Placeholders: replace 4000:4050, the branch path, and the trunk path. Expected check: if mergeinfo records 4000:4050 as merged but this command returns differing paths, the property is stale or the merge was incomplete. Risk: none, read-only.
3. Migration spot-check
After svnadmin dump followed by svnadmin load into a fresh repository, run svn propget svn:mergeinfo on a few trunk and branch paths and compare against the source repository. Mergeinfo is versioned and should survive a dump/load cycle.
Failure modes
- Fragmented mergeinfo. Many small merges across many paths make the property large. Large property values slow commits, checkouts, and eligibility queries. Mitigate by merging at the branch root rather than individual files and by consolidating long-lived feature branches.
- Silent unrecorded merge. A developer merges changes locally but forgets to commit the updated mergeinfo, or merges without
--record-onlywhen no content changes were needed. Later eligibility scans suggest re-merging work that is already present. - Corrupt mergeinfo. Manual editing with a text editor or a faulty script can produce malformed revision ranges. Subsequent
svn mergeoperations may skip revisions or fail with property errors. - Hook bypass. Anyone with direct filesystem access to the repository, or a disabled pre-commit hook, can change mergeinfo without review.
Conditions that would change the design
- Hundreds of active branches. If mergeinfo grows large enough to degrade repository performance, reduce branch count, shorten branch lifetimes, or move to a reintegration-only model.
- Low merge frequency. If the team merges once per month or less, manual mergeinfo updates may be cheaper than maintaining CI jobs and hooks.
- Planned migration away from Subversion.
svn:mergeinfodoes not translate directly to Git merge commits. If migration is imminent, export merge history once rather than investing in automation.
Limitations and verification
svn:mergeinfo records that a revision range was merged, not that the merge was semantically correct. A recorded merge can still leave logical conflicts or missing tests. Eligibility queries are only as accurate as the most recent mergeinfo commit.
To verify the design in a non-production repository:
- Create a branch from trunk, commit a change, and merge it back to trunk.
- Commit the merge, including the updated
svn:mergeinfoproperty. - Run
svn mergeinfo --show-revs eligibleon trunk and confirm the merged revisions no longer appear as pending. - Run
svn diff --summarizeacross the merged range to confirm trunk and branch content match for those paths.
Do not treat a successful test in a sandbox as proof that production mergeinfo is correct; verify against your actual branch history.
Rollback for an incorrect record-only commit
Because recording mergeinfo creates a repository revision, it changes state. If a svn merge --record-only commit records a range that was never actually applied, revert that commit and re-record only after confirming the real merge content. Reverting removes the incorrect history entry but does not restore any content that was never merged.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.