在考虑了我之前的问题(One SVN Repository or many?)的答案之后,我决定采用我拥有的4个左右的存储库并将它们合并为一个。这当然会导致一个问题,最好的方法是什么?
有没有办法组合两个或多个存储库来维护两者的版本历史记录?
编辑:我还应该指出我正在使用Assembla.com,它不提供对svnadmin命令的访问权限,AFAIK
另一个编辑:这是否重要?如果svnadmin适用于URL,那么就没问题了。
答案 0 :(得分:72)
编辑:哦,问题编辑是在我打字时进行的。这是
的答案有没有办法合并两个或更多 存储库维护版本 两者的历史?
假设
现有存储库的结构如下:
你需要一个类似的结构:
然后为每个项目存储库:
svnadmin dump > project<n>.dmp
然后为每个转储文件:
svn mkdir "<repo url>/project<n>"
svnadmin load --parent-dir "project<n>" <filesystem path to repos>
更复杂的操作是可能的,但这是最简单,最直接的。在转储/加载期间更改源存储库结构是危险的,但可以通过svnadmin dump
,svndumpfilter
,手动编辑或其他文本过滤器和svnadmin load
与第三方提供商打交道
svnadmin dump
个文件。提供商应该愿意/能够提供这个 - 是 您的代码!YMMV:这似乎是一种合理的方法,但我从未与这样的第三方提供商合作过。
答案 1 :(得分:10)
使用Subversion 1.7,您现在可以远程执行转储。也就是说,无需访问本地文件系统和svnadmin dump
命令。
您可以使用svnrdump
来获取远程存储库的完整转储。有关语法详细信息,请参阅文档。
请注意,服务器不必运行1.7,只需运行客户端。
http://svnbook.red-bean.com/en/1.7/svn.ref.svnrdump.c.dump.html
答案 2 :(得分:9)
是的,使用svnadmin dump和svnadmin load。
我们假设您需要存储库,一个使用HEAD修订版100,另一个使用HEAD修订版150.
您转储第一个存储库并将其加载到新存储库中:最终得到第一个存储库的完整故事,从修订版0到修订版150.
然后您转储第二个存储库并将其加载到新存储库中:它将加载其完整历史记录,唯一改变的是实际修订版本号。第二个存储库的历史记录将在新版本的存储库中表示,从版本151到版本250。
两个存储库的完整历史记录都是保存程序,只有导入第二个存储库的修订号才会更改。
同样适用于两个以上的存储库。
编辑:我在编辑时发布了,所以我没有看到你的笔记......答案 3 :(得分:3)
如果您无法访问svnadmin,那将很难但是可行。假设您有存储库A和B,并希望将它们合并到存储库C中。以下是您必须使用的步骤来实现此目的。
将存储库A的修订版1签出到您的硬盘。
在C存储库的根目录下创建一个名为Repository_A的目录,并将其签出到本地硬盘。
将您的A(减去).svn文件中的文件复制到Repository_A文件夹中的C结帐中。
在C上执行提交。
将您的存储库A的工作副本更新为版本2,并执行步骤3和4,并重复每个连续的修订,直到您到达头部。
现在对B.做同样的事情。
这基本上和@Davide Gualano建议的一样,不需要svnadmin。您可以编写一个简单的脚本来为您执行此操作,如果没有很多修订,您可以手动执行此操作。
答案 4 :(得分:3)
您可以使用以下步骤在一个存储库中加载许多转储文件。
存储库根目录:
projectA
branches
tags
trunk
projectB
branches
tags
trunk
首先,您必须在存储库根目录中创建目录(项目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
这样,您将拥有一个包含许多转储存储库的存储库。
答案 5 :(得分:1)
这个问题的其他答案使我能够制作下面的脚本。根据您的情况调整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