【问题标题】:Is there a fast way to lock my SVN repository's trunk?有没有一种快速的方法来锁定我的 SVN 存储库的主干?
【发布时间】:2011-01-14 12:48:57
【问题描述】:

有时我需要确保没有人致力于特定分支或我的主干。发布构建和重新集成合并就是一个例子。

SVN“锁定”所有文件是不现实的(很长一段时间,因为项目很大)。我也不相信锁定会阻止某人提交新文件。

在我完成我正在做的事情之前,确保没有人向文件夹提交任何内容的快速方法是什么?

谢谢

【问题讨论】:

  • 你不能为发布版本创建一个新分支吗?并在这个没有其他人在工作的新分支上做你所有的建筑等?

标签: svn version-control


【解决方案1】:

很老的问题。我的回答可能会对使用 Tortoise SVN 的人有所帮助

  1. 在本地系统中右键项目文件夹,选择TortoiseSVN->Properties
  2. 点击新建->NeedsLock
  3. 在对话框中选择需要锁定:
  4. 点击确定
  5. 提交文件
  6. 完成!

【讨论】:

    【解决方案2】:

    正确的方法是我的拙见。

    1. 锁好后备箱
    2. 创建标签
    3. 松开行李箱上的锁
    4. 导出标签
    5. 构建代码
    6. 如果构建成功锁定标记版本(否则删除它)

    我就是这样做的,我有一个标记部分的脚本

    #!/bin/bash
    #
    #    Copyleft
    #
    
    #
    # Use with caution
    #
    #
    #
    # This script expects 2 variables in the environment to be set : USERNAME & PASSWORD
    # These are needed to access our Subversion server.
    #
    
    #
    # This script tags the code of each project @ HEAD
    # Later version will be more sofisticated to allow tagging at a specified REVISION (it should already be the case but ... )
    #
    # This script must be saved un iso-8858-1 with UNIX LF
    # ##############################################################################################################################################
    
    # for debugging
    set -x
    set -v
    
    
    # The Current verion of the tagging script is
    
    
    BASEDIR=$(dirname $0)
    export BASE_SVN_URL=https://my-svn-server/svn/repository/
    export ROOT_DIR=../..
    export VERSION="v0000.01"
    export REVISION=HEAD
    export TAG_NAME=TC_05
    
    for PRJ in MODULE_1 MODULE_2 MODULE_3
    do
      svn lock --username ${USERNAME} --password ${PASSWORD}  --no-auth-cache --non-interactive  --trust-server-cert   --force                     \
                                                ${BASE_SVN_URL)${PRJ}/trunk/                                                                       \
                                                -m "Locking the trunk of ${PRJ} before generating a Tagged version : ${VERSION} Tag is : ${TAG_NAME}"
    done
    
    
    for PRJ in MODULE_1 MODULE_2 MODULE_3
    do
      svn copy --username ${USERNAME} --password ${PASSWORD}  --no-auth-cache --non-interactive  --trust-server-cert                               \
                                               ${BASE_SVN_URL)${PRJ}/trunk@${REVISION}                                                             \
                                               ${BASE_SVN_URL)${PRJ}/tags/${VERSION}/${TAG_NAME}                                                   \
                                               -m "$1"
    
      svn lock --username ${USERNAME} --password ${PASSWORD}  --no-auth-cache --non-interactive  --trust-server-cert                               \
                                                ${BASE_SVN_URL)${PRJ}/tags/${VERSION}/${TAG_NAME}                                                  \
                                                -m "Tagged version cannot be modified afterwards"
    
    
      svn unlock --username ${USERNAME} --password ${PASSWORD}  --no-auth-cache --non-interactive  --trust-server-cert   --force                   \
                                                ${BASE_SVN_URL)${PRJ}/trunk/                                                                       \
                                                -m "Locking before generating a Tagged version"
    done
    
    set +x
    set +v
    
    #
    # TODO :
    # 
    # 1. Ensure that the following parameters are set correctly
    #      _ username / password (though not mandatory)
    #      _ Commit message, VERSION & TAG ought to be set before start
    #      _ ... ?
    # 2. Ensure that the directory structure exist
    # 3. Ensure that the required variable are set before starting ... but anyway the script will fail :)
    # 4. Check the return code of the important commands command.
    # 5.
    

    我的代码构建位于另一个脚本中。 长脚本很酷,但在过程早期失败时往往会引发问题,使系统处于未知状态。 提供的脚本尚未经过全面测试,也未在我们的系统上广泛使用以保证它们没有错误。

    但是我建议很少使用 svn 锁定。

    在发布之前的最后,这是确保没有最后一分钟错误不会危及您的发布的一种手段......但是良好的沟通应该允许您使用几乎相同的代码,但指定一个提交号

    \T,

    【讨论】:

      【解决方案3】:

      需要我再次推送我的pre-commit 钩子吗?

      这可以处理很多事情,但防止人们修改文件是它的主要目的。您可以通过控制文件控制提交行为:

      [ FILE The repository is now locked and you are no longer allowed to change files]
      Match = .*
      access = read-only
      users = @ALL
      
      [ File Except for me. I can do whatever I want]
      match = .*
      access = read-write
      users = si
      

      控制文件可以存在于存储库中,因此您不需要访问服务器。只需签出控制文件,编辑它并提交。 (当然,预提交脚本控制了谁可以修改控制文件的访问权限!)

      您可能想要做的是使用分支发布。我们使用 Jenkins 并通过 Jenkins 内部版本号完成所有操作。开发人员会说“我想分支构建 #50,然后它会被分支,或者”让我们标记构建 #51,然后它就会被标记。

      当您可能想要锁定您的存储库时,我们会进行分支。但是,我们让开发者继续在主干上,然后限制谁可以在一个分支上操作:

      [group cm]
      users = si
      
      [group Release]
      users = bob, alice
      
      [group developers]
      users = robert fred cindy @Release
      
      [file You do not have access to make changes to this repository]
      match = .*
      access = read-only
      users = @all
      
      [file Let all developers work on the trunk]
      file = /trunk/**
      access = read-write
      users = @developers
      
      [file only release group can work on the 4.5 branch]
      file = /branches/4.5/**
      access = read-write
      users = @release
      
      [file You cannot edit a tag. You can only create a tag]
      file = /tags/*/
      access = add-only
      Users = all
      
      [file CM group can do anything]
      file = .*
      access = read-write
      users = @CM
      

      权限是向下读取的,适用于您的最后一个权限就是您获得的权限。开发者可以访问主干。发布人员可以在 4.5 分支上工作,但不能在任何其他分支上工作。特殊的add-only 访问允许您创建标签,但不能修改标签。 /tags/*/表示只能直接在tag目录下创建tag,而且必须是从其他位置复制过来的目录。

      【讨论】:

        【解决方案4】:

        根据您对服务器的访问权限,发送一条通知,告诉任何人在某个时间之前不要提交。

        如果您不能这样做,请使用file://file+ssh:// 签出/签入发布版本,并在此期间关闭 SVN 服务器进程。 (无论是 apache 还是 svnserver)然后在构建完成后立即重新启动它。

        此外,请务必重新进行此操作,这样就不需要尽快锁定 repo。 (我意识到这只是你继承的一个暂时的东西)

        【讨论】:

          【解决方案5】:

          我们在为发布版本编译项目时遇到了这个问题,其中构建服务器属性(CruiseControl.NET 项目标签)用作程序集和安装程序版本的一部分。

          在您对工作副本进行分支(或标记)时,解决方案很简单,例如用于发布版本。

          工作流程:

          1. 检查主干(或分支)的新工作副本。
          2. 构建您的版本,这会更新文件,使您的工作副本处于修改状态。
          3. 如果你的构建成功,svn 将工作副本复制到你的新分支或标签中。

          如果您想在不分支的情况下提交工作副本,那么正如您所说,如果有人修改了存储库的该路径,这将失败(或至少不可靠)。

          解决此问题的一种方法是使用svn authorization control,将构建服务器用户添加到svn,并为存储库提供不同的authz 文件。

          工作流程:

          1. authz 替换为文件,为构建服务器用户授予写入权限,并为所有其他用户授予读取权限。
          2. 正常执行构建。
          3. authz 替换为授予所有用户正常访问权限的文件。

          请注意,svn 授权允许基于路径的控制,因此您可以将其限制在主干(或任何地方)以减少对用户的影响。

          使用类似方法(相同工作流程)的另一种方法是替换 pre-commit hook 并检查用户;如果不是您的构建服务器用户执行提交,则拒绝提交(带有适当的错误消息)。同样,如果需要,这可能是基于路径的(需要一些额外的正则表达式工作)。

          【讨论】:

            【解决方案6】:

            有趣的问题。听起来您的开发工作流程可以进行一些更改,因为您遇到了这个问题。特别是,在这样一个大型项目中,您应该考虑一个更受控制的工作流程,因此开发更改不会同时出现在同一个分支上,就像正在进行的发布构建一样。例如,您提到了重新集成合并 - 当然您可以协调项目,以便重新集成合并不会与发布版本同时发生。并且开发人员不应该直接提交正在发布构建的分支。

            可能性:

            • 与开发人员有效沟通。
              • 宣布您将要做什么。
              • 开发人员至少应该知道他们不应该提交正在进行发布构建的分支。
            • 在分支中构建。然后在构建完成后标记分支。
            • 开发人员在不同的分支上进行开发工作。然后将集成合并到集成分支中(可能是trunk)。
              • 开发人员应该知道,不应在正在进行发布构建的分支上进行集成。

            【讨论】:

              【解决方案7】:

              我们首先,您可以尝试在特定版本而不是头部执行这些操作。

              如果修订版不是一个选项,我接下来建议您标记要构建的修订版或其他任何内容并对其进行操作。这显然不适用于合并,因为它违背了目的。

              但是,要解决您问题的症结,我能想到的阻止传入信息的最快方法是停止服务器本身。不过,我不是 SVN 专家,我已经管理了一个盒子好几年了。

              【讨论】:

                【解决方案8】:

                如果您正在制作发布版本,您要做的第一件事就是检查特定的修订版。

                在此期间是否有人提交其他内容并不重要 - 它不会影响您的构建。

                【讨论】:

                • 确实有点。我的内部版本号包含 svn 版本。运行我的自动构建会生成一堆需要提交的文件。因此,我构建的最后一步是签入。我试过只在修订号上加 1,但有时我在构建过程中遇到问题,当我修复它们时,有人已经向该文件夹提交了一些内容。
                • 您最好更改您的流程,以便它不需要签入生成的文件。您自动生成的文件不属于源代码管理。
                • 是的,我同意。这是我继承的系统。我们计划改变它,但现在,我只想快速锁定行李箱。
                • @oefe,我不同意。将生成的文件添加到存储库(例如 MSI 或 EXE 安装程序)有很多好处。您能否保证 X 年后您的构建服务器将能够编译与最初编译(和发布)相同版本的源代码。将源代码和源代码生成的 MSI/EXE 放在同一个地方要容易得多。显然这是在一个分支或标签中,而不是主干。
                • @Davy8 理论上我同意。然而,软件总是在升级,新的编译器版本,新的运行时(.NET,Java VMs),新的第 3 方库等等。除非您为所有这些维护相同的版本,否则您如何保证您将拥有相同的 MSI /EXE 首次发布? (即使你的源代码还是一样的)
                【解决方案9】:

                passwd 文件可以在工作完成时临时更改。缺点是这会影响整个存储库,而不仅仅是一个文件夹。

                【讨论】:

                • @Mr Grieves 不是。我也不会称其为“绝妙”的建议,但在某些情况下就足够了,因此这是对问题的有效答案。
                猜你喜欢
                • 2018-09-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-10-17
                • 1970-01-01
                相关资源
                最近更新 更多