我计划迁移一堆代码库的 svn 到 git。其中两个处于特定状态。
一个项目在 svn 存储库中已经开发完成。由于各种约束,该项目在某个时候被分叉了。复制 svn 存储库来制作分叉。从那时起,这两个项目分别演进。除了主干之外,两个存储库中都不存在任何分支或标签。
原始项目开发了重要的功能,需要将其移植到分支上。在当前情况下,可以通过从不同版本创建补丁并将其应用于分支项目来完成此操作。这样做的优点是短期内方便,但长期具有许多棘手的后果。
我们可以拥有两个不同的 git 存储库,并通过拉取请求进行跨分支移植,但这可能缺乏可用性(我们没有使用 GitHub)。此外,可能会出现我们希望通过模块化设计重构将分支重新集成到父项目中的时间。另一种方法是将两个 svn 存储库合并为单个 git 存储库的不同分支,并从那里管理后续合并(具有所有它所提供的优点)。
理想情况下,我想重新创建项目的真实历史记录,即具有以下内容的 git 存储库:
- 一个包含分叉之前的提交的单一分支 - 两个不同的分支,由父分支和分叉分支的提交组成
一个有趣的事实可能会有所帮助,以下命令为通用提交生成相同的 SHA1:
我不关心
如果可能的话,我该如何实现这样的结果?
一个项目在 svn 存储库中已经开发完成。由于各种约束,该项目在某个时候被分叉了。复制 svn 存储库来制作分叉。从那时起,这两个项目分别演进。除了主干之外,两个存储库中都不存在任何分支或标签。
原始项目开发了重要的功能,需要将其移植到分支上。在当前情况下,可以通过从不同版本创建补丁并将其应用于分支项目来完成此操作。这样做的优点是短期内方便,但长期具有许多棘手的后果。
我们可以拥有两个不同的 git 存储库,并通过拉取请求进行跨分支移植,但这可能缺乏可用性(我们没有使用 GitHub)。此外,可能会出现我们希望通过模块化设计重构将分支重新集成到父项目中的时间。另一种方法是将两个 svn 存储库合并为单个 git 存储库的不同分支,并从那里管理后续合并(具有所有它所提供的优点)。
理想情况下,我想重新创建项目的真实历史记录,即具有以下内容的 git 存储库:
- 一个包含分叉之前的提交的单一分支 - 两个不同的分支,由父分支和分叉分支的提交组成
一个有趣的事实可能会有所帮助,以下命令为通用提交生成相同的 SHA1:
git svn clone -s -A svn.authors --no-metadata http://subversion.foo.local/repo/path git_migration
我不关心
--no-metadata
,因为这是单向迁移。如果可能的话,我该如何实现这样的结果?
cd git_migration
,git log | grep 'commit' | cut -f2 -d' ' | while read hash; do (cd ../git_migration-2; git log | grep "$hash"); done | head -1
。没有匹配就退出,所以可以自由使用Ctrl+C。注意,这是O(m*n)复杂度(我们有大约2000个版本,这是一次性操作,所以我们不太在意)。 - Lloekigit remote add -f -t master migration2 ../git_migration-2
然后git merge-base $(cat .git/refs/heads/master) $(cat .git/refs/remotes/migration2/master)
产生了与我的 hack 相同的提交,只是速度快得多(多得多!)。感谢 @sehe。 - Lloekigit merge-base master migration2/master
,它会更短 :) (符号名称 - 称为 refs - 将自动解析;请参见 git rev-parse) - sehe