修复一个坏的合并
Fixing a bad merge that got baked in
所以我们的团队是 Git 的新手。我们遇到了类似 this one 的情况,只是更糟:开发人员进行了错误的合并,并且此错误合并已被埋没在大约 20 次后续提交中,因为我们在一天后才注意到错误合并。
我们如何解决这个问题?
编辑: 看起来 git revert -m
命令可能是诀窍,但我们真正需要还原的只有一个文件……一个大的 edmx 文件得到了严重损坏。有什么方法可以限制恢复到那个文件吗?
如果只有一个损坏的文件,您可以在没有问题的地方找到一个提交并从那里检出它:
git checkout <revision> -- path/to/file
然后在下次提交时保存。
鉴于您的编辑,我建议提取文件的完整副本 "pre-merge" 以及任何需要的更改。有多种方法可以做到这一点:您可以反向应用合并带来的更改,希望任何后续更改不会冲突或重叠;您可以提取一个好的预合并版本并检查是否需要任何更新;等等。
例如,如果 <revspec>
是具有已知良好版本文件的提交:
$ git log <revspec>..HEAD -- path/to/file # find changes to file
(这将显示所有可从 HEAD
访问但不能从 <revspec>
或其父文件访问的提交;这应该包括合并本身,显然你 不想 保留,但也会显示做出更改的提交,毕竟您可能想要保留)。
$ git checkout <revspec> -- path/to/file
(这只是将旧版本提取到工作目录中,并将其也写入索引,即,它已经准备好提交)。
现在,如果有您做想要更改的修订:
$ git show <rev> -- path/to/file | git apply
... repeat for all <rev>s, make sure they all apply;
do manual work if needed ...
$ git add path/to/file
如果三个都没有这样的修改,你不需要应用任何东西,也不需要 add
结果;您现在可以 git commit
.
一种不同的方法,但现在您必须选择哪个 "side" 合并引入了错误的东西。假设坏东西来自第二个父级(分支合并,而不是分支合并):
$ git diff <mergerev>^1 <mergerev> -- path/to/file | git apply -R
这里我们得到 git diff
以显示文件如何从 "good"(mergerev 的第一个父级)更改为 "bad"(mergerev,从第二个父级引入更改),和 "reverse apply" 对工作树的那些更改。
如果一切顺利,git add
修复文件并提交。
所以我们的团队是 Git 的新手。我们遇到了类似 this one 的情况,只是更糟:开发人员进行了错误的合并,并且此错误合并已被埋没在大约 20 次后续提交中,因为我们在一天后才注意到错误合并。
我们如何解决这个问题?
编辑: 看起来 git revert -m
命令可能是诀窍,但我们真正需要还原的只有一个文件……一个大的 edmx 文件得到了严重损坏。有什么方法可以限制恢复到那个文件吗?
如果只有一个损坏的文件,您可以在没有问题的地方找到一个提交并从那里检出它:
git checkout <revision> -- path/to/file
然后在下次提交时保存。
鉴于您的编辑,我建议提取文件的完整副本 "pre-merge" 以及任何需要的更改。有多种方法可以做到这一点:您可以反向应用合并带来的更改,希望任何后续更改不会冲突或重叠;您可以提取一个好的预合并版本并检查是否需要任何更新;等等。
例如,如果 <revspec>
是具有已知良好版本文件的提交:
$ git log <revspec>..HEAD -- path/to/file # find changes to file
(这将显示所有可从 HEAD
访问但不能从 <revspec>
或其父文件访问的提交;这应该包括合并本身,显然你 不想 保留,但也会显示做出更改的提交,毕竟您可能想要保留)。
$ git checkout <revspec> -- path/to/file
(这只是将旧版本提取到工作目录中,并将其也写入索引,即,它已经准备好提交)。
现在,如果有您做想要更改的修订:
$ git show <rev> -- path/to/file | git apply
... repeat for all <rev>s, make sure they all apply;
do manual work if needed ...
$ git add path/to/file
如果三个都没有这样的修改,你不需要应用任何东西,也不需要 add
结果;您现在可以 git commit
.
一种不同的方法,但现在您必须选择哪个 "side" 合并引入了错误的东西。假设坏东西来自第二个父级(分支合并,而不是分支合并):
$ git diff <mergerev>^1 <mergerev> -- path/to/file | git apply -R
这里我们得到 git diff
以显示文件如何从 "good"(mergerev 的第一个父级)更改为 "bad"(mergerev,从第二个父级引入更改),和 "reverse apply" 对工作树的那些更改。
如果一切顺利,git add
修复文件并提交。