I filed https://issues.apache.org/jira/browse/SVN-4730, "'svnadmin verify' should check rep-cache refers to valid revs".
The following script ("rollback-1.sh") incorporates some of your suggestions: [[[ #!/bin/bash # Remove the most recent revision(s) from a repository # usage: $0 NEW_HEAD_REV # Assumes we are in the repository directory. # Requires: svnadmin, svnlook set -ex # stop on error; show cmds executed # repository directory REPOS=. # desired new head revision R=$1 OLD_R=`svnlook youngest $REPOS` OLD_TXNS=`svnadmin lstxns $REPOS` # check the repository format is one we know how to handle test `cat $REPOS/format` -eq 5 test `cat $REPOS/db/fs-type` = fsfs FSFS_FORMAT=`head -1 $REPOS/db/format` test $FSFS_FORMAT -ge 7 # svn 1.9 test $FSFS_FORMAT -le 8 # svn 1.10 grep -q "layout sharded" db/format # check the unwanted revisions have not been packed # TODO: finish this: svnadmin info $REPOS | grep "FSFS Shards Packed:" #... # remove the 'current' file; let 'svnadmin recover' recreate it with the # new head revision number later. (Alternatively, we could write $R into it.) rm $REPOS/db/current # remove the unwanted revision files for F in $(seq $((R+1)) $OLD_R); do rm -f $REPOS/db/revs/*/$F $REPOS/db/revprops/*/$F done # remove all pending txns, in case they reference an unwanted rev svnadmin rmtxns $REPOS $OLD_TXNS # Prune the rep-cache. This is essential, otherwise later commits will be # silently corrupted. # # 'svnadmin recover' does this since 1.7.3, 1.8.0. # # If we can't use 'recover' (e.g. because we're inside an 'svnadmin freeze' # script) we could do this manually with the 'sqlite3' utility. The expected # output is no output. #sqlite3 $REPO/db/rep-cache.db "delete from rep_cache where revision > $R" # re-start all repository-accessing processes (svnserve, httpd) # TODO: invite the user to do that... # 'recover' recreates the 'current' file according to the last rev found, # and prunes the rep cache. svnadmin recover $REPOS ]]] - Julian
rollback-1.sh
Description: application/shellscript