我使用subgit将旧的svn存储库转换为git(包括完整的历史记录,分支,标记)。经过一些初步的麻烦,我得到了它的工作,它几乎完美的工作。除了分支似乎没有合并回主干/主分支:
正如你所看到的,git知道我将绿色主人分支以获得黑色分支。但它似乎并不知道这个分支在提交73653d1
时被合并回主服务器。看起来我放弃了那个分支,并在master分支中的一次提交中独立实现了所有这些。
这不是正确合并的样子,对吧?有没有办法来解决这个问题?请注意,这是历史上大约50次提交,除了看似缺失的引用之外,代码还可以。
答案 0 :(得分:5)
所以,
r141:将^ / trunk复制到^ / branches / restructure
r142:修改^ / branches / restructure
...
r148:修改^ / branches / restructure
r149:从^ / branches / restructure到^ / trunk
也就是说,在r149没有将^ / branches / restructure的r141合并到^ / trunk中。
正如您可能知道的,Git中的合并提交包括其每个父级的整个历史记录。这就是为什么SubGit会在创建合并提交时检查是否所有必要的修订都合并到相应的分支中。
在您的情况下,SubGit检测到r141为^ / branches / restructure历史记录中的间隙,这就是为什么它没有将此分支添加为提交73653d1
的合并父项。
有人可能会说:
r141没有引入任何文件或目录修改,为什么SubGit需要将此修订版包含在svn:mergeinfo中?
嗯,通常情况下,单个SVN修订版可能会创建一个分支并修改其中的任何文件。这就是为什么SubGit仍会检查分支历史中的每个修订版。
但是,SubGit可能会更聪明,并检查创建分支的修订版是否修改了其中的任何文件,因此对于您的情况,SubGit会自动创建合并提交。我们将来可能会实施;这是我们跟踪器的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应自动将此修订转换为合并提交。否则,您可以从头开始翻译历史记录,或者只是再次将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
commit作为合并父项添加到73653d1
commit。
希望有所帮助。