SVN Pre-commit hook do unikania zmian w podkatalogach tagów

Czy jest ktoś, kto ma jasne instrukcje jak dodać hook przed zatwierdzeniem, który unika zmian w podkatalogach tagów?

Przeszukałem już sporo Internetu. Znalazłem ten link: SVN::Hooks::DenyChanges , ale nie mogę skompilować rzeczy.

Author: szabgab, 2009-01-21

11 answers

Nie mam wystarczającej reputacji, aby "skomentować" powyższą odpowiedź Raima, ale jego praca była świetna, z jednym wyjątkiem, jego wzór grepa jest zły.

Po prostu użyłem poniższego Hooka jako haka przed zatwierdzeniem (nie miałem istniejącego, w takim przypadku trzeba by się połączyć):

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

Jedyny problem ze wzorcem grep Raima polega na tym, że pasuje on tylko do "tagów", jeśli znajdował się w" korzeniu " twojego repo. Ponieważ mam kilka projektów w moim repo, skrypt jak napisał pozwalał na commity na tagu gałęzie.

Również, upewnij się, że chmod +x jak wskazano, w przeciwnym razie pomyślisz, że zadziałało b/c zatwierdzenie nie powiodło się, ale nie powiodło się b / c, że nie można było uruchomić haka przed zatwierdzeniem, nie dlatego, że hook zadziałał.

To było naprawdę świetne, dzięki Raim. Znacznie lepsza i lżejsza waga niż wszystkie inne sugestie, ponieważ nie ma żadnych zależności!
 38
Author: apinstein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-15 22:58:40

Oto krótki skrypt powłoki zapobiegający zatwierdzaniu tagów po ich utworzeniu:

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

Zapisz to w hooks/pre-commit dla swojego repozytorium Subversion i utwórz je jako wykonywalne za pomocą chmod +x.

 16
Author: raimue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-23 01:16:22

Oto mój plik wsadowy Windows Pre-commit hook. Jeśli użytkownik jest administratorem, Pozostałe kontrole zostaną pominięte. Sprawdza, czy komunikat commit jest pusty i czy jest przypisany do znacznika. Uwaga: findstr to nerfed alternatywa dla grepa na innych platformach.

Sposób, w jaki sprawdza, czy commit jest przypisany do znacznika, najpierw sprawdza, czy svnlook changed zawiera "tags/". Następnie sprawdza, czy svnlook zmienił dopasowania " ^A. Tagi/[^/]/$", co oznacza, że sprawdzi, czy dodajesz nowy folder pod tagami/.

Użytkownicy mogą tworzyć nowe projekty. Hak przed zatwierdzeniem pozwala użytkownikowi na utworzenie folderów trunk / tags / i branches/. Użytkownicy nie mogą usuwać folderów trunk / tags / i branches/. Będzie to działać dla repozytorium jednego lub wielu projektów.

 @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
 7
Author: mcdon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-23 17:46:54

Ten anwser jest dużo po dacie, ale odkryłem parametr --copy-info dla Komendy svnlook changed.

Wyjście tego polecenia dodaje " + " w trzeciej kolumnie, więc wiesz, że jest to Kopia. Możesz sprawdzić commity w katalogu tags i zezwolić na commity tylko z obecnością'+'.

Dodałem jakieś wyjście w mój wpis na blogu .

 6
Author: coudenysj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-20 07:17:45

Dość późno na imprezę, jednak napisałem Python pre-commit hook do pracy, który jest oparty na log-police.py skrypt na http://subversion.tigris.org/.

Ten skrypt powinien robić to, co chcesz, ale sprawdza również, czy istnieje komunikat dziennika, chociaż powinien być łatwy do usunięcia ze skryptu.

Niektóre zastrzeżenia:

  • jestem nowy w Pythonie, więc najprawdopodobniej można by go napisać lepiej
  • został przetestowany tylko na Windows 2003 z Pythonem 2.5 i Subversion 1.4.

Wymagania:

  • Subversion
  • Python
  • Subversion bindings for Python

Wreszcie kod:

#!/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))
 4
Author: Nick Brooks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-30 23:30:45

Przyjęta odpowiedź uniemożliwia aktualizację plików w tagu, ale nie uniemożliwia dodawania plików do tagu. Następująca wersja obsługuje oba:

#!/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
 3
Author: Vinay Sahni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-19 15:38:05

Większość wcześniej napisanych skryptów jest niekompletna, ponieważ kilka przypadków nie jest objętych. To jest mój skrypt:

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

Może to wydawać się skomplikowane, ale musisz upewnić się, że jesteś w /tags i możesz utworzyć /tags, jeśli nie istnieje i wszystkie kolejne foldery. Wszelkie inne zmiany są blokowane. Prawie żaden z poprzednich skryptów nie obejmuje wszystkich przypadków opisanych w książce Subversion dla svnlook changed ....

 3
Author: Michael-O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 08:46:58

Jeśli używasz JIRA, możesz użyć dodatku o nazwie Commit Policy do ochrony ścieżek w repozytorium bez pisania własnych hooków.

Jak? Użyj warunku o nazwie zmienione pliki muszą pasować do wzorca.

MA argument typu wyrażenia regularnego, który musi pasować do każdego pliku w zatwierdzeniu, w przeciwnym razie zatwierdzenie zostanie odrzucone. Tak więc, w Twoim przypadku powinieneś użyć wyrażenia regularnego, które oznacza " nie zaczyna się od prefiksu / tags/".

(Ty może zaimplementować wiele innych inteligentnych kontroli za pomocą tej samej wtyczki.)

Zastrzeżenie: jestem programistą pracującym nad tym płatnym dodatkiem.

 1
Author: Ferenc Kiss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-26 16:05:23

Moja wersja pozwala tylko na tworzenie i usuwanie tagów. To powinno obsłużyć wszystkie specjalne przypadki (jak dodawanie plików, zmiana właściwości, itp.).

#!/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
 0
Author: Marián Černý,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-11 14:42:03

Wymienione odpowiedzi są świetne, ale żadna nie zrobiła dokładnie tego, czego potrzebuję. Chcę umożliwić łatwe tworzenie tagów, ale po ich utworzeniu powinny być w pełni tylko do odczytu.

Chcę również zapobiec głupiej sytuacji, w której jeśli to zrobisz:

svn copy myrepo/trunk myrepo/tags/newrelease
Wszystko jest dobrze za pierwszym razem. Ale za drugim razem, jeśli znacznik już istnieje, skończysz z myrepo/tags/newrelease/trunk.

Mój hook przed zatwierdzeniem będzie szukał dowolnego istniejącego katalogu SVN pasującego (repo)/tags/(tag)/ i nie powiedzie się, jeśli zostanie znaleziony:

$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
 0
Author: grue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-18 15:44:36

Ponieważ pierwsza odpowiedź Nie uniemożliwiała dodawania / suppr plików i uniemożliwiała tworzenie nowych tagów, a także wielu innych, gdzie niekompletne lub błędne, przerobiłem ją

Oto mój hak przed commit : Cele to:

  • Disallow commits on tags (dodawanie/supresja/aktualizacje plików)
  • nie zapobiegaj tworzeniu tagów

--------- Plik "pre-commit" (umieścić w repozytoriach folder) ---------

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

--------- koniec pliku " PRE-commit" ---------

Ponadto, zrobiłem 2 skrypty powłoki, aby skopiować mój hook w każdym projekcie mojego svn : Jeden do Ustawienia repo tylko do odczytu:

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

--------- koniec pliku "setOneRepoTagsReadOnly.sh" ---------

I jeden dzwoni do każdego repo, aby wszystkie moje repo były tylko odczytywane:

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

--------- koniec pliku "makeTagsReadOnly.sh" ---------

I wykonuj Skrypty bezpośrednio z svn "root" (/var/svn/repos / svn, w moim przypadku). Btw, zadanie cron może być ustawione, aby automatycznie modyfikować nowe repozytoria, wykonując Skrypty thoses codziennie

Mam nadzieję, że to pomoże.
 0
Author: Balmipour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-14 00:02:13