我用了subgit将旧的 svn 存储库转换为 git(包括完整的历史记录、分支、标签)。在遇到一些最初的麻烦后,我让它开始工作并且几乎完美地工作。除了分支似乎没有 merge 回主干/主分支:
可以看到,git知道我把绿色master分支得到黑色分支。但它似乎并不知道这个分支在提交 73653d1
时被 merge 回 master。看起来我放弃了那个分支并在 master 分支的一次提交中独立实现了所有这些。
这不是正确 merge 的样子,对吧?有没有办法来解决这个问题?请注意,这大约是历史上的 50 次提交,除了看似缺少引用之外,代码还不错。
最佳答案
所以,
r141:复制^/trunk到^/branches/restructure
r142: 修改 ^/branches/restructure
...
r148: 修改 ^/branches/restructure
r149:将 r142:148 从 ^/branches/restructure merge 到 ^/trunk
也就是没有把^/branches/restructure的r141 merge 到r149的^/trunk。
您可能知道,Git 中的 merge 提交包含其每个父项的完整历史记录。这就是为什么 SubGit 在创建 merge 提交时会检查是否所有必要的修订都已 merge 到相应的分支中。
在您的情况下,SubGit 将 r141 检测为 ^/branches/restructure 历史记录中的空白,这就是为什么它没有将此分支添加为 merge 父级以提交 73653d1
。
有人可能会争论:
r141 didn't introduce any file or directory modifications, so why SubGit needs including this revision into svn:mergeinfo?
好吧,在通常情况下,单个 SVN 修订版可能会创建一个分支并修改其中的任何文件。这就是为什么 SubGit 仍然检查分支历史中的每个修订。
但是,SubGit 可能更聪明一些,它会检查创建分支的修订是否修改了其中的任何文件,因此对于您的情况,SubGit 会自动创建 merge 提交。我们可能会在未来实现;这是the issue在我们的跟踪器上。
如何修复 Git 中的历史记录?
由于 Subversion 不允许对现有历史进行任何修改,因此您必须创建一个新修订版,将缺少的 r141 添加到 ^/trunk 的 svn:mergeinfo 属性中。考虑为此执行以下操作:
$ svn switch ^/trunk .
$ svn merge --record-only ^/branches/restructure@148 .
$ svn commit -m 'Merged r141 of restructure changes into the trunk'
如果您保持 Subversion 和 Git 存储库同步,SubGit 应该会自动将此修订转换为 merge 提交。否则,您可以从头开始翻译历史记录,或者再次将 SubGit 安装到同一个 SVN 存储库中。
更新:
如果不再需要 SVN 同步,如何修复 Git 存储库中的历史记录?
您可以使用以下命令重写从 73653d1
commit 开始的 Git 历史部分:
git filter-branch --parent-filter \
'test $GIT_COMMIT = 73653d1 && echo "-p 2ec9e8c -p 5c237f9" || cat' master
注意:使用完整的提交 ID 而不是缩写 73653d1
、2ec9e8c
和 5c237f9
。
此命令应将 5c237f9
提交作为 merge 父级添加到 73653d1
提交。
希望对您有所帮助。
关于从 svn 切换后 Git 分支未 merge ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13803503/