How to prevent changes to a tag via svn hook
A colleague of mine recently asked if it was possible to keep people from committing changes to tags in subversion. I thought “Hey, that should be easy to do via the pre-commit hook. I bet someone already made one that I can just test and use“. Either my google-fu failed me or the request wasn’t as common as I had anticipated, because surprisingly I couldn’t find any hooks that truly accomplish blocking changes to a tag (probably right after I post this someone will say “hey, why didn’t you look $here, it is exactly what you wanted“).
I found people looking for such a feature, and I found a hook or two that kinda did what I needed (the best I could find was a hook that just blocked updates to /tags/* but it allowed deletes, adds and property changes), but none that really blocked all changes to tags. So I decided to just make my own configurable svn hook. You can tell it what to allow and what to block, and which directory to work on (since not everyone has the tags in their base directory of the repository).
You may have to change the SVNLOOK variable depending on where your svnlook binary is installed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #!/bin/bash #=============================================================================== # # FILE: pre-commit # # DESCRIPTION: pre-commit svn hook. configurable hook to block certain # actions on svn tags # (e.g. blocking changes to existing tags) # # REQUIREMENTS: svnlook # AUTHOR: Ryan Schulze (rs), ryan@dopefish.de #=============================================================================== #=============================================================================== # Path to tags directory in the repository #=============================================================================== TAGS_PATH="^tags/" #=============================================================================== # What to allow or block #=============================================================================== UPDATE=block DELETE=block ADD=block PROPERTIES=block #=============================================================================== REPOS="${1}" TXN="${2}" SVNLOOK=/usr/bin/svnlook ABORT=0 while read line do # SVN Action for this element ACTION="${line%% *}" # Path for this element FILE_PATH="$(echo "${line#* }" | sed 's/^ *//')" # regex that skips entries for the top level directory of a specific tag (e.g. tags/1.5/) # so that we can still create and delete the tags themselves if [[ "${FILE_PATH}" =~ ${TAGS_PATH}[/]*[^/]+/.+$ ]] then # A - Item added to repository # D - Item deleted from repository # U - File contents changed # _U - Properties of item changed # UU - File contents and properties changed case ${ACTION} in U | UU ) [[ "${UPDATE}" == 'block' ]] && ABORT=1 ;; D ) [[ "${DELETE}" == 'block' ]] && ABORT=1 ;; A ) [[ "${ADD}" == 'block' ]] && ABORT=1 ;; _U | UU ) [[ "${PROPERTIES}" == 'block' ]] && ABORT=1 ;; esac fi if [[ ${ABORT} -gt 0 ]] then echo "Cannot change tags!" 1>&2 exit 1 fi done < <(${SVNLOOK} changed -t "$TXN" "$REPOS") # All checks passed, so allow the commit. exit 0 |