一个或多个SVN存储库?


106

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

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主机已开始按每个存储库收费,因此我正在考虑将多个存储库合并为一个。


3
我也问了同样的问题,前一段时间,所以如果你需要帮助,不再可能有一些在这里:stackoverflow.com/questions/130447/...
弥敦道W¯¯

1
哦,该死-对不起,骗人。我尝试搜索,我发誓!
尼克

没有问题:)我不担心只是提到它,所以如果您在这里没有得到所需的帮助,那么我的Q可能会有更多帮助
Nathan W,

1
nickf,svn:外部人员可以在一个大型存储库中正常工作。您只需指向子目录与您感兴趣的代码回购。
本Gartner公司

当然,在任何正常的商业环境中,显然,您都会有多个存储库。(因此,很明显,您可以确定不同的客户/组只能看到他们自己的不同项目。)想象一下可以使用Subversion版本库的大型免费Subversion网站之一。他们只有一个庞大的仓库,而不是每个人一个!
Fattie 2014年

Answers:


77

单一问题还是多重问题取决于个人或组织的偏好。

多个或单个管理主要归结于访问控制和维护。

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

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

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

这不是二进制,黑白问题。

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

JFTR:

Subversion中的修订版本号在存储库外部确实没有任何意义。如果您需要有意义的名称来进行修订,创建一个TAG

提交消息很容易按存储库中的路径过滤,因此仅读取与特定项目相关的消息是一件很简单的事情。


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


1
“多个存储库的访问控制将需要多个文件”,许多存储库可以指向同一访问限制文件。请参阅下面的答案。
弗雷德里克·莫林

嗨,肯(Ken),您是否愿意进一步评论一个存储库多个项目设置中的检出和分支过程?我现在正在一家公司中工作,该公司在一个存储库中有许多项目,每个项目都有自己的/ project / <trunk> <branch> <tags>文件夹系统。但是工程师一直在从根目录中一次签出所有项目:分支和修订图不再起作用:(
bboyle1234 2012年

25

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

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

有多个存储库有一点:管理大型存储库是不舒服的。倾销/加载巨大的仓库需要很多时间。但是,由于您不进行任何管理,因此我认为这不会引起您的关注;)

SVN可以在较大的存储库中很好地扩展,即使在大型(> 100GB)的存储库上也不会出现速度下降的情况。

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


2
多个存储库!=多个授权。如果使用svn + ssh和私钥身份验证,则同一主机上的多个存储库将很轻松。
马修·辛克尔

1
我说过“单一回购==单一授权”,否定当然不是您建议的“多个回购==多个授权”。
彼得·帕克,

1
从技术角度讲,说“多个存储库!=多个授权”并不一定意味着您要这样做。他可能会为了其他用户的利益而澄清
Casebash

svn:externals无法解决哪些问题?
克林特·帕奇

1
@Gusdor,您是对的,但是大多数用户没有意识到这一事实,并且责怪SVN版本控制错误(同时,正如您所说的那样,他们在开发方面存在错误)。是的,您是对的,您可以并且必须使用peg修订,但是实际上:SVN团队中有多少人了解PEG修订?
彼得·帕克

7

我会使用多个存储库。除了用户访问问题外,它还使备份和还原更加容易。而且,如果您发现自己处于有人愿意为您的代码(及其代码)付钱的位置,则将它们仅存储库转储会更容易。

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


是的倍数倍数倍!
cfeduke

3
您可以使用dumpfilter来存储库转储,以输入/排除任何路径并分隔任何基于路径的信息。因此,这实际上不是问题。
彼得·帕克,

当有人想向您支付代码费用时,您还可以设置对存储库子树的访问权限。
桑德·里肯

7

我们使用单个存储库。我唯一关心的是规模,但在看到ASF的存储库后(70万次修订并不断增加)后,我坚信性能不会成为问题。

我们的项目都是相关的互锁模块,它们为任何给定应用程序形成了一组依赖关系。因此,理想的是单个存储库。您可能需要为每个项目使用单独的主干/分支/标签,但是您仍然可以在单个修订版中自动对整个代码库进行更改。重构很棒。


7

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

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

在外壳中:

$ 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

虽然可以将一组授权/身份验证文件用于多个存储库是正确的,但这是优先选择的问题。我将更新我的帖子以反映您的答案。我确实发现“错误”有点发炎。
Ken Gentle

1
我之前不知道该怎么做。谢谢。
哈维

5

我将创建单独的存储库 ...为什么?如果您在一个存储库中有很多无关的项目,那么修订号和提交消息将毫无意义,这肯定会在短期内造成很大混乱。


5
如果您查看相应的项目文件夹,就不会有问题,您只会收到提交给该项目的确认消息
Peter Parker's

是的,您可以做到,但是我个人认为维护大型存储库更加困难,管理用户权限,备份,修订号等,这取决于您的团队需求,如果您选择使用一个大型仓库,那么SVN可以很好地扩展...
CMS

3
备份一个存储库似乎比备份20个存储库容易。附带说明一下,备份存储库的一种巧妙方法是使用svnsync维护只读副本
Sander Rijken 09年

5

我们是一家小型软件公司,我们在整个开发过程中使用一个仓库。树看起来像这样:

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

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

这对我们来说确实非常有效,我们使用Trac进行接口。修订号遍及整个回购,而不是特定于一个项目的,但是这并不涉及我们。


4

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

确实,您应该只使用git;)


4

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

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



2

与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)"

2

与使用单个仓库的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结构。我将应用程序设置简单地用作保存回购中特定应用程序设置文件的位置,以便与其他人轻松共享(并在此文件夹结构中将ClientName替换为VendorName并将ProjectName替换为AppName;并且branch || tags可用于标记不同主要版本的设置供应商产品的版本)。

欢迎您对我的结构发表评论-我最近将其更改为该结构,到目前为止还算很高兴,但是有时发现为每个项目维护分支结构很麻烦-特别是如果该项目只是一个项目设置而仅仅是对另一个项目进行单元测试时。


1

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

但是,即使那样,也不是使用倍数的好理由。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.