Roll back a Subversion repository
|Debian (Etch, Lenny, Squeeze)|
|Ubuntu (Lucid, Maverick, Natty, Trusty)|
To roll back a Subversion repository to a previous state, deleting all subsequent revisions
/var/lib/svn/foo is a Subversion repository with a head revision of 201. When you committed that revision the working copy contained several hundred altered files. You intended to commit only one of them, but neglected to give a path list to
svn commit. You wish to correct this mistake by rolling back to revision 200.
Deleting revisions is a highly invasive procedure which involves rebuilding the repository. You will require administrative access to it, and the cooperation of any other users. In principle it ought to be safe, but there is significant potential for data loss if you make a mistake.
The method described here has six steps:
- Roll back any working copies of the repository.
- Export any files that you want to keep.
- Dump the revisions to be kept.
- Load the dumpfile into a new, empty repository.
- Replace the old repository with the new repository.
- Re-commit any deleted changes that are to be kept.
Do not use this procedure if you merely wish to:
- delete a file or directory from the head revision, or
- alter a log message.
The former can be done without administrative access using the
svn rm command. The latter requires administrative access, but can be achieved more easily and safely using the
svnadmin setlog command.
When a revision is deleted from the repository, any working copies of that revision become invalid. To prevent this from happening you should roll back each of them to a revision that will not be deleted:
svn update -r 200
This should be done by the owner of the working copy, not by root. You will need to ensure that the working copies remain in this state until the procedure has been completed.
If the revisions to be deleted contain any files that you want to keep then you should make a copy of them now. It is better to do this in the form of an export as opposed to a working copy, because a working copy would be invalidated by the deletion.
It is not necessary to export the entire repository: only the part containing the files of interest. Typically the trunk or a particular branch will suffice:
svn export file:///var/lib/svn/foo/trunk foo-trunk-snapshot
svnadmin dump command to create a dumpfile containing the revisions to be kept, but not the revisions to be deleted:
cd /var/lib/svn svnadmin dump foo -r 0:200 > foo.dump
-r option specifies the set of revisions to be included in the dumpfile. In this case the dumpfile will include revisions 0 to 200 inclusive, but not revision 201.
svnadmin create command to create a new, empty repository, then use the
svnadmin load command to load it with the content of the dumpfile:
svnadmin create foo.new svnadmin load foo.new < foo.dump
If the repository needs to be owned by a different account from the one you are using then you should (recursively) change its ownership now. For example, if it is served using Apache then it may need to be owned by
chown -R www-data:www-data foo.new
The new repository should now be ready for use, so can be moved into place:
mv foo foo.old mv foo.new foo
If the revisions that were deleted contained any changes that you want to keep then these should now be re-committed to the repository. The easiest way to do this is to check out a new working copy, then overwrite it with the snapshot prepared earlier:
svn co file:///var/lib/svn/foo/trunk foo-trunk cp -r foo-trunk-snapshot/* foo-trunk
You should now be able to obtain a list of new or modified files using the
svn status command, and to (selectively) commit them to the repository using
svn add and
svn commit in the normal way.