英文:
Reject commit of PDF files for Tortoise (Windows)
问题
在我们的存储库中,用户意外提交了几个PDF文件,现在存储库的大小相当大。而且在存储这种二进制文件没有用。
我尝试过使用设置/全局忽略模式:
*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo __pycache__ *.rej *~ #*# .#* .*.swp .DS_Store [Tt]humbs.db *.pdf
但是我仍然能够成功添加一个PDF文件并提交它。
我期望由于这个设置,提交会被阻止。是否有其他阻止存储库中的PDF文件的方法?
英文:
In our repository, a user has accidentally committed several PDF's and now the size of the repo is quite big. And it's not useful to have this sort of binary files there.
I've tried with Settings/Global ignore pattern:
*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo __pycache__ *.rej *~ #*# .#* .*.swp .DS_Store [Tt]humbs.db *.pdf
But I was still able to add a PDF file and to commit it successfully.
I expected that the commit is blocked because of the setting. Is there another way to block PDF's for the repository?
答案1
得分: 1
以下是代码的翻译部分:
借助您的帮助,我成功实现了以下功能。
它会阻止存储库中的PDF和HTML文件。
批处理文件位于hooks文件夹中。
@echo off
::
:: 阻止具有空日志消息的提交。
::%REPOROOT%\hooks\pre-commit.bat
setlocal
rem Subversion将存储库路径和事务ID传递过来
set svnlook="C:\Program Files\TortoiseSVN\bin\"
set REPOS=%1
set TXN=%2
set TXN_NAME=%3
SET ThisScriptsDirectory=%~dp0
svnlook changed -t %2 %1 | findstr \.html >nul
if %errorlevel% equ 0 goto err
svnlook changed -t %2 %1 | findstr \.pdf >nul
if %errorlevel% equ 0 goto err
exit 0
:err
svnlook changed -t %2 %1 | findstr \.html >%~dp0%USERNAME%_pre-commit.txt
svnlook changed -t %2 %1 | findstr \.pdf >>%~dp0%USERNAME%_pre-commit.txt
echo. 1>&2
echo 由于您尝试提交无效文件(HTML、PDF等),您的提交已被阻止。 1>&2
echo 请不要在版本控制中使用PDF文件。二进制文件和HTML文件无法在存储库中进行比较。-- 谢谢 1>&2
exit 1
希望这对您有所帮助。如果您有任何其他问题,请随时提出。
英文:
With your help, i was able to implement the following.
Its blocking PDFs and HTMLs from the repository.
The batch file is in the hooks folder.
@echo off
::
:: Stops commits that have empty log messages.
::%REPOROOT%\hooks\pre-commit.bat
setlocal
rem Subversion sends through the path to the repository and transaction id
set svnlook= "C:\Program Files\TortoiseSVN\bin\"
set REPOS=%1
set TXN=%2
set TXN_NAME=%3
SET ThisScriptsDirectory=%~dp0
svnlook changed -t %2 %1 | findstr \.html >nul
if %errorlevel% equ 0 goto err
svnlook changed -t %2 %1 | findstr \.pdf >nul
if %errorlevel% equ 0 goto err
exit 0
:err
svnlook changed -t %2 %1 | findstr \.html >%~dp0%USERNAME%_pre-commit.txt
svnlook changed -t %2 %1 | findstr \.pdf >>%~dp0%USERNAME%_pre-commit.txt
echo. 1>&2
echo Your commit has been blocked because you tried to commit an invalid file 1>&2
echo (HTML, PDF, ..). 1>&2
echo Please don't use PDF's in the version control. Binary files and HTMLs 1>&2
echo cannot be compared in the repository. -- Thank you 1>&2
exit 1
答案2
得分: 0
为什么忽略模式不起作用
全局忽略模式没有效果,因为您仍然可以明确添加文件。这在《红豆书》中的“忽略文件”章节中有描述。全局和每个目录的忽略旨在清除视图中的工件、交换文件等。
引入 pre-commit 钩子
为了防止某些文件被提交到版本库,Subversion 提供了钩子脚本。这些脚本在特定事件发生时在版本库服务器上运行。要防止提交,请使用pre-commit 钩子。
阅读 svnadmin
在任何新版本库中放置的钩子模板。以下相关问题的答案也可能有所帮助:
https://stackoverflow.com/questions/819874/how-do-i-implement-an-svn-hook-to-know-the-filename-of-the-file-committed-etc 和 https://stackoverflow.com/questions/17790484/svn-server-pre-commit-hook-know-the-list-of-files-that-are-being-committed
钩子可以是任何类型的可执行文件,通常是shell脚本或批处理文件。从钩子调用任何其他脚本或程序都是可能的,因此几乎没有限制。
根据版本库托管在Windows还是* NIX系统上以及您选择的(脚本)语言,脚本的外观将会有很大不同。我可以提供大纲和一些指导。随时发布另一个具体实现的答案。
要实现的算法是:
- 获取提交事务
- 在事务上使用
svnlook
获取文件名(例如*.pdf
)或二进制文件 - 如果有问题,向
stderr
写入消息并返回非零退出代码
为了完整起见,让我们提一下,TortoiseSVN提供了客户端提交钩子。我几乎认为这不是一个解决方案,因为它似乎同时提供了两个世界中的最坏的部分。
纯技术解决方案的不足之处
问题解决了吗?几乎没有。还记得上次你的邮件客户端告诉你通过电子邮件发送foo.exe
是“不安全的”吗?当然,你立刻将那个家伙重命名为foo.exe.txt
并发送了!
这就是您的用户会做的事情。同样,当您创建官方政策“不得提交PDF文件”时,您创建了一项非正式政策“在提交之前重命名PDF文件”。
不相信?假设您想集成第三方库。您获得了二进制库文件和PDF格式的API文档。最好将所有这些内容放在一个地方,正确的版本中……在您的版本库中。只是您不能,因为您禁止了二进制文件和/或PDF文件。
最后一个想法…
无论您选择是否实施pre-commit钩子,都应该向用户传达原因。如果不知道为什么提交二进制文件是不好的(而且它真的不好吗?),任何限制都会看起来像是阻碍他们工作的障碍。让他们理解,您将不需要钩子脚本。
问题中突出的一句话是有人“意外提交”了某些东西。没有人应该接受事情是偶然发生的。
您应该调查为什么提交了这些文件。我立刻可以想到三个原因:
-
粗心大意。仔细审查自己的更改在专业行为上是很重要的。进行所有更改的同行审查甚至更好,并防范许多陷阱。
-
用户不熟悉TortoiseSVN(毫不奇怪,现在每个人都在使用Git)。对如何使用工具的培训可能是一个不错的投资。
-
用户认为这是正确的做法。建立一些关于您希望在版本控制中拥有什么和不拥有什么的共同理解。
英文:
Why ignore patterns don't work
The global ignore pattern has no effect because you can still explicitly add files. This is described in the Red Bean Book, Chapter on Ignoring Files. Global and per-directory ignores are intended to clear the view from artifacts, swap files, etc.
Introducing the pre-commit hook
To prevent certain files to be committed to the repository, Subversion offers hook scripts. These are run on the repository server when a certain event happens. To prevent a commit, use the pre-commit hook.
Read the hook templates that svnadmin
puts in any new repository.
Answers to the following, related questions may also help:
https://stackoverflow.com/questions/819874/how-do-i-implement-an-svn-hook-to-know-the-filename-of-the-file-committed-etc and https://stackoverflow.com/questions/17790484/svn-server-pre-commit-hook-know-the-list-of-files-that-are-being-committed
Hooks can be any kind of executables, usually shell scripts or batch files. It's possible to call any other script or program from a hook so there's hardly a limit to what one can do.
Depending on whether the repository is hosted on a Windows or *NIX box and what your (scripting) language of choice is, the script will look very different. I can give the outline and some pointers. Feel free to post another answer with a concrete implementation.
The algorithm to implement is:
- Get commit transaction
- Use
svnlook
on the transaction to get file names (e.g.*.pdf
) or the if it's a binary file - If offending, write a message to
stderr
and return a non-zero exit code
For the sake of completeness, let's mention that TortoiseSVN offers client side commit hooks. I hardly think that's a solution since it seems to offer the worst of both worlds.
The shortcomings of a purely technical solution
Problem solved? Hardly. Remember the last time your mail client told you it was "insecure" to send foo.exe
by e-mail? Of course you immediately renamed that sucker to foo.exe.txt
and sent it anyway!
That's what your users will do. The same time you create an official policy "you must not commit PDF files" you create an inofficial policy "rename PDF files before committing them".
Not convinced? Assume you want to integrate a third-party library. You get the binary lib file and the API documentation as PDF. Better to have all of this in one place, in the correct version ... in your repository. Only you can't because you outlawed binary files and/or PDF files.
One last thought ...
Whether or not you choose to implement a pre-commit hook, you should communicate the reasons to your users. Without knowing why committing binary files is bad (and is it really?) any kind of restriction will just seem like an obstacle thrown in their way to keep them from doing their work. Make them understand and you won't need a hook script.
The one sentence that sticks out in the question is that somebody "accidentally committed" something. Nobody should accept that things happen by accident.
You should investigate why those files were committed. I can immediately think of three reasons:
-
Sloppiness. It's a matter of professional conduct to carefully review your own changes before committing them. Having all changes peer reviewed is even better and guards against many more pitfalls.
-
The user was not familiar with TortoiseSVN (not surprisingly, everybody is using Git these days). Some training on how to use the tools might be a good investment.
-
The user thought it was the right thing to do. Build some common understanding on what you want have in version control and what not.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论