pre commit Hook用于阻止大于20MB的提交

时间:2014-12-23 19:14:12

标签: svn hook

是否可以为SVN 1.8编写prcommit挂钩,以避免提交大于~20MB的文件。任何建议,将不胜感激。谢谢 ! 我试过这个,但这不适用于二进制文件或其他文件扩展名

filesize=$($SVNLOOK cat -t $TXN $REPOS $f|wc -c)
if [ "$filesize" -gt "$MAX_SIZE"]
then
    echo "File $f is too large(must <=$MAX_SIZE)" >&2
    exit 1
fi

4 个答案:

答案 0 :(得分:6)

你需要在这里做两件事:

  • 首先使用svn -t$TXN changed获取事务中已更改的路径。您需要过滤掉svn changed/结尾的任何行返回的目录。
  • 对于svn changed中的每个条目,您需要针对它运行svn -t$TXN filesize file。然后,总结文件更改。

像这样的东西。这还没有经过测试,但应该给你一个想法:

total=0
svnlook -t $TXN changed | while read status file
do
    [[ status == "D" ]] && continue  # Ignore deletions
    [[ $file == */ ]] && continue    # Skip directories
    size=$(svnlook -t $TXN filesize $REPOS $file)
    ((total+=size))
done
if [[ $total -gt $maxsize ]]
then
    echo "Commit is too big!" >&2
    exit 1
else
    exit 0
fi

但是,我不喜欢将shell用于钩子脚本。相反,您应该使用像Python或Perl这样的真正的脚本语言。他们更容易使用,更强大,更灵活。

为什么要过滤掉这些大提交?您是否让开发人员尝试提交他们刚刚构建的可执行文件?


懒惰的獾指出你不是在谈论总提交大小,而只是一个文件那么大。如果是这种情况,你可以做一个类似的钩子,但是没有总计:

svnlook -t $TXN changed | while read status file
do
    [[ $status == "D" ]] && continue  # Skip Deletions
    [[ $file == */ ]] && continue     # Skip directories
    size=$(svnlook -t $TXN filesize $REPOS $file)
    if [ $size -gt $maxsize ]]
    then
        echo "File '$file' too large to commit" >&2
        exit 2
    fi
done
exit 0

答案 1 :(得分:2)

阅读svnlook help

使用svnlook changed + svnlook filesize

对懒人的解释

$SVNLOOK filesize -t $TXN $REPOS $f将&#34; ...打印位于$ f&#34;的文件的大小(以字节为单位)。

test-repo的HEAD状态样本

>svnlook filesize Repo trunk/ADExplorer.exe
479096

如果要在预提交挂钩中检查事务中的每个文件,则必须:

获取交易(svnlook changed -t ...

中所有对象的列表
>svnlook changed Repo
A   trunk/ADExplorer.exe
A   trunk/Hlp/
A   trunk/Hlp/AdExplorer.chm

从列表中删除所有非文件实体,因为

>svnlook filesize Repo trunk/Hlp/
svnlook: E160017: Path 'trunk/Hlp' is not a file

将纯文件列表的每个对象传递给svnlook filesize并测试返回的数字

答案 2 :(得分:2)

在任务检查传入事务的大小时,使用svnlook分析文件大小并不总是最佳方法。您的存储库可能已经有“大”文件,用户可能正在对它们进行更改。在预提交钩子脚本中使用svnlook filesize而没有任何特殊逻辑将拒绝对这些文件的修改。

要避免此类问题,请检查磁盘上传入事务的大小?这是一个用PowerShell编写的示例预提交钩子脚本。它检查$repos\db\txn-protorevs\$txn.rev中传入事务的总大小,如果大于100MB,则拒绝提交。

<强> 预commit.ps1

# Store hook arguments into variables with mnemonic names
$repos    = $args[0]
$txn      = $args[1]

# Put commit size limit in bytes
$limit = 1000000

# Prepare error message
$errortxt = ("Commits larger than 100MB are forbidden.")

# Check the size of $txn.rev file and deny the commit if larger than $limit
$item = Get-Item "$repos\db\txn-protorevs\$txn.rev"

if ($item.Length -gt $limit){
  [Console]::Error.WriteLine($errortxt)
  exit 3
}
exit 0

应该从Windows Batch脚本启动用PowerShell编写的Hook脚本。这是一个例子:

<强> 预commit.bat

set PWSH=%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe

%PWSH% -command $input ^| %1\hooks\pre-commit.ps1 %1 %2

if errorlevel 1 exit %errorlevel%

答案 3 :(得分:0)

此问题的当前答案在我们的svn服务器上不起作用。也许在颠覆过程中某些事情发生了变化。

这是我们post-commit挂钩的配置方式:

REPOS="$1"
REV="$2"
MAXSIZE=1048576

# we don't want anyone to know if something went wrong
svnlook changed -r $REV $REPOS | while read status file
do
  [[ $status == "D" ]] && continue  # Skip Deletions
  [[ $file == */ ]] && continue     # Skip directories
  size=$(svnlook filesize -r $REV $REPOS $file)
  if [ $size -gt $MAXSIZE ]]
  then
    #do something if the file is larger than MAXSIZE, in our case just write that file, size and revision to a file
    echo "File '$file' with size '$size' too large to commit.REV: '$REV'" >/tools/svnrepos/file-commits-big-size.txt
  fi
done