一个 SVN 存储库还是多个 SVN 存储库?

One SVN repository or many?

提问人:nickf 提问时间:10/31/2008 更新时间:6/2/2010 访问量:42458

问:

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

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 主机已经开始按每个存储库收费。

SVN的

评论

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

答:

1赞 Levi Rosol 10/31/2008 #1

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

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

7赞 Greg Hewgill 10/31/2008 #2

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

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

评论

0赞 cfeduke 10/31/2008
是的,多个多个!
3赞 Peter Parker 10/31/2008
您可以将存储库转储到“在/排除任何路径”中进行转储筛选,并分隔任何基于路径的信息。所以这不是一个真正的问题。
0赞 Sander Rijken 2/24/2009
当有人想向你支付代码费用时,你还可以设置对存储库子树的访问。
4赞 Paul Wicks 10/31/2008 #3

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

但实际上,您应该只使用 git ;)

5赞 Christian C. Salvadó 10/31/2008 #4

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

评论

5赞 Peter Parker 10/31/2008
没有问题,如果你查看相应的项目文件夹,你只会得到提交到这个项目的commitMessages
0赞 Christian C. Salvadó 10/31/2008
是的,你可以做到,但我个人认为维护一个大型存储库更加困难,管理用户权限、备份、修订号等,这取决于你的团队需求,如果你选择使用一个大的存储库,SVN 的扩展性非常好......
3赞 Sander Rijken 2/25/2009
对我来说,备份一个存储库似乎比备份 20 个更容易。顺便说一句,备份存储库的一个巧妙方法是使用 svnsync 维护只读副本
78赞 Ken Gentle 10/31/2008 #5

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

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

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

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

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

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

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

JFTR:

Subversion 中的修订号在存储库之外真的没有意义。如果您需要修订版的有意义的名称,请创建一个 TAG

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


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

评论

1赞 Frederic Morin 2/26/2009
“访问控制 [...]多个存储库将需要多个文件“,许多存储库可以指向同一个访问限制文件。请参阅下面的回答。
0赞 bboyle1234 9/7/2012
嗨,Ken,您愿意进一步评论在 one-repository-multiple-projects 设置中签出和分支的过程吗?我现在与一家公司合作,该公司在一个存储库中拥有许多项目,每个项目都有自己的 /project/<trunk><branch><tags>文件夹系统。但是工程师们已经从根目录中一次检查了所有项目:分支和修订图不再起作用:(
25赞 Peter Parker 10/31/2008 #6

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

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

对于多个存储库,只有一个点:管理大型存储库是不舒服的。 转储/加载大型存储库需要花费大量时间。但是由于你不做任何管理,我认为这不会是你关心;)

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

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

评论

2赞 Matthew Schinckel 10/31/2008
多个存储库 != 多个授权。如果使用 svn+ssh 和 private-key-authentication,则同一主机上的多个存储库是无痛的。
1赞 Peter Parker 10/31/2008
我说“单个存储库 == 单个授权”,否定当然不是您建议的“多个存储库 == 多个授权”。
1赞 Casebash 10/4/2009
从技术上讲,说“多个存储库 != 多个授权”并不一定意味着您是这个意思。他可以为了其他用户的利益而澄清
0赞 Clint Pachl 2/2/2011
svn:externals 没有解决哪些问题?
1赞 Peter Parker 11/3/2014
@Gusdor,你是对的,但大多数用户都没有意识到这个事实,并指责 SVN 它做错了版本控制(而,正如你所说,他们做错了开发)。是的,你是对的,你可以而且必须使用 peg revs,但实际上:SVN 团队中有多少人了解 peg 修订?
7赞 Mark Renouf 10/31/2008 #7

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

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

2赞 Frederic Morin 10/31/2008 #8

如果您计划或使用像 trac 这样的工具与 SVN 集成,那么每个项目使用一个存储库更有意义。

5赞 mlambie 10/31/2008 #9

我们是一家小型软件公司,我们使用一个存储库进行所有开发。树如下所示:

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

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

这对我们来说非常有效,我们使用 Trac 来连接它。修订号是整个存储库的,而不是特定于一个项目的,但这并不能使我们分阶段。

7赞 Frederic Morin 10/31/2008 #10

请注意,在做出决定时,许多 SVN 存储库可以共享相同的配置文件。

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

在 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

评论

0赞 Ken Gentle 2/26/2009
虽然您正确地将一组授权/身份验证文件用于多个存储库,但这样做是首选问题。我会更新我的帖子以反映您的答案。我确实觉得“错误”有点煽动性。
1赞 Harvey 3/31/2009
在此之前,我不知道该怎么做。谢谢。
2赞 Harvey 3/31/2009 #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)"
4赞 ofer 12/10/2009 #12

需要考虑的另一件事是,使用多个存储库会导致您失去统一日志记录(SVN log 命令)的能力,仅此一项就是选择单个存储库的充分理由。

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

2赞 J.D. 6/2/2010 #13

类似于使用单个存储库的 mlambie,但在文件夹结构上走得更远,以轻松缩放到特定类型的项目 - 基于 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 用作将特定 Apps 设置文件保存在存储库中的位置,以便轻松与其他人共享(并在此文件夹结构中将 ClientName 替换为 VendorName,将 ProjectName 替换为 AppName;并且 branches|tags 也可用于标记不同主要版本的供应商产品的设置)。

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