我使用subgit将旧的svn仓库转换为git(包括完整的历史记录、分支和标签)。经过一些初步的麻烦,我让它工作起来了,几乎完美无缺。但是分支似乎没有合并回主干/主分支:
73653d1
时合并回主分支。它看起来像是我放弃了那个分支,并独立地在主分支中实现了所有内容的单个提交。这不是正确合并应该看起来的样子,对吧?有没有办法解决这个问题?请注意,这大约是50次提交之前的历史记录,除了看似缺少的引用外,代码没问题。
所以,
r141: 复制了 ^/trunk 到 ^/branches/restructure
r142: 修改了 ^/branches/restructure
...
r148: 修改了 ^/branches/restructure
r149: 将 ^/branches/restructure 的 r142:148 合并到了 ^/trunk
也就是说,r149 没有将 ^/branches/restructure 的 r141 合并到 ^/trunk。
正如您可能已经知道的,Git 中的合并提交包括其每个父提交的完整历史记录。这就是为什么 SubGit 在创建合并提交时会检查是否将所有必要的修订版本合并到相应的分支中。
在您的情况下,SubGit 将 r141 识别为 ^/branches/restructure 历史记录中的缺口,这就是为什么它没有将此分支添加为提交 73653d1
的合并父级。
有人可能会争论:
r141 没有引入任何文件或目录修改,那么 SubGit 为什么需要将此修订版本包括在 svn:mergeinfo 中呢?
好吧,在常见情况下,单个 SVN 修订版本可能会创建一个分支 并且 修改其中的任何文件。这就是为什么 SubGit 仍会检查分支的每个历史记录。
但是,SubGit 可能会更加智能,并检查创建分支的修订版本是否修改其中的任何文件,因此对于您的情况,SubGit 将自动创建合并提交。我们可能会在未来实现这一点;这是我们跟踪器中相应的 问题。
如何在 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'
73653d1
提交开始的Git历史记录的一部分:git filter-branch --parent-filter \
'test $GIT_COMMIT = 73653d1 && echo "-p 2ec9e8c -p 5c237f9" || cat' master
注意:请使用完整的提交ID而不是缩写的73653d1
,2ec9e8c
和5c237f9
。
该命令应将5c237f9
提交作为合并父提交添加到73653d1
提交中。
希望对你有所帮助。
73653d1
提交。我刚刚在我的答案中更新了这个。 - vadishev
svn merge
之后,主干没有得到正确的_svn:mergeinfo_属性。请运行svn propget svn:mergeinfo ^/trunk@rXYZ
,其中rXYZ
是73653d1
的版本号。合并信息是否包括分支的r141:r148版本? - vadishevsvn:mergeinfo ^/trunk@r149
返回/branches/restructure:142-148
。 - Jawapgit fetch origin refs/svn/attic/branches/restructure/*:refs/tmp/restructure/*
从git中访问它,这将在分支被删除之前获取那些修订版本。 - vadishev