Bulk copying locks is a similar issue to bulk copying revprops. There
is no easy way to bulk copy locks from a repository to a copy of the
repository (even hotcopy has problems: issue 3750).
As with revprops I can write a script using the bindings (see below).
However this script is less useful that the one to copy revprops. It
has a performance problem when the number of locks is large due to the
O(N^2) behaviour of the index. It may be possible to mitigate this by
collecting the locks and using the _many API although I suspect the
bindings need to be enhanced first.
Another problem is that Subversion's current API doesn't allow setting
the lock's creation date, the date is always set from the local clock.
That means there is no way to write code using the current API that will
copy locks. It is possible that the best way to copy locks is to do an
OS copy of the entire locks subdir from an offline repository and rely
on the fact that the on-disk representation remains valid across FSFS
We should have a better method. At a minimum we need a new FS API that
allows the lock's creation date to be specified.
We don't have dump/load support for locks but we probably don't need it.
'svnadmin lslocks' is effectively a dump for locks. The lock order is
lexical MD5 of the path, which is probably not optimal for adding locks
in a bulk load. Getting a better order might be tricky as is deciding
how to break the list into batches. As with revprops making sure the FS
layer can detect an add that doesn't change anything and then avoid all
disk writes will probably help.
from svn import core, fs, repos
src_path = core.svn_path_canonicalize(sys.argv)
dst_path = core.svn_path_canonicalize(sys.argv)
src_repo = repos.open(src_path)
dst_repo = repos.open(dst_path)
src_fs = repos.fs(src_repo)
dst_fs = repos.fs(dst_repo)
dst_head = fs.youngest_rev(dst_fs)
def add_locks(src_lock, pool):
dst_lock = fs.get_lock(dst_fs, src_lock.path)
if (dst_lock and src_lock.token == dst_lock.token
and src_lock.comment == dst_lock.comment
and src_lock.is_dav_comment == dst_lock.is_dav_comment
and src_lock.expiration_date == dst_lock.expiration_date):
print "elide: " + src_lock.path
access = fs.create_access(src_lock.owner)
src_lock.path, src_lock.token, src_lock.comment,
print "set: " + src_lock.path
fs.get_locks(src_fs, "", add_locks)
def rm_locks(dst_lock, pool):
src_lock = fs.get_lock(src_fs, dst_lock.path)
if not src_lock:
fs.unlock(dst_fs, dst_lock.path, dst_lock.token, True)
print "rm: " + dst_lock.path
access = fs.create_access("dummy")
fs.get_locks(dst_fs, "", rm_locks)
Received on 2015-09-24 13:48:44 CEST