Frage

Gibt es jemanden, klare Anweisungen hat, wie man ein pre-commit Haken hinzuzufügen, die Änderungen von Variablen Unterverzeichnisse vermeidet?

Ich suchte das Internet bereits eine ganze Menge. Ich fand diesen Link: SVN :: Hooks :: DenyChanges , aber ich kann‘ t scheinen, um die Dinge zu kompilieren.

War es hilfreich?

Lösung

Ich habe nicht genug Ruf „Kommentar“ auf Raim Antwort oben, aber sein großen gearbeitet, mit einer Ausnahme, sein grep Muster ist falsch.

Früher habe ich einfach den unten als meine pre-commit Haken (ich habe nicht ein vorhandenes haben, müssten Sie in diesem Fall fusionieren):

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

Das einzige Problem mit Raim des grep Muster ist, dass es nur „Tags“ abgestimmt, wenn es an der „Wurzel“ des Repo ist. Da ich mehrere Projekte in meinem Repo haben, das Skript als er schrieb es Commits auf Tag-Filialen erlaubt.

Auch sollten Sie + chmod x wie angegeben, sonst werden Sie denken, es funktionierte b / c der gescheiterte commit, aber es versäumt b / c es nicht die pre-commit Haken exec könnte, nicht weil der Haken gearbeitet .

Das war wirklich toll, danke Raim. Viel besser und leichter als alle anderen Vorschläge, wie es keine Abhängigkeiten hat!

Andere Tipps

Hier ist eine kurze Shell-Skript zu begehen, um Tags zu verhindern, nachdem sie erstellt wurden:

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

Speichern Sie diese bei hooks/pre-commit für Ihre Subversion-Repository und es mit chmod +x ausführbar machen.

Hier ist meine Windows-Batch-Datei pre-commit Haken. Wenn der Benutzer ein Administrator ist, werden die anderen Kontrollen übersprungen werden. Es prüft, ob die Commit-Nachricht leer ist, und wenn das zu einem Tag zu begehen ist. Hinweis:. Findstr ist eine regeltreue Alternative auf anderen Plattformen grep

Die Art und Weise überprüft, ob das zu einem Tag begeht, ist es zunächst überprüft, ob svnlook geändert „Markierungen /“. Es prüft dann, ob svnlook geändert matches "^ A. -Tags / [^ /] / $", was bedeutet, dass es, wenn Sie einen neuen Ordner unter Tags hinzufügen /.

Benutzer dürfen neue Projekte erstellen. Die pre-commit Haken ermöglicht es einem Benutzer die Ordner trunk / tags / und Verzweigungen / zu erstellen. Benutzer sind nicht erlaubt die Ordner trunk / Tags löschen / und Verzweigungen /. Dies funktioniert für eine ein- oder mehr Projekt-Repository.

 @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

Dieses anwser ist viel nach Datum, aber ich entdeckte die --copy-Info-Parameter für den Befehl svnlook geändert.

Die Ausgabe dieses Befehls fügt ein ‚+‘ in der dritten Spalte, so dass Sie wissen, dass es eine Kopie ist. Sie können auf die Tags Verzeichnis für Commits überprüfen, und nur Commits erlauben, mit einem ‚+‘ vor.

Ich habe eine Ausgabe in .

Pretty spät zur Party, aber schrieb ich eine Python-pre-commit Haken für die Arbeit, die das log-police.py Skript basiert weg auf http://subversion.tigris.org/ .

Dieses Skript sollte das tun, was Sie wollen, aber es überprüft auch, dass eine Log-Nachricht vorhanden ist, aber das sollte einfach sein aus dem Skript zu entfernen.

Einige Einschränkungen:

  • Ich bin neu in Python, so dass es sehr wahrscheinlich geschrieben werden könnte besser
  • Es hat sich nur auf Windows 2003 mit Python 2.5 und Subversion 1.4 getestet.

Anforderungen:

  • Subversion
  • Python
  • Subversion-Bindings für Python

Schließlich ist der 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))

Die meisten der zuvor geschriebenen Skripte sind unvollständig, da mehrere Fälle nicht erfasst werden. Das ist mein Skript:

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

Es könnte kompliziert erscheinen, aber Sie müssen sicherstellen, dass Sie in /tags sind und Sie /tags erlaubt zu erstellen, wenn es nicht vorhanden ist und alle folgenden Ordner. Jede andere Änderung ist gesperrt. Fast keiner der vorherigen Skripte decken alle Fälle im Subversion Buch für svnlook changed ... beschrieben.

Die akzeptierte Antwort verhindert, dass Dateien in einem Tag zu aktualisieren, aber nicht daran hindert, Dateien auf einen Tag hinzuzufügen. Die folgende Version behandelt beide:

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

nur Meine Version erlaubt das Erstellen und Löschen von Tags. Dies sollte alle Sonderfälle behandelt (wie Dateien hinzufügen, ändern Eigenschaften, usw.).

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

Wenn Sie JIRA verwenden, können Sie das Add-on verwenden Namen Politik Commit Pfade in Ihrem Repository zu schützen ohne individuellen Haken schreiben .

Wie? Verwenden Sie die Bedingung genannt Changed Dateien müssen ein Muster entsprechen.

Es verfügt über einen regulären Ausdruck Typ Argument, das für jede Datei in einem verpflichten müssen übereinstimmen, da sonst die commit wird abgelehnt. Also, in Ihrem Fall sollten Sie einen regulären Ausdruck verwenden, das bedeutet „beginnt nicht mit dem Präfix / tags /".

(Sie können viele andere intelligente Kontrollen mit der gleichen Plugin implementieren.)

Disclaimer:. Ich bin ein Entwickler auf diesen bezahlt Add-on arbeitet

Da die erste Antwort nicht Add- / suppr Dateien verhindern und neue Tags Schaffung verhindert, und viele andere, wo unvollständig oder fehlerhaft, ich überarbeitete es

Hier ist mein pre-commit Haken: Ziele sind:

  • Disallow verpflichtet auf Tags (Datei / bei Unterdrückung / Updates)
  • Sie nicht Erstellung von Tags verhindern

--------- Datei "pre-commit" (put in Repositories Haken Ordner) ---------

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

--------- Ende der Datei "pre-commit" ---------

Auch habe ich zwei Shell-Skripten meine Haken in jedem Projekt von meinem SVN zu kopieren: Ein ein Repo nur lesen setzen:

--------- Skript "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

--------- Ende der Datei "setOneRepoTagsReadOnly.sh" ---------

Und man es für jeden Repo-Aufruf an alle meine repos nur lesbar zu machen:

--------- Datei "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' \{\} \;

--------- Ende der Datei "makeTagsReadOnly.sh" ---------

I thoses Skripte direkt aus dem SVN "root" (/ var / svn / repos / svn, in meinem Fall) auszuführen. Btw, könnte eine Crontask automatisch eingestellt werden, um neue repos zu ändern, indem thoses Skripte täglich Ausführen

Hoffe, es hilft.

Die aufgeführten Antworten sind groß, aber keiner tat genau das, was ich brauche. Ich mag Tags ermöglichen leicht zu schaffen, aber sobald sie erstellt werden, sollten sie vollständig schreibgeschützt sein.

Ich mag auch die dumme Situation zu verhindern, wo, wenn Sie dies tun:

svn copy myrepo/trunk myrepo/tags/newrelease

Alles ist gut das erste Mal. Aber das zweite Mal, wenn der Tag bereits vorhanden ist, werden Sie mit myrepo/tags/newrelease/trunk enden.

Mein pre-commit Haken für jeden bereits bestehenden SVN Verzeichnisanpassungs (repo)/tags/(tag)/ aussehen wird und fehlschlagen, wenn es gefunden:

$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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top