Hello,
I have the following standard structure in my repository:
repos1/
branches/
tags/
trunk/
In another repository (repos2), I use svn:externals to reference a
specific tag of repos1. My concern is that I don't want people to
accidentally commit changes to the tag referenced by the externals
definition.
I've written a pre-commit hook to prevent changes to paths below
tags/<dir>, where <dir> is a specific tag. The hook still allows
deletion, addition, and copying from tags.
Any comments? Suggestions for improvements? Anybody see anything else
that does this?
Wesley Leggette
Cleversafe, LLC
#!/usr/bin/env python
import sys
import os
import os.path
from svn import repos, fs, delta, core
### DEAR USER: Please populate the test_props() and test_path_change()
### to do your bidding.
def test_props(props):
"""Validate the PROPS (a dictionary mapping property names to
values) set on the transaction. Return 0 if all is well, non-zero
otherwise."""
### Test the transaction (revision-to-be) properties. If there is
### bogosity, write to sys.stderr and return non-zero.
return 0
def test_path_change(path, change):
"""Validate the CHANGE made to PATH in the transaction. Return 0
if all is well, non-zero otherwise."""
# The svn_node_kind of the path.
item_kind = change.item_kind
# Non-zero iff properties of this path were changed.
prop_changes = change.prop_changes
# Non-zero iff path is a file, and its text was changed.
text_changed = change.text_changed
# The location of the previous revision of this resource, if any.
base_path = change.base_path
base_rev = change.base_rev
# Non-zero iff this change represents an addition (see
# base_path/base_rev for whether it was an addition with history).
added = change.added
### Test the path change as you see fit. If there is bogosity,
### write to sys.stderr and return non-zero.
# Debug statements
#sys.stderr.write('item_kind = ' + str(item_kind) + '\n')
#sys.stderr.write('prop_changes = ' + str(prop_changes) + '\n')
#sys.stderr.write('text_changed = ' + str(text_changed) + '\n')
#sys.stderr.write('base_path = ' + str(base_path) + '\n')
#sys.stderr.write('base_rev = ' + str(base_rev) + '\n')
#sys.stderr.write('added = ' + str(added) + '\n')
#sys.stderr.write('change.path = ' + str(change.path) + '\n')
#sys.stderr.write('-------------------\n')
#sys.stderr.write(str(dir(change)) + '\n')
sys.stderr.write('\n')
if change.path is not None:
if change.path.startswith('tags'):
if text_changed or prop_changes:
sys.stderr.write('Modifying tags is prohibited. Try commiting in a branch.\n')
return 1
destpath = change.path.lstrip('tags')
if len(destpath) > 0 and destpath[0] == '/':
destpath = destpath.lstrip('/')
if destpath.find('/') >= 0:
#sys.stderr.write('destpath = ' + str(destpath) + '\n')
#sys.stderr.write('FOUND = ' + str(destpath.find('/')) + '\n')
sys.stderr.write('Tag modifications must occur below the tag directory.\n')
sys.stderr.write('If you are adding or modifying directories or files \n')
sys.stderr.write('within a tag, try commiting in a branch.\n')
return 1
if base_path is not None:
if base_path.startswith('tags'):
if change.path is None:
srcpath = base_path.lstrip('tags')
if len(srcpath) > 0 and srcpath[0] == '/':
srcpath = srcpath.lstrip('/')
if srcpath.find('/') >= 0:
#sys.stderr.write('srcpath = ' + str(srcpath) + '\n')
sys.stderr.write('Deleting files and directories within a tag is prohibited.\n')
sys.stderr.write('Try commiting in a branch.\n')
return 1
return 0
def main(pool, repos_dir, txn, config_fp):
# Construct a ChangeCollector to fetch our changes.
fs_ptr = repos.svn_repos_fs(repos.svn_repos_open(repos_dir, pool))
root = fs.txn_root(fs.open_txn(fs_ptr, txn, pool), pool)
cc = repos.ChangeCollector(fs_ptr, root, pool)
# Call the transaction property validator. Might as well get the
# cheap checks outta the way first.
retval = test_props(cc.get_root_props())
if retval:
return retval
# Generate the path-based changes list.
e_ptr, e_baton = delta.make_editor(cc, pool)
repos.svn_repos_replay(root, e_ptr, e_baton, pool)
# Call the path change validator.
changes = cc.get_changes()
paths = changes.keys()
paths.sort(lambda a, b: core.svn_path_compare_paths(a, b))
for path in paths:
change = changes[path]
retval = test_path_change(path, change)
if retval:
return retval
return 0
def _usage_and_exit():
sys.stderr.write("USAGE: %s REPOS-DIR TXN-NAME\n" % (sys.argv[0]))
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) < 3:
_usage_and_exit()
sys.exit(core.run_app(main, sys.argv[1], sys.argv[2], None))
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Tue Jul 11 19:22:31 2006