3

我的项目(相当大,大约 200 万行代码和数万次提交)目前正在从 git-svn 切换到 git。许多用户都有带有历史记录的 git-svn 分支,这在新的纯 git 存储库中会很不错。基本场景是这样的

旧的 git-svn 存储库:

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

我在此存储库上有一个分支,该分支已多次合并 master,例如:

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

我想将此分支移动到新的纯 git 存储库并维护我的历史记录。为了让事情变得更复杂,pure-git 存储库和 svn 存储库的目录结构略有不同。具体来说,此存储库中的基本目录结构有两个目录,例如:

foo/ bar/

在新的 git 存储库中,bar/已经移动到新的存储库。

如何将此分支移动到新存储库并最终在纯 git 存储库中得到类似的东西?

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

我认为以下方法会起作用:

从 git-svn repo 上的特性分支:

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch bar" B..HEAD

这应该删除对 foo 目录的所有修改,这在新仓库中不存在。然后,将 git-svn 存储库添加为纯 git 存储库的远程,并从纯 git 存储库执行此操作:

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

不幸的是,这似乎不起作用。我仍然需要手动解决我在功能分支中已经解决的所有合并冲突。有没有办法做我想做的事?

4

1 回答 1

1

正如您所做的那样,您应该运行的第一件事是filter-branch --index-filter修复分支的树结构。但现在你需要修复父母关系。根据合并的次数,有两种选择:

  • 手动操作:看看git help replacegit replace允许您将一个提交替换为另一个。为每个合并库执行此操作。例如:

    git replace B B'
    git replace E E'
    

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

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

  • --parent-filter 来做。看看 的--parent-filter论点filter-branch。它将允许您指定一个脚本来重写父关系。该脚本可以使用git-svn-id:应该记录在每个移植的提交消息中的 ,以在新的master.

于 2013-04-28T18:44:53.907 回答