首先,允许我首先从高级别总结一下锁定特性,Subversion采用的缺省版本控制模型是”拷贝-修改-合并“模型,用户会从版本化目录中检出个人工作拷贝,然后提交修改,只需要担心偶尔发生的对于同一个文件的修改。锁定(有时候我们称为”保留检出”)允许Subversion用户跳出缺省模型,而采用”锁定-修改-解锁“模型,这样多个用户顺序提交给定文件,所以冲突不会发生。后一种模型是Visual SourceSafe中经常使用的,Subversion的锁定特性通过允许用户声明对一个文件的修改排他锁来完成这个功能(然后之后放弃这个权利)。
推荐使用锁定吗?
Subversion开发者不会真的开发新特性来违反社区自己的推崇和最佳实践,而锁定特性(Subversion 1.2添加)是有意开发的,问题可以这样描述:”何时推荐锁定?”为了回答,我们来看一下两种控制模型赞成和反对的理由。
拷贝-修改-合并具有较少管理和流程的特性,所有的人可以自由修改文件,只是在发生冲突时解决。不幸的是,当冲突发生时,解决冲突的代价会有很大的不同,从不费任何脑到我浪费了一周的工作,这取决于冲突文件的格式。
当使用锁定-修改-解锁时,每一个人需要付出流程代价,如在需要编辑时明确锁定文件的,而在结束修改时解锁文件。如果用户不小心,这可能意味着一个用户可能保留不必要的时间来编辑文件,这会妨碍项目组的生产力,也会需要管理员的干涉。但是在正面,你不必在解决冲突上花费力气,因为冲突(只会发生在多个文件提交同一个文件的修改)不可能发生。
就像生活中的很多事情,两种模型的平衡会是最好的结果。Subversion的内置上下文修改合并算法可以处理大多数多个用户同时修改同一个文件的情况,当然文件是文本文件或其他人可读格式。对这些文件,使用拷贝-修改-合并(不锁定文件)可以节省用户投入到流程的步骤,鼓励协作并防止管理投入。但是对于处理冲突代价很高的文件,例如不可读文件格式,锁定和解锁会比解决可能发生的冲突轻松许多。
Subversion支持保留检出吗?
就像前面提到的,很多人将Subversion的文件锁定特性当作”保留检出”,但是这非常不准确的。在具备保留检出功能的版本控制系统,术语” checkout”不仅仅是在你的计算机得到一个版本化的文件,也是获得修改文件的权利,一个保留检出是同样的,除了你保护的修改权限是排他的 - 文件对其他用户是只读的。Subversion使用这个术语很古怪,缺省情况下,如果你从Subversion版本库检出一个文件,你可以编辑它,你可能无法提交它,一方面因为你没有授权,也有可能是你的本地工作拷贝已经过时了,或者是本文相关的 - 因为其他人锁定了它。
但是等一下,如果有其他人锁定了文件,为什么Subversion允许我们花时间修改它?
你可以运行’svn status –update’或对文件或版本库URL运行’svn info’来查看被其他人锁定的文件,但是Subversion不会坚持这些信息到工作拷贝,在你最后询问服务器锁定和提交修改之间一定有一个时间差,锁定文件节省了处理冲突或浪费编辑的时间,但是不能帮助协作者来解决你以前面对的情形。
处理这种场景的最佳方法是使用Subversion的文件属性-svn:needs-lock。通过在文件上设置这个属性,你可以告诉Subversion这个文件会导致你和你的协作者需要在修改之前获得这个文件的锁,设置svn:needs-lock属性的文件在工作拷贝(在OS的文件系统意义上的)首先会是只读的,这样足以让行为良好的编辑软件不会修改这个文件,当你将文件加载到软件时,软件会提示文件只读,你会记起你需要使用”svn lock”锁定文件,通过这样做,Subversion会改变工作拷贝中的文件系统访问控制,它不再是只读得了,你可以修改这个文件了。当你提交并释放了文件的锁定,Subversion重新让它在工作拷贝回到只读状态。
作为最佳实践,我推荐你小心的评估svn:needs-lock属性的有无,如果一个文件没有包含这个属性,你确实需要锁定它吗?如果你确实需要锁定文件,有其他人会从工作拷贝的只读属性中获益吗?
请注意,svn:needs-lock属性不会导致Subversion要求文件提交时是锁定状态,它只会作用于客户端文件系统的只读问题,前面我也说了svn:needs-lock发挥作用需要你使用行为良好的软件。但是如果你的软件忽略只读文件系统位-或者你手工修改文件许可位 - 你或许不会发现在修改之前获取锁会失败,Subversion会很高兴得允许你提交修改。(如果你的软件这样运行,请考虑告诉它的开发者!)
可以锁定模块/目录,还是只能是文件?
很不幸,此时在Subversion里你只能锁定文件。
这种不幸的原因很清楚,因为你不能锁定目录,许多人会这样工作 - 锁定目录下的所有文件,不管对于特定文件集是否必要,这样在Subversion中会有一些性能问题。现在Subversion还不支持多条锁定路径操作的原子化- 如果200个文件中有126个锁定因为一些原因(很可能是被别人锁定了)失败了,你会得到部分锁定。对于经常这样做的人来说,应该考虑”svn lock”不接受recursive子命令的事实,这不是Subversion开发者不小心,如果你希望整个目录的访问限制,请使用路径为基础的访问控制方法。
你能告诉Subversion你希望锁定所有文件吗?
是,你可以,但是决定这样做之前请读一下前一个问题的答案。如果你觉得你确实需要,你可以将所有的文件设置svn:needs-lock属性。(你可以参考使用客户端的自动化属性功能。)读一下前面的纪录,为什么Subversion那些文件需要锁定。作为选择,你可以编写一个pre-commit钩子脚本可以检查提交文件是否已经被锁定。(你可以相信Subversion来检查提交者确实是锁定的拥有者。)
可以锁定特定文件类型(例如所有的*.doc文件)吗?
当然,看前一个答案,只需要限制自动化属性的范围,或使用钩子基础的提交验证来确认感兴趣的文件类型。
原始链接
About the Author
C. Michael (Mike) Pilato has been on the Subversion project as a committer since 2000. Mike is one of the co-authors of “Version Control with Subversion” and he is on the board of the non-profit Subversion Corporation.