40 votes

Crochet de pré-validation SVN pour éviter les modifications des sous-répertoires de balises

Quelqu'un a-t-il des instructions claires sur la manière d'ajouter un point d'ancrage de pré-validation qui évite les modifications des sous-répertoires de balises?

J'ai déjà un peu cherché sur Internet. J'ai trouvé ce lien: SVN :: Hooks :: DenyChanges , mais je n'arrive pas à compiler les choses.

39voto

apinstein Points 1401

Je n'ai pas assez réputation de "commentaire" sur Raim la réponse ci-dessus, mais son très travaillé, avec une seule exception, son grep motif est erroné.

J'ai simplement utilisé le ci-dessous comme mon pre-commit hook (je n'ai pas un existant, vous aurez besoin de fusionner dans ce cas):

#!/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

Le seul problème avec Raim du grep motif, c'est qu'il n'a d'égale que "tags" si c'était à la "racine" de votre pension. Depuis que j'ai plusieurs projets dans mon repo, le script comme il l'a écrit autorisé s'engage sur la balise de branches.

Aussi, assurez-vous de faire un chmod +x comme indiqué, sinon vous allez croire qu'il a travaillé b/c de la validation a échoué, mais il a échoué b/c il ne pouvait pas exec le pre-commit hook, non pas parce que le crochet a travaillé.

C'était vraiment génial, merci Raim. Beaucoup mieux et plus léger que tous les autres suggestions comme il n'a pas de dépendances!

16voto

Raim Points 2335

Voici un court script shell pour empêcher la validation des tags après leur création:

 #!/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
 

Enregistrez ceci à hooks/pre-commit pour votre référentiel Subversion et rendez-le exécutable avec chmod +x .

7voto

mcdon Points 1690

Voici mon fichier de commandes windows pre-commit hook. Si l'utilisateur est un administrateur les autres contrôles seront ignorés. Il vérifie si le message de commit est vide, et si la validation est à une balise. Remarque: findstr est un nerfed alternative à un grep sur d'autres plates-formes.

La façon dont il vérifie si la validation est d'une balise, il vérifie d'abord si svnlook changé contient des "tags/". Il vérifie ensuite si svnlook changé correspond à "^A.tags/[^/]/$", ce qui signifie qu'il va vérifier si l'ajout d'un nouveau dossier dans tags/.

Les utilisateurs sont autorisés à créer de nouveaux projets. Le pre-commit hook permet à un utilisateur de créer les dossiers trunk/ tags/ branches et/. Les utilisateurs ne sont pas autorisés à supprimer les dossiers trunk/ tags/ branches et/. Cela fonctionne pour un seul ou plusieurs de dépôt de projet.

 @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

6voto

coudenysj Points 315

Cette réponse est beaucoup après la date, mais j’ai découvert le paramètre --copy-info pour la commande svnlook modified.

La sortie de cette commande ajoute un '+' dans la troisième colonne, vous savez donc qu'il s'agit d'une copie. Vous pouvez vérifier les commits dans le répertoire des tags et n'autoriser que les commits avec un '+'.

J'ai ajouté une sortie dans mon article de blog .

4voto

Nick Brooks Points 126

Assez en retard à la fête, mais j'ai écrit un python pre-commit hook pour le travail qui est basée sur la log-police.py script sur http://subversion.tigris.org/.

Ce script devrait faire ce que vous voulez, mais il vérifie également qu'un message de journal existe, même si cela devrait être facile à retirer à partir du script.

Quelques mises en garde:

  • Je suis nouveau sur Python, donc il est probable qu'il pourrait être mieux écrit
  • Il a seulement été testé sur Windows 2003 avec Python 2.5 et Subversion 1.4.

Exigences:

  • Subversion
  • Python
  • Subversion liaisons Python

Enfin, le code:

#!/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))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X