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