문제

태그 하위 디렉터의 변경을 피하는 사전 커밋 후크를 추가하는 방법에 대한 명확한 지침이있는 사람이 있습니까?

나는 이미 인터넷을 꽤 검색했다. 이 링크를 찾았습니다. svn :: 후크 :: denychanges 그러나 나는 물건을 편집 할 수없는 것 같습니다.

도움이 되었습니까?

해결책

위의 Raim의 답변에 대해 "의견"으로 명성이 충분하지 않지만 그의 Grep 패턴은 잘못되었습니다.

나는 단순히 아래를 사전 커밋 후크로 사용했습니다 (기존 후크가 없었 으므로이 경우 병합해야합니다).

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

Raim의 Grep 패턴의 유일한 문제는 Repo의 "루트"에있는 경우 "태그"만 일치한다는 것입니다. Repo에 여러 프로젝트가 있기 때문에 그가 쓴 대본은 태그 브랜치에서 커밋을 허용했습니다.

또한 표시된대로 CHMOD +X를 확신하십시오. 그렇지 않으면 커밋이 실패한 B/C가 작동했다고 생각하지만 B/C 실패는 후크가 작동했기 때문에 사전 커밋 후크를 실행할 수 없었습니다.

정말 대단했습니다. Raim 감사합니다. 의존성이 없기 때문에 다른 모든 제안보다 훨씬 낫고 가벼운 무게!

다른 팁

다음은 태그가 생성 된 후에 태그에 커밋하는 것을 방지하기위한 짧은 쉘 스크립트입니다.

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

이것을 저장하십시오 hooks/pre-commit 전복 저장소의 경우, 실행할 수 있도록하십시오 chmod +x.

다음은 내 Windows 배치 파일 사전 커밋 후크입니다. 사용자가 관리자 인 경우 다른 수표가 건너 뜁니다. 커밋 메시지가 비어 있는지 확인하고 커밋이 태그에 있는지 확인합니다. 참고 : Findstr는 다른 플랫폼의 Grep에 대한 대안입니다.

커밋이 태그에 있는지 확인하는 방식은 먼저 svnlook 변경 사항에 "태그/"가 포함되어 있는지 확인합니다. 그런 다음 svnlook이 일치를 변경했는지 확인합니다. "^a.태그/[^//$ ", 즉 태그/에 새 폴더를 추가하는지 확인합니다.

사용자는 새로운 프로젝트를 만들 수 있습니다. 사전 커밋 후크를 통해 사용자는 폴더 트렁크/ 태그/ 및 분기를 만들 수 있습니다. 사용자는 폴더 트렁크/ 태그/ 및 분기를 삭제할 수 없습니다. 이것은 단일 또는 다중 프로젝트 저장소에 작동합니다.

 @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

이 ANWSER는 날짜 이후에 많은 것이지만 svnlook 변경된 명령에 대한 -copy-info 매개 변수를 발견했습니다.

이 명령의 출력은 세 번째 열에 '+'를 추가하므로 사본임을 알 수 있습니다. 태그 디렉토리에 대한 커밋을 확인할 수 있으며 '+'선물로만 커밋을 허용 할 수 있습니다.

출력을 추가했습니다 내 블로그 게시물.

파티에 꽤 늦었지만 Log-Police.py 스크립트를 기반으로하는 작업용 Python Pre-Commit Hook을 썼습니다. http://subversion.tigris.org/.

이 스크립트는 원하는 작업을 수행해야하지만 로그 메시지가 존재하는지 확인하지만 스크립트에서 쉽게 제거해야합니다.

일부 경고 :

  • 나는 Python을 처음 접했기 때문에 더 잘 작성 될 수 있습니다.
  • Python 2.5 및 Subversion 1.4로 Windows 2003에서만 테스트되었습니다.

요구 사항 :

  • 파괴
  • 파이썬
  • 파이썬에 대한 전복 바인딩

마지막으로 코드 :

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

몇 가지 사례가 다루지 않기 때문에 이전에 쓰여진 스크립트의 대부분은 불완전합니다. 이것은 내 대본입니다.

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

복잡해 보이지만 당신이 /tags 그리고 당신은 창조 할 수 있습니다 /tags 존재하지 않는 경우 모든 후속 폴더. 다른 변화가 차단됩니다. 이전 스크립트 중 거의 아무도 Subversion Book에 설명 된 모든 사례를 다루지 않습니다. svnlook changed ....

허용 된 답변은 태그의 파일 업데이트를 방지하지만 태그에 파일을 추가하는 것을 방지하지는 않습니다. 다음 버전은 다음을 모두 처리합니다.

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

내 버전에서는 태그 만 만들고 삭제할 수 있습니다. 이렇게하면 파일 추가, 속성 변경 등의 모든 특수 사례를 처리해야합니다.

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

JIRA를 사용하는 경우 이름이 부가 기능을 사용할 수 있습니다. 커밋 정책 저장소의 경로를 보호합니다 커스텀 훅을 쓰지 않고.

어떻게? 이름이 지정된 조건을 사용하십시오 변경된 파일은 패턴과 일치해야합니다.

커밋의 모든 파일에 대해 일치 해야하는 정규 표현식 유형 인수가 있습니다. 그렇지 않으면 커밋이 거부됩니다. 따라서 귀하의 경우 "접두사 /태그 /로 시작하지 않는다"는 것을 의미하는 REGEX를 사용해야합니다.

(동일한 플러그인으로 다른 많은 스마트 체크를 구현할 수 있습니다.)

면책 조항 : 저는이 유료 애드온에서 작업하는 개발자입니다.

첫 번째 답변은 ADD/SUPPR 파일을 방지하지 못하고 새로운 태그 생성을 방해했으며, 불완전하거나 버그가 불완전한 곳이 많았 기 때문에 재 작업했습니다.

내 사전 커밋 후크는 다음과 같습니다. 목표는 다음과 같습니다.

  • 태그에 대한 커밋 허용 (파일 추가/억제/업데이트)
  • 태그 생성을 방해하지 마십시오

--------- "Pre-Commit"(저장소에 넣습니다 후크 폴더) ---------

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

---------- 파일의 끝 "사전 커밋"--------

또한 SVN의 모든 프로젝트에서 후크를 복사하기 위해 2 개의 쉘 스크립트를 만들었습니다.

--------- 스크립트 "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

---------- 파일의 끝 "setonEREPOTAGSREADONLY.SH"--------

그리고 하나는 모든 저장소를 위해 그것을 부르고, 모든 저장소를 읽게합니다.

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

---------- 파일의 끝 "Maketagsreadonly.sh"--------

SVN "루트"(/var/svn/repos/svn, 내 경우)에서 직접 스크립트를 실행합니다. BTW, CRON 작업은 매일 Thoses 스크립트를 실행하여 새 저장소를 자동으로 수정하도록 설정할 수 있습니다.

도움이되기를 바랍니다.

나열된 답변은 훌륭하지만 내가 필요로하는 것을 정확히하지 못했습니다. 태그를 쉽게 만들고 싶지만 일단 생성되면 완전히 읽기 전용이어야합니다.

또한 이렇게하면 어리석은 상황을 막고 싶습니다.

svn copy myrepo/trunk myrepo/tags/newrelease

모든 것이 처음입니다. 그러나 두 번째로, 태그가 이미 존재한다면, 당신은 끝날 것입니다 myrepo/tags/newrelease/trunk.

내 사전 커밋 후크는 기존 SVN 디렉토리 일치를 찾을 것입니다. (repo)/tags/(tag)/ 발견되면 실패합니다.

$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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top