tortoise tag subversion estructura entre diferencia create crear branches svn tags svn-hooks pre-commit

svn - tag - merge branches subversion



Gancho de precompilación de SVN para evitar cambios en subdirectorios de etiquetas (11)

Aquí está mi gancho de precompilación del archivo por lotes de Windows. Si el usuario es un administrador, las otras comprobaciones se omitirán. Comprueba si el mensaje de confirmación está vacío y si la confirmación es una etiqueta. Nota: findstr es una alternativa nerfed para grep en otras plataformas.

La forma en que comprueba si la confirmación es para una etiqueta, primero comprueba si svnlook changed contiene "etiquetas /". A continuación, comprueba si svnlook changed coincide con "^ A. Tags / [^ /] / $", lo que significa que comprobará si está agregando una nueva carpeta debajo de las etiquetas /.

Los usuarios pueden crear nuevos proyectos. El enlace precompromiso permite a un usuario crear las carpetas trunk / tags / y branches /. Los usuarios no pueden eliminar las carpetas trunk / tags / y branches /. Esto funcionará para un repositorio de uno o varios proyectos.

@echo off rem This pre-commit hook will block commits with no log messages and blocks commits on tags. rem Users may create tags, but not modify them. rem If the user is an Administrator the commit will succeed. rem Specify the username of the repository administrator rem commits by this user are not checked for comments or tags rem Recommended to change the Administrator only when an admin commit is neccessary rem then reset the Administrator after the admin commit is complete rem this way the admin user is only an administrator when neccessary set Administrator=Administrator setlocal rem Subversion sends through the path to the repository and transaction id. set REPOS=%1% set TXN=%2% :Main rem check if the user is an Administrator svnlook author %REPOS% -t %TXN% | findstr /r "^%Administrator%$" >nul if %errorlevel%==0 (exit 0) rem Check if the commit has an empty log message svnlook log %REPOS% -t %TXN% | findstr . > nul if %errorlevel% gtr 0 (goto CommentError) rem Block deletion of branches and trunk svnlook changed %REPOS% -t %TXN% | findstr /r "^D.*trunk/$ ^D.*branches/$" >nul if %errorlevel%==0 (goto DeleteBranchTrunkError) rem Check if the commit is to a tag svnlook changed %REPOS% -t %TXN% | findstr /r "^.*tags/" >nul if %errorlevel%==0 (goto TagCommit) exit 0 :DeleteBranchTrunkError echo. 1>&2 echo Trunk/Branch Delete Error: 1>&2 echo Only an Administrator may delete the branches or the trunk. 1>&2 echo Commit details: 1>&2 svnlook changed %REPOS% -t %TXN% 1>&2 exit 1 :TagCommit rem Check if the commit is creating a subdirectory under tags/ (tags/v1.0.0.1) svnlook changed %REPOS% -t %TXN% | findstr /r "^A.*tags/[^/]*/$" >nul if %errorlevel% gtr 0 (goto CheckCreatingTags) exit 0 :CheckCreatingTags rem Check if the commit is creating a tags/ directory svnlook changed %REPOS% -t %TXN% | findstr /r "^A.*tags/$" >nul if %errorlevel% == 0 (exit 0) goto TagsCommitError :CommentError echo. 1>&2 echo Comment Error: 1>&2 echo Your commit has been blocked because you didn''t enter a comment. 1>&2 echo Write a log message describing your changes and try again. 1>&2 exit 1 :TagsCommitError echo. 1>&2 echo %cd% 1>&2 echo Tags Commit Error: 1>&2 echo Your commit to a tag has been blocked. 1>&2 echo You are only allowed to create tags. 1>&2 echo Tags may only be modified by an Administrator. 1>&2 echo Commit details: 1>&2 svnlook changed %REPOS% -t %TXN% 1>&2 exit 1

¿Hay alguien que tenga instrucciones claras sobre cómo agregar un enlace precompromiso que evite los cambios a los subdirectorios de las etiquetas?

Ya busqué bastante en internet. Encontré este enlace: SVN::Hooks::DenyChanges , pero parece que no puedo compilar las cosas.


Aquí hay un breve script de shell para evitar comprometerse con las etiquetas una vez que se han creado:

#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook # Committing to tags is not allowed $SVNLOOK changed -t "$TXN" "$REPOS" | grep "^U/W*tags" && /bin/echo "Cannot commit to tags!" 1>&2 && exit 1 # All checks passed, so allow the commit. exit 0

Guarde esto en hooks/pre-commit para su repositorio de Subversion y hágalo ejecutable con chmod +x .


Dado que la primera respuesta no impedía los archivos add / suppr, y evitaba la creación de nuevas etiquetas, y muchos otros estaban incompletos o con errores, lo reelaboré

Aquí está mi gancho precompromiso: las metas son:

  • No permitir confirmaciones en las etiquetas (adición / supresión / actualizaciones de archivos)
  • No evite la creación de etiquetas

--------- archivo "precompromiso" (poner en los repositorios ganchos carpeta) ---------

#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook #Logs #$SVNLOOK changed -t "$TXN" "$REPOS" > /tmp/changes #echo "$TXN" > /tmp/txn #echo "$REPOS" > /tmp/repos # Committing to tags is not allowed # Forbidden changes are Update/Add/Delete. /W = non alphanum char Redirect is necessary to get the error message, since regular output is lost. # BUT, we must allow tag creation / suppression $SVNLOOK changed -t "$TXN" "$REPOS" | /bin/grep "^A/W.*tags//[0-9._-]*//." && /bin/echo "Commit to tags are NOT allowed ! (Admin custom rule)" 1>&2 && exit 101 $SVNLOOK changed -t "$TXN" "$REPOS" | /bin/grep "^U/W.*tags//[0-9._-]*//." && /bin/echo "Commit to tags are NOT allowed ! (Admin custom rule)" 1>&2 && exit 102 $SVNLOOK changed -t "$TXN" "$REPOS" | /bin/grep "^D/W.*tags//[0-9._-]*//." && /bin/echo "Commit to tags are NOT allowed ! (Admin custom rule)" 1>&2 && exit 104 # All checks passed, so allow the commit. exit 0;

--------- fin del archivo "precompromiso" ---------

Además, hice 2 scripts de shell para copiar mi gancho en cada proyecto de mi svn: One para establecer un repo de solo lectura:

--------- script "setOneRepoTagsReadOnly.sh" ---------

#!/bin/sh cd /var/svn/repos/svn zeFileName=$1/hooks/pre-commit /bin/cp ./CUSTOM_HOOKS/pre-commit $zeFileName chown www-data:www-data $zeFileName chmod +x $zeFileName

--------- fin del archivo "setOneRepoTagsReadOnly.sh" ---------

Y uno lo llama para cada repositorio, para hacer que todos mis repos solo sean leídos:

--------- archivo "makeTagsReadOnly.sh" ---------

#!/bin/shs/svn #Lists all repos, and adds the pre-commit hook to protect tags on each of them find /var/svn/repos/svn/ -maxdepth 1 -mindepth 1 -type d -execdir ''/var/svn/repos/svn/setOneRepoTagsReadOnly.sh'' /{/} /;

--------- fin del archivo "makeTagsReadOnly.sh" ---------

Ejecuto estos scripts directamente desde svn "root" (/ var / svn / repos / svn, en mi caso). Por cierto, una tarea cron se puede configurar para modificar automáticamente los repositorios nuevos mediante la ejecución de esos scripts diariamente

Espero eso ayude.


Este informe es muy posterior a la fecha, pero descubrí el parámetro --copy-info para el comando svnlook changed.

La salida de este comando agrega un ''+'' en la tercera columna, para que sepa que es una copia. Puede verificar las confirmaciones en el directorio de etiquetas y solo permitir las confirmaciones con un ''+'' presente.

He agregado algunos resultados en mi publicación de blog .


La mayoría de los scripts escritos previamente están incompletos porque varios casos no están cubiertos. Este es mi guion:

contains_tags_dir=`$SVNLOOK changed --copy-info -t "$TXN" "$REPOS" | head -1 | egrep "+//tags//.*$" | wc -l | sed "s/ //g"` if [ $contains_tags_dir -gt 0 ] then tags_dir_creation=`$SVNLOOK changed --copy-info -t "$TXN" "$REPOS" | head -1 | egrep "^A .+//tags//$" | wc -l | sed "s/ //g"` if [ $tags_dir_creation -ne 1 ] then initial_add=`$SVNLOOK changed --copy-info -t "$TXN" "$REPOS" | head -1 | egrep "^A /+ .+//tags//.+//$" | wc -l | sed "s/ //g"` if [ $initial_add -ne 1 ] then echo "Tags cannot be changed!" 1>&2 exit 1 fi fi fi

Puede parecer complicado, pero debes asegurarte de que estás en /tags y puedes crear /tags si no existe y todas las carpetas subsiguientes. Cualquier otro cambio está bloqueado. Casi ninguno de los scripts anteriores cubre todos los casos descritos en el libro de Subversion para svnlook changed ...


La respuesta aceptada impide actualizar archivos en una etiqueta, pero no impide agregar archivos a una etiqueta. La siguiente versión maneja ambos:

#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK="/home/staging/thirdparty/subversion-1.6.17/bin/svnlook" # Committing to tags is not allowed $SVNLOOK changed -t "$TXN" "$REPOS" --copy-info| grep -v "^ " | grep -P ''^[AU] /w+/tags/'' && /bin/echo "Cannot update tags!" 1>&2 && exit 1 # All checks passed, so allow the commit. exit 0


Las respuestas enumeradas son excelentes, pero ninguna hizo exactamente lo que necesito. Quiero permitir la creación de etiquetas fácilmente, pero una vez que se crean, deben ser de solo lectura.

También quiero evitar la estúpida situación en la que si haces esto:

svn copy myrepo/trunk myrepo/tags/newrelease

Todo está bien la primera vez. Pero la segunda vez, si la etiqueta ya existe, terminará con myrepo/tags/newrelease/trunk .

Mi gancho precompromiso buscará cualquier vinculación (repo)/tags/(tag)/ directorio SVN preexistente y fallará si se encuentra:

$SVNLOOK tree -N --full-paths "$REPOS" "`$SVNLOOK changed -t "$TXN" "$REPOS" / | sed ''s/[A-Z][[:space:]]*/([^/]*/)//tags///([^/]*/)//.*//1//tags///2///'' / | head -n 1`" / && echo "Tag already exists, commit rejected." >&2 / && exit 1


Mi versión solo permite crear y eliminar etiquetas. Esto debería manejar todos los casos especiales (como agregar archivos, cambiar propiedades, etc.).

#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/local/bin/svnlook output_error_and_exit() { echo "$1" >&2 exit 1 } changed_tags=$( $SVNLOOK changed -t "$TXN" "$REPOS" | grep "[ /]tags/." ) if [ "$changed_tags" ] then echo "$changed_tags" | egrep -v "^[AD] +(.*/)?tags/[^/]+/$" && output_error_and_exit "Modification of tags is not allowed." fi exit 0


Muy tarde para la fiesta, sin embargo, escribí un gancho de precompromiso de python para el trabajo que se basa en el script log-police.py en http://subversion.tigris.org/ .

Este script debe hacer lo que quiera, sin embargo, también verifica que exista un mensaje de registro, aunque debería ser fácil de eliminar del script.

Algunas advertencias:

  • Soy nuevo en Python, por lo que probablemente podría escribirse mejor
  • Solo se ha probado en Windows 2003 con Python 2.5 y Subversion 1.4.

Requisitos:

  • Subversión
  • Pitón
  • Enlaces de Subversion para Python

Finalmente, el código:

#!/usr/bin/env python # # pre-commit.py: # # Performs the following: # - Makes sure the author has entered in a log message. # - Make sure author is only creating a tag, or if deleting a tag, author is a specific user # # Script based on http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/log-police.py # # usage: pre-commit.py -t TXN_NAME REPOS # E.g. in pre-commit.bat (under Windows) # python.exe {common_hooks_dir}/pre_commit.py -t %2 %1 # import os import sys import getopt try: my_getopt = getopt.gnu_getopt except AttributeError: my_getopt = getopt.getopt import re import svn import svn.fs import svn.repos import svn.core # # Check Tags functionality # def check_for_tags(txn): txn_root = svn.fs.svn_fs_txn_root(txn) changed_paths = svn.fs.paths_changed(txn_root) for path, change in changed_paths.iteritems(): if is_path_within_a_tag(path): # else go to next path if is_path_a_tag(path): if (change.change_kind == svn.fs.path_change_delete): if not is_txn_author_allowed_to_delete(txn): sys.stderr.write("/nOnly an administrator can delete a tag./n/nContact your Subversion Administrator for details.") return False elif (change.change_kind != svn.fs.path_change_add): sys.stderr.write("/nUnable to modify " + path + "./n/nIt is within a tag and tags are read-only./n/nContact your Subversion Administrator for details.") return False # else user is adding a tag, so accept this change else: sys.stderr.write("/nUnable to modify " + path + "./n/nIt is within a tag and tags are read-only./n/nContact your Subversion Administrator for details.") return False return True def is_path_within_a_tag(path): return re.search(''(?i)//tags//'', path) def is_path_a_tag(path): return re.search(''(?i)//tags//[^//]+//?$'', path) def is_txn_author_allowed_to_delete(txn): author = get_txn_property(txn, ''svn:author'') return (author == ''bob.smith'') # # Check log message functionality # def check_log_message(txn): log_message = get_txn_property(txn, "svn:log") if log_message is None or log_message.strip() == "": sys.stderr.write("/nCannot enter in empty commit message./n") return False else: return True def get_txn_property(txn, prop_name): return svn.fs.svn_fs_txn_prop(txn, prop_name) def usage_and_exit(error_msg=None): import os.path stream = error_msg and sys.stderr or sys.stdout if error_msg: stream.write("ERROR: %s/n/n" % error_msg) stream.write("USAGE: %s -t TXN_NAME REPOS/n" % (os.path.basename(sys.argv[0]))) sys.exit(error_msg and 1 or 0) def main(ignored_pool, argv): repos_path = None txn_name = None try: opts, args = my_getopt(argv[1:], ''t:h?'', ["help"]) except: usage_and_exit("problem processing arguments / options.") for opt, value in opts: if opt == ''--help'' or opt == ''-h'' or opt == ''-?'': usage_and_exit() elif opt == ''-t'': txn_name = value else: usage_and_exit("unknown option ''%s''." % opt) if txn_name is None: usage_and_exit("must provide -t argument") if len(args) != 1: usage_and_exit("only one argument allowed (the repository).") repos_path = svn.core.svn_path_canonicalize(args[0]) fs = svn.repos.svn_repos_fs(svn.repos.svn_repos_open(repos_path)) txn = svn.fs.svn_fs_open_txn(fs, txn_name) if check_log_message(txn) and check_for_tags(txn): sys.exit(0) else: sys.exit(1) if __name__ == ''__main__'': sys.exit(svn.core.run_app(main, sys.argv))


No tengo la reputación suficiente para "comentar" la respuesta de Raim, pero funcionó muy bien, con una excepción, su patrón grep está mal.

Simplemente utilicé lo siguiente como mi enlace de precompromiso (no tenía uno existente, necesitaría fusionarse en ese caso):

#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/opt/local/bin/svnlook # Committing to tags is not allowed $SVNLOOK changed -t "$TXN" "$REPOS" | grep "^U/W.*//tags//" && /bin/echo "Cannot commit to tags!" 1>&2 && exit 1 # All checks passed, so allow the commit. exit 0

El único problema con el patrón grep de Raim es que solo coincidía con las "etiquetas" si estaba en la "raíz" de su repositorio. Como tengo varios proyectos en mi repo, el script, tal como lo escribió, permitió confirmaciones en las ramas de las etiquetas.

Además, asegúrese de modificar chmod + x como se indica, de lo contrario, pensará que funcionó, b / c falló la confirmación, pero falló b / c no pudo ejecutar el enganche precompromiso, no porque el gancho funcionó.

Esto fue realmente genial, gracias Raim. ¡Mucho mejor y más ligero que todas las otras sugerencias ya que no tiene dependencias!


Si está utilizando JIRA, puede usar la política de confirmación nombrada del complemento para proteger las rutas en su repositorio sin escribir enlaces personalizados .

¿Cómo? Use la condición llamada Los archivos modificados deben coincidir con un patrón .

Tiene un argumento de tipo de expresión regular que debe coincidir para cada archivo en una confirmación, de lo contrario, se rechaza la confirmación. Entonces, en su caso, debería usar una expresión regular que significa "no comienza con el prefijo / etiquetas /".

(Puede implementar muchas otras verificaciones inteligentes con el mismo complemento).

Descargo de responsabilidad: soy un desarrollador que trabaja en este complemento pago.