我们有一个非标准的subversion repository,我们想将其转换为Git。问题是,我真的不知道从哪里开始,以确保我们保持完整的历史,但不会以一团糟告终。
我们的存储库拥有过去6年的公司产品套件历史,并经历了多次重组。在所有情况下,我们都有一个核心平台代码库,然后在核心平台上以不同方式组合的几个项目/插件。
最初几年的结构如下:
-- plugin1
- trunk
- branches
- tags
-- pluginX
- trunk
- branches
- tags
-- trunk (core platform)
- <various sub dirs)
-- branches (various feature branches of the entire repository)
- refactoring1
- refactoringX
-- tags (various tags of customer releases of full respository)
- customerX_1.x
-- vendor (vendor drops and tracking of 3rd party source deps)
- 3rd_party_code_A
- 3rd_party_code_X
随着时间的推移,我们添加了更多的根目录,包括:
-- releases (replaced tags; branches for released stable versions of repos)
-- sandbox (area for misc projects of interest; should have been new repo)
然后我们清理了这个,最后得到了:
-- trunk
- platform
- plugin1
- pluginX
-- stable (stable release branches of trunk)
- 1.1
- 1.2
-- tags (release points; marks a point on a stable branch)
- 1.1.1
- 1.1.2
-- vendor
-- sandbox
-- releases (copies of old releases of interest)
这就是我们的历史。我们希望最终得到的是更干净的东西。现在,我们认为git存储库的基础是这样的(基本上是前一个"trunk"目录的副本)。
- platform
- plugin1
- pluginX
Branches:
- stable/1.1
- stable/1.2
Tags:
- rel/1.1.1
- rel/1.1.2
我们希望将沙盒和供应商放入他们自己的存储库中。(不知道如何做到这一点,但也许有一种方法可以只导入svn存储库的一个子集)
至于分支和标记,我们希望来自"stable"的代码最终成为分支,来自"tags"的代码最后成为stable中的标记。
对于原始结构中的旧历史,我们希望保留尽可能多的历史,但不想污染新的存储库。例如,如果我们可以回顾并看到重构分支上发生的更改,这些更改将是非常好的,但不是绝对需要的。
目前,我们正在讨论如何进行,以及如何以一种干净的方式重组和进口一切。我们最不需要的是一种方法,在之前的两次重组中都有完整的平台和插件代码的历史。如果可能的话,我们还希望从最新的存储库结构中获得稳定的和标记的信息。
有人对如何进口有建议吗?
例如:
- 是否有可能保留整个重组的完整历史
- 我们是否应该在导入之前以某种方式重写subversion存储库以进行清理?如果是,如何进行
- 我们应该导入完整的历史记录,然后在Git中对其进行重组吗
- 关于如何让这个进口产品变得干净,有什么想法吗
根据您的情况,git-svn(带有默认的--follow-parent
选项)可能会按原样运行。您应该做的第一件事是尝试运行几次git-svm,仔细拼写-T
、-b
和-t
选项,以帮助它处理目录结构。
不过,您可能会遇到复杂目录结构历史记录的问题。
我最近遇到了一个非常类似的情况,将我公司的Subversion代码迁移到git,在那里SVN历史经历了与您所描述的非常相似的重组。在我的案例中,我还想将项目从一个Subversion存储库分离到多个Git存储库(每个项目一个)。
我能够采取简单的方法,决定迁移几个月以上的历史并不重要,所以对于每个项目,我都确定git-svn可以优雅地处理的最早版本,然后只从那里获取历史(使用git-svn -r
)。在处理过以前的VCS迁移(VSS到SVN,2005)后,我从经验中知道,长期历史几乎从未被提及。在任何情况下,让旧的Subversion服务器运行(以只读模式)都很容易,以便在必要时可以使用它来查找信息。
我不知道有什么简单的方法可以清理Subversion的历史,除了使用svndumpfilter
来排除其中的某些部分。不过,如果你幸运的话,git-svn会神奇地做正确的事情,而且git log
中的历史实际上会比svn log
中的历史看起来更干净(因为git看待分支和标记的方式不同)。
通常,在进行此类迁移时,历史的清洁度和完整性是两个相互冲突的目标。幸运的是,它们都被高估了——它们都更吸引我们的美感,而不是实用的必需品。
编辑:关于清洁的小提示:在git-svn上使用--prefix
选项,为导入的分支提供一个唯一的前缀,因为在git中可能会有不同的分支约定,这使得以后查看svn历史记录变得很容易。