SVN pre-commit hook for avoiding changes to tags subdirectories

前端 未结 11 569
陌清茗
陌清茗 2020-11-28 04:25

Is there anybody who has clear instructions on how to add a pre-commit hook that avoids changes to tags subdirectories?

I already searched the internet quite a bit.

相关标签:
11条回答
  • 2020-11-28 05:04

    Most of the previously written scripts are incomplete because several cases are not covered. This is my script:

    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
    

    It might seem complicated but you have to make sure that you are in /tags and you are allowed create /tags if it does not exist and all subsequent folders. Any other change is blocked. Almost none of the previous scripts cover all cases described in the Subversion book for svnlook changed ....

    0 讨论(0)
  • 2020-11-28 05:04

    If you are using JIRA, you can use the add-on named Commit Policy to protect paths in your repository without writing custom hooks.

    How? Use the condition named Changed files must match a pattern.

    It has an regular expression type argument that must match for every file in a commit, otherwise the commit is rejected. So, in your case you should use a regex that means "does not start with the prefix /tags/".

    (You can implement many other smart checks with the same plugin.)

    Disclaimer: I'm a developer working on this paid add-on.

    0 讨论(0)
  • 2020-11-28 05:06

    This anwser is a lot after date, but I discovered the --copy-info parameter for the svnlook changed command.

    The output of this command adds a '+' in the third column, so you know it is a copy. You can check for commits to the tags directory, and only allow commits with a '+' present.

    I've added some output in my blog post.

    0 讨论(0)
  • My version only allows creating and deleting tags. This should handle all the special cases (like adding files, changing properties, 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
    
    0 讨论(0)
  • 2020-11-28 05:11

    Here is my windows batch file pre-commit hook. If the user is an administrator the other checks will be skipped. It checks if the commit message is empty, and if the commit is to a tag. Note: findstr is a nerfed alternative to grep on other platforms.

    The way it checks if the commit is to a tag, it first checks if svnlook changed contains "tags/". It then checks if svnlook changed matches "^A.tags/[^/]/$", which means that it will check if you are adding a new folder under tags/.

    Users are allowed to create new projects. The pre-commit hook allows a user to create the folders trunk/ tags/ and branches/. Users are not allowed to delete the folders trunk/ tags/ and branches/. This will work for a single or multi-project 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
    
    0 讨论(0)
提交回复
热议问题