恢复合并与重置合并
我的猜测是你实际上是 Already-up-to-date
。
问题是git revert不会撤消合并,它只会撤消合并带来的更改。当您创建合并提交时,您将合并这两个分支的提交历史。
合并
develop
|
A---B---C
\ \
E---F---M
|
newfeature
在上述情况下,develop
合并到newfeature
中,创建M
提交。如果您要运行git log newfeature
,您会看到来自两个分支的所有提交,但是从分支的角度来看newfeature
,所有这些更改都是由M
提交执行的。
还原
该git revert
命令不会删除任何提交,而是创建一个新的提交,以撤消提交包含的更改。例如,如果您有一个包含此差异的提交...
-This is the old sentence.
+This is the new sentence.
然后恢复它,revert 命令将创建一个新的提交,它刚刚执行了相反的差异,它只是翻转了符号。
-This is the new sentence.
+This is the old sentence.
这对于撤消其他开发人员已经拥有的提交造成的损害非常有用。它推动历史前进,而不是改变历史。
恢复合并
但是,在非快进合并的情况下,它可能会产生不良影响。
develop
|
A---B---C
\ \
E---F---M---W
|
newfeature
假设 W 是一个回复提交,你可以看到 runninggit log newfeature
仍然会包含来自开发分支的所有提交。结果,来自的其他合并develop
将不起作用,因为它看不到您的分支中缺少任何内容。
使用git reset而不是还原。
将来,如果合并尚未与其他开发人员共享,您可能需要考虑使用git reset --hard <ref>
(合并的提交哈希在哪里)撤消合并。<ref>
在上面的示例中,在创建了 merge commit 之后M
,运行该命令git reset --hard F
将导致以下结果。
develop
|
A---B---C
\ \
E---F---M
|
newfeature
正如您所看到的,这种技术不会像某些人认为的那样消除提交,它只是将您的分支移回您选择的提交。现在如果你跑了git log newfeature
,你只会得到 commit F
,E
和A
. 现在合并实际上已从您的分支历史记录中消失,因此稍后尝试重新合并develop
不会导致任何问题。
这种方法并非没有复杂性。意识到您现在正在修改历史记录,因此如果在合并newfeature
后分支被推送到远程分支M
,那么 git 会认为您只是过时并告诉您需要运行git pull
. 如果只是您在那个远程分支上工作,那么请随意force-push
- git push -f <remote> <branch>
。这将具有与重置相同的效果,但在远程分支上。
如果这个分支正在被多个开发人员使用,而他们现在已经从中撤出 - 那么这是一个坏主意。这是非常git revert
有用的原因,因为它在不改变实际历史的情况下撤消更改。
对历史记录使用重置实际上仅适用于尚未共享的提交。
解决方案 - 还原还原。
如果合并提交已经被共享,那么最好的方法可能是git revert
在该合并上使用。但是,正如我们之前所说,您不能简单地将分支合并回来并期望该分支的所有更改重新出现。答案是还原还原提交。
假设您在develop
尊重合并后在分支上做了一些工作newfeature
。你的历史看起来像这样。
develop
|
A---B---C---D
\ \
E---F---M---W
|
newfeature
如果你合并develop
到newfeature
现在,你只会得到D
,因为它唯一的提交还不是newfeature
分支历史的一部分。您还需要做的是恢复该W
提交 -git revert W
应该做的伎俩是git merge develop
.
develop
|
A---B---C-----------D
\ \ \
E---F---M---W---M---G
|
newfeature
这将恢复原始合并提交所做的所有更改——这些更改实际上是由原始合并提交进行的C
,B
但被还原了W
,然后它D
通过新的合并提交引入我G
建议在合并最近的更改之前develop
还原还原,我怀疑这样做以该顺序触发冲突的可能性较低。
TL;博士
还原会创建一个“还原提交”。撤消还原时,您需要对第一次还原时创建的还原提交运行还原命令。它应该很容易找到,git 倾向于自动评论恢复,以便它们以“Reverted”一词开头。
git revert <commit>