我有一个巨大的 VisualSVN 存储库,其结构如下
/common
└── ^/trunk
├── proj1
│ └── CMakeLists.txt
├── proj2
│ └── CMakeLists.txt
└── projN
└── CMakeLists.txt
5 年之后,19,000 次提交……我想要真正有效的分支。所以我想将该存储库分成几个较小的存储库
/proj1
├── ^/branches
└── ^/trunk
└── CMakeLists.txt
/proj2
├── ^/branches
└── ^/trunk
└── CMakeLists.txt
/projN
├── ^/branches
└── ^/trunk
└── CMakeLists.txt
我该怎么做?
我很高兴使用客户端命令
svn mv
来获得正确的结构,但最重要的是过滤掉所有我不想要的内容。
我开始使用
svnadmin
创建完整存储库的 4GB 转储文件
D:\Repositories> svnadmin dump D:\Repositories\common > common.dump
* Dumped revision 0.
* Dumped revision 1.
...
* Dumped revision 18968.
* Dumped revision 18969.
然后我使用
svndumpfilter
将其减少为仅与感兴趣的项目相关的修订:
D:\Repositories> svndumpfilter \
--drop-empty-revs \
--renumber-revs \
include trunk/proj1 \
< common.dump > proj1.dump
Including (and dropping empty revisions for) prefixes:
'/trunk/proj1'
Revision 0 committed as 0.
Revision 1 skipped.
Revision 2 skipped.
...
Revision 561 committed as 1.
...
Revision 669 committed as 2.
...
Revision 13514 committed as 36.
svndumpfilter: E200003: Invalid copy source path: '/trunk/proj2/file' for `/trunk/proj1/file`
此操作失败,因为在某个时刻执行了
svn mv ^/trunk/proj2/file ^/trunk/proj1/file
。我可以通过简单地添加另一个include
来解决这个问题:
D:\Repositories> svndumpfilter \
--drop-empty-revs \
--renumber-revs \
include \
trunk/proj1 \
trunk/proj2/file \
< common.dump > proj1.dump
...
Revision 13515 comitted as 38.
svndumpfilter: E200003: Missing merge source path '/branches/proj1-tests'; try with --skip-missing-merge-sources
越来越近了,我真的不需要合并历史记录,所以我会按照建议的操作并添加
--skip-missing-merge-sources
D:\Repositories> svndumpfilter \
--drop-empty-revs \
--renumber-revs \
--skip-missing-merge-sources \
include \
trunk/proj1 \
trunk/proj2/file \
< common.dump > proj1.dump
成功!事实上,我已经包含了大约 100 件东西。现在我想用它来创建新的存储库:
D:\Repositories> svnadmin create proj1
D:\Repositories> svnadmin load --ignore-uuid proj1 < proj1.dump
<<< Started new transaction, based on original revision 1
* editing path : trunk/proj2/file
...svnadmin: E160013: File not found: transaction '0-0', path '/trunk/proj2/file'
现在我陷入困境了。我该如何处理?
问题是创建
trunk/proj2
的修订版不包括在内。您可以添加 include trunk/proj2
,但最终可能会添加整个树,而这恰恰违背了过滤的目的。
然后您可以花时间完善过滤器,但是使用 svnadmin 部署的脚本已经做到了这一点:
svnrdump
。
D:\Repositories> svnrdump dump file:///Repositories/common/trunk/proj1 > proj1.dump
D:\Repositories> svnadmin create proj1
D:\Repositories> svnadmin load proj1 < proj1.dump
D:\Repositories> del proj1.dump
或使用管道:
D:\Repositories> svnadmin create proj1
D:\Repositories> svnrdump dump file:///Repositories/common/trunk/proj1 | svnadmin load proj1
然后签出工作副本并根据需要
svn mv
。
D:\Temp> svn checkout file:///Repositories/proj1 proj1.wc
D:\Temp> cd proj1.wc
D:\Temp> svn move trunk/proj1/* trunk/
D:\Temp> svn remove trunk/proj1
D:\Temp> svn commit
可能有一种方法可以包含
--drop-empty-revs --renumber-revs
,但我还没有找到。我尝试了以下方法,但它并没有过滤掉太多:
svnrdump dump file:///Repositories/common/trunk/proj1 > proj1.dump
svndumpfilter --drop-empty-revs --renumber-revs include / < proj1.dump > proj1-filtered.dump
svnadmin load proj1 < proj1-filtered.dump