一个SVN存储库还是很多?

时间:2008-10-31 02:34:03

标签: svn

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

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。 (我想?)

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

13 个答案:

答案 0 :(得分:75)

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

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

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

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

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

这不是二元,黑色&白色问题。

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

JFTR:

Subversion中的

修订号 在存储库外面没有任何意义。如果您需要有意义的修订名称,创建标签

提交消息很容易通过存储库中的路径进行过滤,因此只读取与特定项目相关的消息是一项微不足道的工作。


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

答案 1 :(得分:25)

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

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

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

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

因此,您可以减少单个存储库的麻烦。 但你真的应该考虑回购布局!

答案 2 :(得分:7)

我会使用多个存储库。除了用户访问问题之外,它还使备份和还原更容易。如果你发现自己处于某个人想要为你的代码(及其历史记录)付钱的位置,那么就更容易给他们一个存储库转储。

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

答案 3 :(得分:7)

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

我们的项目都是相关的,不同的互锁模块,它们为任何给定的应用程序形成一组依赖关系。因此,单个存储库是理想的。对于每个项目,您可能需要单独的主干/分支/标记,但您仍然可以在单个修订中以原子方式提交整个代码库中的更改。这对于重构来说非常棒。

答案 4 :(得分:6)

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

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

在shell中:

$ 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

答案 5 :(得分:5)

我会创建单独的存储库 ...为什么?如果你只在一个存储库中有很多不相关的项目,那么修订号和提交消息就没有任何意义,这肯定会在短期内造成很大的混乱....

答案 6 :(得分:5)

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

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

我们的想法是,我们将客户和内部工作放在同一个回购中,但最终我们将公司作为自己的“客户”。

这对我们来说非常有效,我们使用Trac与它进行交互。修订号贯穿整个仓库而不是特定于一个项目,但这不会使我们分阶段。

答案 7 :(得分:4)

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

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

答案 8 :(得分:3)

需要考虑的另一件事是,使用多个存储库会导致您无法进行统一日志记录(svn log命令),这就是选择单个存储库的理由。

我使用TortuiseSvn并发现“显示日志”选项是必需的工具。虽然你的项目是不相关的,但我相信你会发现拥有一个集中的全球跨项目信息(路径,bug id,消息等......)总是很有用。

答案 9 :(得分:2)

如果您计划或使用与SVN集成的工具,那么每个项目使用一个回购更有意义。

答案 10 :(得分:2)

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

  • 的/ var / SVN /
  • 的/ var / SVN /仓
  • 的/ var / SVN / repository_files
  • 的/ var / SVN / svnroot
  • 的/ var / SVN / svnroot / repos1版本
  • 的/ var / SVN / svnroot / repos2
  • ...

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

在“repository_files”中,我保留了所有存储库都有sym链接的常见“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)"

答案 11 :(得分:1)

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

但是,即使这也不是使用多重的理由。

答案 12 :(得分:1)

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

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

注意,我在分支机构中有实时主干,因为我将其视为默认分支。唯一的痛苦有时是你想要快速创建另一个项目,你需要构建ProjectName / branches | tags结构。我只是将应用程序设置用作保存特定应用程序设置文件的地方,以便轻松共享给其他人(并在此文件夹结构中将ClientName替换为VendorName和ProjectName到AppName;而分支|标签可用于标记不同主要设置的设置也是供应商产品的版本。)

欢迎任何关于我的结构的评论 - 我最近将其更改为此并且到目前为止非常高兴,但有时发现每个项目维护分支机构|标签结构很麻烦 - 特别是如果项目只是简单地将项目设置为单元测试另一个项目