提问人:nickf 提问时间:10/31/2008 更新时间:6/2/2010 访问量:42458
一个 SVN 存储库还是多个 SVN 存储库?
One SVN repository or many?
问:
如果您有多个不相关的项目,将它们放在同一个存储库中是一个好主意吗?
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 主机已经开始按每个存储库收费。
答:
我的建议是其中之一。除非您有不同的用户访问每个用户,否则我会说使用多个。
但同样,即使这样也不是使用多个的好理由。
我会使用多个存储库。除了用户访问问题外,它还使备份和还原更容易。如果你发现自己处于有人想为你的代码(及其历史)付费的境地,那么给他们一个存储库转储会更容易。
我建议仅仅因为托管服务提供商的收费政策而合并存储库并不是一个很好的理由。
评论
就我个人而言,我会为每个存储库创建新的存储库。它使签出过程更加简单,并使整体管理更容易,至少在用户访问和备份方面是这样。此外,它还避免了全局版本号问题,因此版本号对所有项目都有意义。
但实际上,您应该只使用 git ;)
我会创建单独的存储库......为什么?如果你在一个存储库中有很多不相关的项目,那么修订号和提交消息将没有任何意义,这在短期内肯定会一团糟。
评论
单个问题与多个问题归结为个人或组织的偏好。
多与单的管理主要归结为访问控制和维护。
单个存储库的访问控制可以包含在单个文件中;多个存储库可能需要多个文件。维护也有类似的问题 - 一个大备份,或很多小备份。
我管理我自己的。有一个存储库,多个项目,每个项目都有自己的标签、主干和分支。如果一个代码太大,或者我需要物理隔离客户的代码以方便他们,我可以快速轻松地创建一个新的存储库。
我最近咨询了一家相对较大的公司,将多个源代码控制系统迁移到 Subversion。他们有 ~50 个项目,从非常小的项目到企业应用程序及其公司网站。他们的计划?从单个存储库开始,如有必要,迁移到多个存储库。迁移几乎完成,它们仍然在单个存储库中,由于它是单个存储库,因此没有报告任何投诉或问题。
这不是一个二元的、非黑即白的问题。
做对你有用的事情 - 如果我在你的位置上,我会尽可能快地将项目合并到一个存储库中,因为我(非常非常小的)公司的成本将是一个主要考虑因素。
JFTR:
Subversion 中的修订号在存储库之外真的没有意义。如果您需要修订版的有意义的名称,请创建一个 TAG
提交消息很容易按存储库中的路径进行过滤,因此仅读取与特定项目相关的消息是一项微不足道的工作。
编辑:有关对 SVN 使用单个授权/身份验证配置的详细信息,请参阅 Blade 的响应。
评论
对于您的具体情况,一 (1) 个存储库是完美的。您将节省很多钱。我总是鼓励人们使用单个存储库。因为它类似于单个文件系统:它更容易
- 您将有一个查找代码的地方
- 您将拥有一份授权书
- 您将有一个提交编号(曾经尝试过构建一个分布在 3 个存储库中的项目?
- 你可以更好地重用常用库,并在这些库中跟踪你的进度(svn:externals 是 PITA,不会解决所有问题)
- 计划为完全不同的项目,可以一起成长并共享功能和接口。这在多个存储库中将很难实现。
对于多个存储库,只有一个点:管理大型存储库是不舒服的。 转储/加载大型存储库需要花费大量时间。但是由于你不做任何管理,我认为这不会是你关心;)
SVN 可以很好地扩展更大的存储库,即使在大型 (>100GB) 存储库上也不会减速。
因此,使用单个存储库的麻烦将更少。但是你真的应该考虑一下回购布局!
评论
我们使用单个存储库。我唯一担心的是规模,但在看到 ASF 的存储库(700k 修订和计数)后,我非常确信性能不会成为问题。
我们的项目都是相关的、不同的互锁模块,它们构成了任何给定应用程序的一组依赖项。因此,单个存储库是理想的选择。您可能希望每个项目都有单独的主干/分支/标签,但您仍然可以在单个修订版中以原子方式提交整个代码库的更改。这对于重构来说非常棒。
如果您计划或使用像 trac 这样的工具与 SVN 集成,那么每个项目使用一个存储库更有意义。
我们是一家小型软件公司,我们使用一个存储库进行所有开发。树如下所示:
/client/<clientname>/<project>/<trunk, branches, tags>
我们的想法是,我们将客户和内部工作放在同一个存储库中,但我们最终将我们的公司作为自己的“客户”。
这对我们来说非常有效,我们使用 Trac 来连接它。修订号是整个存储库的,而不是特定于一个项目的,但这并不能使我们分阶段。
请注意,在做出决定时,许多 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
评论
与 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)"
需要考虑的另一件事是,使用多个存储库会导致您失去统一日志记录(SVN log 命令)的能力,仅此一项就是选择单个存储库的充分理由。
我使用 TortuiseSvn 并发现“显示日志”选项是强制性工具。虽然你的项目是无关的,但我相信你会发现,拥有一个集中的全局跨项目信息(路径、错误ID、消息等)总是有用的。
类似于使用单个存储库的 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 也可用于标记不同主要版本的供应商产品的设置)。
欢迎对我的结构发表任何评论 - 我最近把它改成了这个,到目前为止非常高兴,但有时发现维护每个项目的分支|标签结构很麻烦 - 特别是如果项目只是一个项目设置只是为了对另一个项目进行单元测试。
上一个:如何在TBODY元素之间放置间距
下一个:使用 jQuery 突出显示单词
评论