将一个git-svn分支迁移到一个git分支

3

我的项目(非常庞大,约有200万行代码和数万个提交记录)目前正在从git-svn切换到git。许多用户在git-svn上有分支和历史记录,这些内容在新的纯git仓库中也很有用。基本情况如下:

旧的git-svn仓库:

A-B-C-D-E-F (master)

我在这个代码库中有一个分支,已经多次合并了主分支,例如:

    G-H---I-J-K (feature)
   /     /
A-B-C-D-E-F (master)

我希望将这个分支移动到新的纯Git存储库中并保留我的历史记录。更复杂的是,纯Git存储库和svn存储库的目录结构略有不同。具体而言,此存储库中的基本目录结构有两个目录,例如:
foo/ bar/
在新的Git存储库中,bar/已移至新存储库。
如何将此分支移动到新存储库,并最终在纯Git存储库中获得以下结果?
    G'-H'----I'-J'-K' (feature)
    /       /
A'-B'-C'-D'-E'-F' (master)

我认为以下内容应该可行:
从git-svn仓库的特性分支开始:
git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch bar" B..HEAD

这将删除foo目录的所有修改,因为在新版本库中该目录不存在。然后,在纯git repo中将git-svn repo添加为远程库,并执行以下操作:

git checkout -b B' feature
git rebase --preserve-merges --onto feature remotes/old_git_svn_repo/master remotes/old_git_svn_repo/feature

不幸的是,这似乎不起作用。我仍然需要手动解决我在特性分支中已经解决过的所有合并冲突。有没有办法实现我的需求?


“E'”目前是什么样子?如果它是一个合并提交,那么它合并了什么,如果你的分支不在仓库中呢? - Chronial
E' 只是一个普通的提交,但 I' 是 H' 和 E' 的合并。我能在我的 ASCII 图表中澄清吗? - TimmyJ
是的,请将 H'I' 之间的线条加长,以便从 E'I' 的线条指向正确方向。 - Chronial
1个回答

1

就像你所做的那样,你应该首先运行一个filter-branch --index-filter来修复分支的树结构。但现在你需要修复父关系。根据有多少次合并,有两个选项:

  • 手动进行:查看 git help replacegit replace 允许您用另一个提交替换一个提交。对于每个合并基础,都要这样做。例如:

    git replace B B'
    git replace E E'
    

    请注意,如果您不在 master..feature 上运行 filter-branchB 可能已经具有不同的 SHA。

    完成此步骤后,您需要再次运行 filter-branch 以使替换永久生效。我建议先进行替换,然后再运行 --index-filter。这样您就可以一次性完成所有操作。

  • 使用 --parent-filter 进行:查看 filter-branch--parent-filter 参数。它允许您指定一个脚本来重写父关系。该脚本可以使用每个移植提交消息中应记录的 git-svn-id: 来查找新的 master 中的匹配提交。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接