使用TortoiseSVN的预提交钩子防止误提交

在软件开发过程中,经常需要临时添加一些代码来调试程序,但这些代码并不应该被提交到版本库中。然而,有时候由于疏忽,这些临时代码可能会被不小心提交。幸运的是,TortoiseSVN提供了一种机制,即预提交钩子(pre-commit hook),可以帮助避免这种情况的发生。

预提交钩子是一种在用户点击“提交”按钮时运行的程序或脚本。它可以检查修改文件的内容,并在适当的时候阻止提交。与Subversion钩子不同,Tortoise钩子是在本地执行的,而不是在托管仓库的服务器上。这意味着不需要担心钩子是否会被管理员接受,或者它是否在服务器上工作(例如,服务器可能没有安装.NET),也不会影响其他仓库用户的经验。客户端钩子也更快。

关于钩子的详细描述可以在Tortoise帮助文件的“4.30.8.客户端钩子脚本”章节中找到。Tortoise支持7种类型的钩子:开始提交、预提交、提交后、开始更新、预更新、更新后和预连接。关注的是预提交动作。钩子的本质是检查添加或修改的文件中是否包含临时代码标记。标记可能是放在临时代码上方的注释中的“NOT_FOR_REPO”文本。

以下是整个钩子的代码——一个简单的控制台应用程序,可能会救一命。

using System; using System.IO; using System.Text.RegularExpressions; namespace NotForRepoPreCommitHook { class Program { const string NotForRepoMarker = "NOT_FOR_REPO"; static void Main(string[] args) { string[] affectedPaths = File.ReadAllLines(args[0]); Regex fileExtensionPattern = new Regex(@"^.*\.(cs|js|xml|config)$", RegexOptions.IgnoreCase); foreach (string path in affectedPaths) { if (fileExtensionPattern.IsMatch(path) && File.Exists(path)) { if (ContainsNotForRepoMarker(path)) { string errorMessage = string.Format("{0} marker found in {1}", NotForRepoMarker, path); Console.Error.WriteLine(errorMessage); Environment.Exit(1); } } } } static bool ContainsNotForRepoMarker(string path) { StreamReader reader = File.OpenText(path); try { string line = reader.ReadLine(); while (line != null) { if (line.Contains(NotForRepoMarker)) { return true; } line = reader.ReadLine(); } } finally { reader.Close(); } return false; } } }

TSVN调用预提交钩子时会传递四个参数。只对第一个参数感兴趣。它包含了一个路径到*.tmp文件。在这个文件中,有一个当前提交影响的文件列表。每行是一个路径。加载列表后,文件会根据扩展名进行过滤(如果不想处理所有类型的文件,这很有用)。检查文件是否存在也很重要——*.tmp文件中的列表包含了删除的文件路径!通过NotForRepoMarker常量表示的标记是通过ContainsNotForRepoMarker方法实现的。尽管它很简单,但它提供了良好的性能。在(中等范围)笔记本电脑上,100MB的文件处理时间不到一秒钟。如果找到标记,程序将以错误代码(值不同于0)退出。在退出之前,包含标记的文件信息会发送到标准错误输出(通过Console.Error)。这个消息将在Tortoise窗口中显示。

代码很简单,不是吗?此外,钩子的安装也很简单!要附加钩子,请从Tortoise的上下文菜单中选择“设置”项。然后选择“钩子脚本”元素并点击“添加…”按钮。将出现这样的窗口:

将“钩子类型”设置为“预提交钩子”。在“工作副本路径”字段中填写包含本地仓库副本的目录路径(不同的文件夹可以有不同的钩子)。在“要执行的命令行”字段中,设置实现钩子的应用程序的路径。检查“等待脚本完成”(这很重要!)和“运行时隐藏脚本”选项(后者将防止控制台窗口显示)。按下“确定”按钮,钩子就安装好了!

现在用“NOT_FOR_REPO”注释标记一些代码,然后尝试执行提交。应该看到类似这样的信息:

注意“重试而不使用钩子”按钮——它允许通过忽略钩子来完成提交。

现在有一个钩子,可以防止临时代码的提交。有人可能还想创建一个强制填写日志消息的钩子,阻止*.log文件的提交等。私人钩子——决定!如果有些钩子对整个团队都有用,可以随时将它们重新制作为Subversion钩子。

在TortoiseSVN 1.7.8/Subversion 1.7.6上测试过。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485