3

我使用subgit将旧的 svn 存储库转换为 git(包括完整的历史记录、分支、标签)。经过一些最初的麻烦后,我让它工作了,它几乎完美地工作了。除了分支似乎没有合并回主干/主分支:

在此处输入图像描述

可以看到,git知道我分支了绿色的master得到了黑色的分支。但它似乎不知道这个分支在 commit 时被合并回了 master 73653d1。看起来我放弃了那个分支,并在主分支的一次提交中独立实现了所有这些。

这不是正确合并的样子,对吧?有没有办法解决这个问题?请注意,这大约是历史上的 50 次提交,除了看似缺少的参考之外,代码还不错。

4

1 回答 1

5

所以,

r141:将 ^/trunk 复制到 ^/branches/restructure
r142:修改 ^/branches/restructure
...
r148:修改 ^/branches/restructure
r149:将 r142:148 从 ^/branches/restructure 合并到 ^/trunk

也就是说,没有将 ^/branches/restructure 的 r141 合并到 r149 的 ^/trunk 中。

您可能知道,Git 中的合并提交包括其每个父项的全部历史记录。这就是为什么 SubGit 在创建合并提交时会检查所有必要的修订是否已合并到相应的分支中。

在您的情况下,SubGit 将 r141 检测为 ^/branches/restructure 历史中的一个空白,这就是为什么它没有将此分支作为合并父级添加到 commit 的原因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'

如果您保持 Subversion 和 Git 存储库同步,SubGit 应该自动将此修订转换为合并提交。否则,您可以从头开始翻译历史记录,或者只需将 SubGit 再次安装到同一个 SVN 存储库中。

更新:
如果不再需要 SVN 同步,如何修复 Git 存储库中的历史记录?

73653d1您可以使用以下命令重写从提交开始的部分 Git 历史记录:

git filter-branch --parent-filter \
'test $GIT_COMMIT = 73653d1 && echo "-p 2ec9e8c -p 5c237f9" || cat' master

注意:使用完整的提交 ID 而不是缩写的73653d1,2ec9e8c5c237f9.

此命令应将提交添加为要5c237f9提交的合并父73653d1级。

希望有帮助。

于 2012-12-10T17:20:32.647 回答