首页 > 解决方案 > 从 svn 到 git 的一次性迁移:如何用源转储替换外部?

问题描述

我正在尝试将我的代码库从 svn 永久迁移到 git,并且由于外部因素而碰壁。

我自由使用 svn 外部组件。我无法预料有一天会迁移到不太灵活的东西,就像 git 子模块一样。多年来我积累了数百个 svn 外部,不仅指向外部相关 repo 中的子目录(也是我自己的代码),但有时指向同一 repo 的不同分支/路径中的子目录,有时通过相对路径和有时通过绝对路径。有时,指向的目标是特定的修订版,有时是尖端。

我已经放弃迁移 svn externals,你不能把一个方形的钉子装进一个圆孔里。只有当您以一种非常简单的方式使用 svn externals 并且已经符合 git 子模块的限制时,它才有效。要迁移并保留有效的历史记录,除了删除所有外部文件并用本地更改替换它们之外,我没有看到任何解决方案。我会有代码重复,但这对于有效历史来说是可以接受的,因为我必须支持的不仅仅是代码库的最新快照。

我希望实现的伪代码:

for each branch:
    for each revision in that branch, from first to last, migrate it to a git commit (as 'git svn clone' does)
        if the revision has any svn externals, copy the directory/file content as is and commit it as if it were local changes, using the same commit message, ('git svn clone' can't do this)
        if the contents of the externals were modified in a later revision, then modify the local files in a git commit too

Final result: a standard git repo with my desired branches and their full history. If git commit 
abcdef123 == svn rev 123, then I get the same file tree from 
"git clone git.example.com/gitrepo && git checkout abcdef123" as I do from 
"svn checkout svn://example.com/svnrepo --revision 123".
If 2 branches evolved from the same ancestor, then that should be reflected in git.

迁移后,我将开始以适合 git 的方式做事:用指向外部存储库的新 git 子模块手动替换本地文件,并相应地更新项目的文件路径。

我怎样才能做到这一点?

标签: gitsvngit-svnsvn-externals

解决方案


推荐阅读