【问题标题】:One SVN repository or many?一个 SVN 存储库还是多个?
【发布时间】:2010-09-20 03:05:49
【问题描述】:

如果您有多个不相关的项目,将它们放在同一个存储库中是否是个好主意?

myRepo/projectA/trunk
myRepo/projectA/tags
myRepo/projectA/branches
myRepo/projectB/trunk
myRepo/projectB/tags
myRepo/projectB/branches

或者您会为每个创建新的存储库吗?

myRepoA/trunk
myRepoA/tags
myRepoA/branches
myRepoB/trunk
myRepoB/tags
myRepoB/branches

各有什么优缺点?我目前所能想到的只是你得到了混合的修订号(那又怎样?),除非存储库实际上是外部的,否则你不能使用svn:externals。 (我想?)

我问的原因是因为我正在考虑将我的多个 repo 合并为一个,因为我的 SVN 主机已经开始对每个 repo 收费。

【问题讨论】:

  • 我前段时间也问过同样的问题,所以如果您需要更多帮助,这里可能有一些帮助:stackoverflow.com/questions/130447/…
  • 哦,该死的 - 对不起,那是骗局。我试过搜索,我发誓!
  • 没有问题 :) 我并不担心刚刚提到它,所以如果你没有在这里得到你需要的帮助,那么我的 Q 中可能会有更多帮助
  • nickf, svn:externals 在一个大存储库中工作得很好。您只需使用您感兴趣的代码指向 repo 中的子目录。
  • 当然,在任何正常的商业环境中,你都会有多个 repos。 (因此,显然,您可以确定不同的客户/组只能看到他们自己不同的项目。)想象一下您可以使用颠覆回购的大型免费颠覆网站之一......想想如果它会多么愚蠢他们只有一个巨大的回购,而不是我们每个人一个!

标签: svn


【解决方案1】:

单个与多个问题归结为个人或组织偏好。

多对单的管理主要归结为访问控制和维护。

单个存储库的访问控制可以包含在单个文件中;多个存储库可能需要多个文件。维护也有类似的问题——一个大备份,或者很多小备份。

我自己管理。有一个存储库,多个项目,每个项目都有自己的标签、主干和分支。如果代码太大,或者我需要物理隔离客户的代码以使他们感到舒适,我可以快速轻松地创建一个新的存储库。

我最近咨询了一家相对较大的公司,将多个源代码控制系统迁移到 Subversion。他们有大约 50 个项目,从非常小的到企业应用程序和他们的公司网站。他们的计划?从单个存储库开始,必要时迁移到多个。迁移几乎完成,它们仍在单个存储库中,由于它是单个存储库,因此没有报告任何投诉或问题。

这不是一个二元、非黑即白的问题。

做对你有用的事情 - 如果我处于你的位置,我会尽快将项目合并到一个存储库中,因为我可以键入命令,因为成本将是我(非常非常小)公司的主要考虑因素。

JFTR:

修订号 在 Subversion 中在存储库之外确实没有任何意义。如果您需要有意义的修订名称,创建一个标签

提交消息很容易按存储库中的路径过滤,因此只阅读与特定项目相关的消息是一项简单的练习。


编辑:有关对 SVN 使用单一授权/身份验证配置的详细信息,请参阅 Blade 的回复。

【讨论】:

  • “[...] 多个存储库的访问控制将需要多个文件”许多存储库可以指向同一个访问限制文件。请参阅下面的答案。
  • 嗨,Ken,您愿意进一步评论一下单存储库多项目设置中的签出和分支过程吗?我现在与一家公司合作,该公司在一个存储库中有许多项目,每个项目都有自己的 /project/ 文件夹系统。但是工程师一直在从根目录一次检查所有项目:分支和修订图不再起作用:(
【解决方案2】:

对于您的特定情况,一 (1) 个存储库是完美的。你会节省很多钱。我总是鼓励人们使用单个存储库。因为它类似于单个文件系统:更容易

  • 您将在一个地方查找代码
  • 您将获得单一授权
  • 您将拥有一个提交编号(曾经尝试构建一个分布在 3 个存储库中的项目?)
  • 您可以更好地重用常用库并跟踪您在这些库中的进度(svn:externals 是 PITA,不会解决所有问题)
  • 计划为完全不同的项目的项目可以共同成长并共享功能和界面。这将很难在多个 repo 中实现。

多个存储库有一个要点:管理庞大的存储库很不舒服。 转储/加载巨大的回购需要很多时间。但是由于您不进行任何管理,我认为这不会是您的关注点;)

SVN 可以很好地适应更大的存储库,即使在巨大的 (>100GB) 存储库上也没有减速。

因此,使用单个存储库的麻烦会更少。 但你真的应该考虑一下 repo 布局!

【讨论】:

  • 多个回购!= 多个授权。如果您使用 svn+ssh 和私钥身份验证,那么同一主机上的多个 repos 是无痛的。
  • 我说的是“单一回购 == 单一授权”,否定当然不是您建议的“多重回购 == 多重授权”。
  • 作为技术人员,说“多个回购!= 多个授权”并不一定意味着你的意思。他可能是为了其他用户的利益而澄清
  • svn:externals 没有解决哪些问题?
  • @Gusdor,您是对的,但大多数用户没有意识到这一事实,并指责 SVN 版本控制错误(而正如您所说,他们的开发错误)。是的,您是对的,您可以而且必须使用 peg revs,但实际上:SVN 团队中有多少人了解 PEG-revisions?
【解决方案3】:

我会使用多个存储库。除了用户访问问题外,它还使备份和恢复更容易。而且,如果您发现自己处于有人想为您的代码(及其历史记录)付费的境地,那么只给他们一个存储库转储会更容易。

我建议仅仅因为您的托管服务提供商的收费政策而整合存储库并不是一个很好的理由。

【讨论】:

  • 是多多多多!
  • 您可以dumpfilter您的存储库转储以包含/排除任何路径并分离任何基于路径的信息。所以这不是一个真正的问题。
  • 当有人想为代码付费时,您还可以设置对存储库子树的访问权限。
【解决方案4】:

我们使用单个存储库。我唯一担心的是规模,但在看到ASF's repository(700k 修订和计数)之后,我非常确信性能不会成为问题。

我们的项目都是相关的、不同的互锁模块,它们为任何给定的应用程序形成一组依赖项。出于这个原因,单个存储库是理想的。您可能希望为每个项目使用单独的主干/分支/标签,但您仍然能够在单个修订版中自动提交整个代码库的更改。这对于重构来说太棒了。

【讨论】:

    【解决方案5】:

    请注意,在做出决定时,many SVN repos can share the same config file.

    示例(取自上面的链接):

    在外壳中:

    $ svn-admin create /var/svn/repos1
    $ svn-admin create /var/svn/repos2
    $ svn-admin create /var/svn/repos3
    

    文件:/var/svn/repos1/conf/svnserve.conf

    [general]
    anon-access = none # or read or write
    auth-access = write
    password-db = /var/svn/conf/passwd
    authz-db = /var/svn/conf/authz
    realm = Repos1 SVN Repository
    

    文件:/var/svn/conf/authz

    [groups]
    group_repos1_read = user1, user2
    group_repos1_write = user3, user4
    group_repos2_read = user1, user4
    
    ### Global Right for all repositories ###
    [/]
    ### Could be a superadmin or something else ###
    user5 = rw
    
    ### Global Rights for one repository (e.g. repos1) ###
    [repos1:/]
    @group_repos1_read = r
    @group_repos1_write = rw
    
    ### Repository folder specific rights (e.g. the trunk folder) ###
    [repos1:/trunk]
    user1 = rw
    
    ### And soon for the other repositories ###
    [repos2:/]
    @group_repos2_read = r
    user3 = rw
    

    【讨论】:

    • 虽然您是正确的,一组授权/身份验证文件可用于多个存储库,但这样做是一个偏好问题。我会更新我的帖子以反映您的答案。我确实觉得“错误”有点煽动性。
    • 我以前不知道该怎么做。谢谢。
    【解决方案6】:

    我会创建单独的存储库...为什么?如果您只有一个存储库中有很多不相关的项目,那么修订号和提交消息将没有任何意义,短期内肯定会一团糟......

    【讨论】:

    • 如果您查看相应的项目文件夹没有问题,您只会得到提交给该项目的提交消息
    • 是的,你可以做到,但我个人认为维护一个大型存储库比较困难,管理用户权限、备份、修订号等,这取决于你的团队需要,SVN 扩展性非常好如果你选择使用一个大仓库...
    • 对我来说,备份一个存储库似乎比备份 20 个更容易。附带说明一下,备份存储库的一种巧妙方法是使用 svnsync 维护只读副本
    【解决方案7】:

    我们是一家小型软件公司,我们使用一个存储库进行所有开发。树看起来像这样:

    /client/<clientname>/<project>/<trunk, branches, tags>
    

    我们的想法是我们将在同一个存储库中进行客户和内部工作,但最终我们将公司作为自身的“客户”。

    这对我们来说非常有效,我们使用 Trac 来连接它。修订号遍布整个 repo,而不是特定于一个项目,但这并不影响我们。

    【讨论】:

      【解决方案8】:

      就个人而言,我会为每个人创建新的存储库。它使结帐过程更加简单,并使管理更容易,至少在用户访问和备份方面是这样。另外,它避免了全局版本号问题,因此版本号对所有项目都有意义。

      真的,你应该只使用 git ;)

      【讨论】:

        【解决方案9】:

        要考虑的另一件事是,使用多个存储库会导致您失去拥有统一日志记录(svn log 命令)的能力,这本身就是选择单个存储库的好理由。

        我使用 TortuiseSvn,发现“显示日志”选项是一个强制工具。尽管您的项目不相关,但我相信您会发现拥有一个集中的全局跨项目信息(路径、错误 ID、消息等......)总是有用的。

        【讨论】:

          【解决方案10】:

          如果您计划或使用与 SVN 集成的 trac 等工具,则每个项目使用一个 repo 更有意义。

          【讨论】:

            【解决方案11】:

            类似于 Blade 关于共享文件的建议,这里有一个稍微简单但不太灵活的解决方案。我这样设置我们的:

            • /var/svn/
            • /var/svn/bin
            • /var/svn/repository_files
            • /var/svn/svnroot
            • /var/svn/svnroot/repos1
            • /var/svn/svnroot/repos2
            • ...

            在“bin”中,我保留了一个名为 svn-create.sh 的脚本,它将完成创建空存储库的所有设置工作。我也把备份脚本放在那里。

            在“repository_files”中,我保留了所有存储库都有符号链接的通用“conf”和“hooks”目录。然后,只有一组文件。不过,这确实消除了在不破坏链接的情况下进行细粒度的、每个项目的访问的能力。这不是我在哪里设置的问题。

            最后,我将主目录 /var/svn 置于源代码控制之下,忽略 svnroot 中的所有内容。这样,存储库文件和脚本也处于源代码控制之下。

            #!/bin/bash
            
            # Usage:
            # svn-create.sh repository_name
            
            # This will:
            # - create a new repository
            # - link the necessary commit scripts
            # - setup permissions
            # - create and commit the initial directory structure
            # - clean up after itself
            
            if [ "empty" = ${1}"empty" ] ; then
              echo "Usage:"
              echo "    ${0} repository_name"
              exit
            fi
            
            SVN_HOME=/svn
            SVN_ROOT=${SVN_HOME}/svnroot
            SVN_COMMON_FILES=${SVN_HOME}/repository_files
            NEW_DIR=${SVN_ROOT}/${1}
            TMP_DIR=/tmp/${1}_$$
            
            echo "Creating repository: ${1}"
            
            # Create the repository
            svnadmin create ${NEW_DIR}
            
            # Copy/Link the hook scripts
            cd ${NEW_DIR}
            rm -rf hooks
            ln -s ${SVN_COMMON_FILES}/hooks hooks
            
            # Setup the user configuration
            cd ${NEW_DIR}
            rm -rf conf
            ln -s ${SVN_COMMON_FILES}/conf conf
            
            # Checkout the newly created project
            svn co file://${NEW_DIR} ${TMP_DIR}
            
            # Create the initial directory structure
            cd ${TMP_DIR}
            mkdir trunk
            mkdir tags
            mkdir branches
            
            # Schedule the directories addition to the repository
            svn add trunk tags branches
            
            # Check in the changes
            svn ci -m "Initial Setup"
            
            # Delete the temporary working copy
            cd /
            rm -rf ${TMP_DIR}
            
            # That's it!
            echo "Repository ${1} created. (most likely)"
            

            【讨论】:

              【解决方案12】:

              类似于 mlambie 使用单个 repo,但在文件夹结构上更进一步,可以轻松缩放到特定类型的项目 - 基于 web html 的项目 vs. cs (C#) vs. sql(SQL 创建/执行脚本) vs . xyz(域特定语言,如 afl(AmiBroker 公式语言)或 ts(TradeStation)):

              /<src|lib>/<app-settings|afl|cs|js|iphone|sql|ts|web>/<ClientName>/<ProjectName>/<branches|tags>
              

              注意,我将主干放在分支中,因为我将其视为默认分支。有时唯一的痛苦是当您想快速创建另一个项目时,您需要构建 ProjectName/branches|tags 结构。我使用 app-settings 只是将特定的应用程序设置文件保存在 repo 中,以便于其他人轻松共享(并在此文件夹结构中将 ClientName 替换为 VendorName 并将 ProjectName 替换为 AppName ;并且分支|标签可用于标记跨不同专业的设置供应商产品的版本)。

              欢迎使用我的结构中的任何 cmets - 我最近将其更改为这个,到目前为止非常高兴,但有时发现维护每个项目的分支|标签结构很麻烦 - 特别是如果项目只是一个项目设置,只是为了对另一个项目进行单元测试项目。

              【讨论】:

                【解决方案13】:

                我的建议是一个。除非您有不同的用户访问每个用户,否则我会说使用多个。

                但同样,即使这也不是使用多个的好理由。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2010-10-24
                  • 2019-06-13
                  • 1970-01-01
                  • 2010-09-21
                  • 2011-07-09
                  • 2012-03-10
                  • 2020-03-12
                  • 1970-01-01
                  相关资源
                  最近更新 更多