Subversion 通常在不使用锁定的情况下效果最佳,它使用“复制-修改-合并”方法,这些方法在名为“复制-修改-合并解决方案”的章节中已较早描述过。但是,在少数情况下,您可能需要实施某种形式的锁定策略。
您正在使用“不可合并”文件,例如,图形文件。如果两个人更改同一个文件,则无法进行合并,因此你们中的一个人将丢失他们的更改。
您的公司过去一直使用锁定修订控制系统,并且管理层已决定“锁定是最好的”。
首先,您需要确保您的 Subversion 服务器已升级到至少 1.2 版本。早期版本根本不支持锁定。如果您使用的是 file://
访问方式,那么当然只需要更新您的客户端。
在本节以及本书的几乎所有地方,“锁定”一词描述的是用户之间相互排斥的机制,以避免提交冲突。不幸的是,还有另外两种 “锁定” 与 Subversion 相关,因此本书有时需要关注。
第二种是 工作副本锁
,Subversion 内部使用它来防止多个 Subversion 客户端在同一工作副本上操作时发生冲突。通常,当像 update/commit/... 这样的命令由于错误而中断时,您会获得这些锁。可以通过在工作副本上运行 cleanup 命令来删除这些锁,如名为“清理”的章节中所述。
第三,如果文件和文件夹正在被另一个进程使用,它们可能会被锁定,例如,如果您在 Word 中打开了一个 Word 文档,则该文件将被锁定,TortoiseSVN 无法访问它。
您通常可以忘记这些其他类型的锁,除非出现问题需要您关注它们。在本书中,“锁定” 除非从上下文中明显可知或明确说明相反,否则均指第一种。
默认情况下,没有任何东西被锁定,任何拥有提交访问权限的人都可以随时提交对任何文件的更改。其他人将定期更新其工作副本,并且存储库中的更改将与本地更改合并。
如果您对文件获取锁,那么只有您可以提交该文件。所有其他用户的提交都将被阻止,直到您释放锁。锁定的文件在存储库中无法以任何方式修改,因此除了锁的所有者之外,也无法删除或重命名它。
锁不是分配给特定用户的,而是分配给特定用户和工作副本的。在一个工作副本中拥有锁也会阻止同一用户从另一个工作副本提交锁定的文件。
举个例子,假设用户 Jon 在他的办公室 PC 上有一个工作副本。他在那里开始处理一个图像,因此获取了该文件的锁。当他离开办公室时,他还没有完成该文件,因此他没有释放该锁。回到家后,Jon 也有一个工作副本,并决定在该项目上多工作一会儿。但他无法修改或提交同一个图像文件,因为该文件的锁位于他在办公室的工作副本中。
但是,其他用户不一定会知道您已获取了锁。除非他们定期检查锁定状态,否则他们首先知道它是在他们的提交失败时,这在大多数情况下不是很有用。为了更容易管理锁,有一个新的 Subversion 属性 svn:needs-lock
。当在文件上设置此属性(设置为任何值)时,每当检出或更新文件时,本地副本都会变为只读除非该工作副本持有该文件的锁。这充当一个警告,警告您除非您首先获取锁,否则不应编辑该文件。已版本化且为只读的文件在 TortoiseSVN 中用特殊覆盖层标记,以指示您需要在编辑之前获取锁。
锁记录在工作副本位置以及所有者处。如果您有多个工作副本(在家中,在工作中),那么您只能在这些工作副本中的一个中持有锁。
如果您的同事之一获取了锁,然后去度假而没有释放它,您该怎么办?Subversion 提供了一种强制锁定的方法。释放其他人持有的锁称为破坏锁,而强制获取其他人已持有的锁称为盗取锁。当然,如果您想与您的同事保持友好关系,这些都不是您应该轻易做的事情。
锁记录在存储库中,并且在您的本地工作副本中创建了一个锁令牌。如果存在差异,例如,如果其他人破坏了锁,则本地锁令牌将变为无效。存储库始终是最终的参考。
在您的工作副本中选择您要获取锁的文件,然后选择命令
→ 。
将出现一个对话框,允许您输入注释,以便其他人可以看到您锁定文件的原因。注释是可选的,目前仅用于基于 Svnserve 的存储库。如果(并且只有当)您需要从其他人那里盗取锁时,请选中盗取锁框,然后单击 。
您可以设置项目属性 tsvn:logtemplatelock
以提供消息模板,供用户填写作为锁定消息。有关如何设置属性的说明,请参阅名为“项目设置”的章节。
如果您选择一个文件夹,然后使用每个子文件夹中的每个文件都已选择进行锁定。如果您真的想锁定整个层次结构,那这就是方法,但是如果您将他们排除在整个项目之外,您可能会变得非常不受您的同事欢迎。谨慎使用...
→ ,则锁定对话框将打开,其中为了确保您不会忘记释放您不再需要的锁,锁定的文件会显示在提交对话框中,并默认选中。如果您继续提交,则您持有的所选文件的锁将被删除,即使文件尚未修改。如果您不想释放某些文件的锁,您可以取消选中它们(如果它们未被修改)。如果您想保留对已修改文件的锁,则必须在提交更改之前启用保留锁复选框。
要手动释放锁,请在您的工作副本中选择您要释放锁的文件,然后选择命令
→ 。无需进一步输入,因此 TortoiseSVN 将联系存储库并释放锁。您也可以在文件夹上使用此命令以递归方式释放所有锁。
要查看您和其他人持有的锁,您可以使用 → 。本地持有的锁令牌会立即显示。要检查其他人持有的锁(并查看您的任何锁是否已损坏或被盗),您需要单击 。
从这里的上下文菜单中,您还可以获取和释放锁,以及破坏和盗取其他人持有的锁。
如果您在没有告知别人的情况下破坏或盗取了别人的锁,您可能会造成工作丢失。如果您正在使用不可合并的文件类型并且您盗取了别人的锁,一旦您释放锁,他们就可以自由地检入他们的更改并覆盖您的更改。Subversion 不会丢失数据,但您已经失去了锁定为您提供的团队协作保护。
如上所述,使用锁定的最有效方法是在文件上设置 svn:needs-lock
属性。有关如何设置属性的说明,请参阅名为“项目设置”的章节。设置了此属性的文件将始终以只读标志检出和更新,除非您的工作副本持有锁。
作为提醒,TortoiseSVN 使用特殊覆盖层来指示这一点。
如果您实施一项策略,其中每个文件都必须锁定,那么您可能会发现使用 Subversion 的自动属性功能更容易,以便在每次添加新文件时自动设置该属性。阅读名为“自动属性设置”的章节以获取更多信息。
当您使用 Subversion 1.2 或更高版本创建新的存储库时,将在存储库 hooks
目录中创建四个 hook 模板。这些模板在获取锁之前和之后以及释放锁之前和之后调用。
在服务器上安装一个 post-lock
和 post-unlock
hook 脚本是一个好主意,该脚本会发送一封电子邮件,指示已锁定的文件。有了这样的脚本,如果有人锁定/解锁文件,您的所有用户都可以收到通知。您可以在存储库文件夹中找到示例 hook 脚本 hooks/post-lock.tmpl
。
您还可以使用 hook 来禁止破坏或盗取锁,或者可能将其限制为指定的管理员。或者,当他们的某个锁被破坏或盗取时,您可能想通过电子邮件通知所有者。
阅读名为“服务器端 hook 脚本”的章节以了解更多信息。