将多个SVN存储库合并为一个

考虑到我以前的问题( 一个SVN库或许多? )的答案,我已经决定采取我有的4个左右的库,并巩固成一个。 这当然会导致这样的问题, 最好的办法是什么?

有没有办法将两个或多个版本库合并在一起,维护版本历史logging?

编辑: 我还应该指出,我正在使用Assembla.com,它不提供访问svnadmin命令,AFAIK

另一个编辑: 这是否甚至重要? 如果svnadmin在URL上工作,那么这是没有问题的。

编辑:哦,这个问题编辑是在我打字时进行的。 这是一个答案

有没有办法将两个或多个版本库合并在一起,维护版本历史logging?


假如说

现有的软件库具有如下结构:

  • 版本库根目录
    • 分支机构
    • 标签
    • 树干

你需要一个像这样的结构:

  • 版本库根目录
    • 了projectA
      • 分支机构
      • 标签
      • 树干
    • 项目B
      • 分支机构
      • 标签
      • 树干

然后,对于您的每个项目存储库:

svnadmin dump > project<n>.dmp 

然后为每个转储文件:

 svn mkdir "<repo url>/project<n>" svnadmin load --parent-dir "project<n>" <filesystem path to repos> 

更复杂的操作是可能的,但这是最简单,最直接的。 在转储/加载期间更改源代码库结构是危险的,但是可以通过svnadmin dumpsvndumpfilter ,手动编辑或其他文本filter和svnadmin load


处理第三方提供商

  • 为每个存储库请求svnadmin dump文件。 提供者应该愿意/能够提供这个 – 这 你的代码!
  • 在本地创build一个SVN仓库。
  • 对转储文件执行上面列出的操作。
  • 使用您最喜爱的客户端validation存储库结构是否正确。
  • 为组合存储库创build一个转储文件。
  • 请求提供者从此转储文件填充新的存储库。

YMMV:这似乎是一个合理的方法,但我从来没有像这样的第三方提供商。

使用Subversion 1.7,您现在可以远程执行转储。 也就是说,无法访问本地文件系统和svnadmin dump命令。

您可以使用svnrdump来获取远程存储库的完整转储。 有关语法详细信息,请参阅文档

请注意,服务器不必运行1.7,只有客户端。

http://svnbook.red-bean.com/en/1.7/svn.ref.svnrdump.c.dump.html

是的,使用svnadmin转储和svnadmin加载 。

我们假设你必须有一个版本库,一个版本是HEAD版本100,另一个是版本号为150的版本。

您转储第一个存储库并将其加载到新的存储库中:您将得到第一个存储库的全部内容,从版本0到版本150。

然后,转储第二个存储库,并将其加载到新的存储库中:它将被加载完整的历史logging,唯一改变的是实际的修订版本号。 第二个存储库的历史将在从修订版151到修订版250的新存储库中表示。

这两个存储库的完整历史logging是保留的,只有导入次要版本库的版本号才会更改。

当然同样适用于两个以上的存储库。

编辑:我发布时,你正在编辑,所以我没有看到你的笔记…

您可以使用以下步骤在一个存储库中加载许多转储文件。

存储库根目录:

  projectA branches tags trunk projectB branches tags trunk 

首先,您必须像这样在您的存储库根目录下创build目录(项目A,项目B):

 $ svn mkdir -m "Initial project root" \ file:///var/svn/repository_root/Project_A\ file:///var/svn/repository_root/Project_B\ file:///var/svn/repository_root/Project_C\ Revision 1 committed. 

之后,您可以加载您的转储文件:

使用参数--parent-dir DIRECTORY

 $ svnadmin load /var/svn/repository_root --parent-dir Project_A < file-dump-PRJA.dump … $ svnadmin load /var/svn/repository_root --parent-dir Project_B < file-dump-PRJB.dump 

这样你将有一个存储库,其中包含许多倾销的存储库。

如果你没有访问svnadmin,这将是困难的,但可行的。 假设您有存储库A和B,并且想要将它们合并到存储库C中,那么您将需要使用这些步骤来完成此操作。

  1. 检查存储库A的修订版本1到您的硬盘。

  2. 在你的C库的根目录下创build一个名为Repository_A的目录,并检查你的本地硬盘。

  3. 将文件从A(减).svn文件中复制到Repository_A文件夹中的C的签出。

  4. 对C进行提交

将版本库A的工作副本更新到修订版本2,并执行步骤3和4,并重复每一个连续的修订,直到您到达首位。

现在和B一样

这基本上和@Davide Gualanobuild议的一样,不需要svnadmin。 你可以写一个简单的脚本来为你做这个,如果没有很多的修改,你可以手动完成。

这个问题的其他答案使我能够在下面创build脚本。 根据您的情况调整REPOS地图。 另外,您可能希望将标签和分支移动到“预聚集”目录中,而不是直接转移到新分支和中继。

 #!/bin/bash NEWREPO=$(pwd)/newrepo NEWREPOCO="${NEWREPO}_co" DUMPS=repodumps REV="0:HEAD" REPOROOT=/data/svn/2.2.1/repositories/ TOOLDIR=/opt/svn/2.2.1/bin/ PATH=${PATH}:${TOOLDIR} # Old Repository mapping declare -A REPOS=( [BlaEntityBeans]='( [newname]="EntityBeans" )' [OldServletRepoServlet]='( [newname]="SpreadsheetImportServlet" )' [ExperimentalMappingXML]='( [newname]="SpreadsheetMappingXML" )' [NewImportProcess]='( [newname]="SpreadsheetImportProcess" )' ) dump() { rm -fr ${DUMPS} mkdir ${DUMPS} for repo in "${!REPOS[@]}" do local dumpfile=${DUMPS}/${repo}.dmp echo "Dumpimg Repo ${repo} to ${dumpfile}" svnadmin dump -r ${REV} ${REPOROOT}/${repo} > ${dumpfile} done } loadRepos() { # new big repo rm -fr ${NEWREPO} svnadmin create ${NEWREPO} svn mkdir file:///${NEWREPO}/trunk -m "" svn mkdir file:///${NEWREPO}/branches -m "" svn mkdir file:///${NEWREPO}/tags -m "" # add the old projects as modules for currentname in "${!REPOS[@]}" do declare -A repo=${REPOS[$currentname]} local newname=${repo[newname]} echo "Loading repo ${currentname} soon to be ${newname}" dumpfile=${DUMPS}/${currentname}.dmp # import the current repo into a trmporary root position svn mkdir file:///${NEWREPO}/${currentname} -m "Made module ${currentname}" svnadmin load --parent-dir ${currentname} ${NEWREPO} < ${dumpfile} # now move stuff arround # first rename to new repo svn move file:///${NEWREPO}/${currentname} file:///${NEWREPO}/${newname} -m "Moved ${currentname} to ${newname}" # now move trunk, branches and tags for vc in {trunk,branches,tags} do echo "Moving the current content of $vc into ${NEWREPO}/${vc}/${newname}" svn move file:///${NEWREPO}/${newname}/${vc} file:///${NEWREPO}/${vc}/${newname} -m "Done by $0" done svn rm file:///${NEWREPO}/${newname} -m "Removed old ${newname}" done } dump loadRepos