Pet*_*now 29 git merge conflict
我最初在'newfeature'分支工作,我被要求紧急修复现场分支上的错误.我创建了一个名为'generalmaintenance'的分支,完成了工作,然后切换到开发并合并它.我现在想要返回'newfeature'分支并合并我之前合并到它的更改.
当我切换到'newfeature'并合并'develop'时,3个文件中存在冲突.
我陷入了纠结,解决了冲突,最终决定在Aptana Studio 3(这是我的IDE)的'Team'菜单中使用"Revert"命令.我预计这会让我回到合并之前,它似乎已经完成了.
无论如何,当我再次合并'develop'时,它说,Already-up-to-date
但是当比较两个分支之间的文件时,它们是非常不同的,我在另一个分支中添加的更改没有被合并.
我现在如何合并这两个分支?
edd*_*oya 57
还原合并与重置合并
我的猜测是,你实际上是 Already-up-to-date
.
问题是git revert不会撤消合并,它只会撤消合并带来的更改.创建合并提交时,组合这两个分支的提交历史记录.
合并
develop
|
A---B---C
\ \
E---F---M
|
newfeature
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,develop
合并到newfeature
,创建M
提交.如果您要运行,git log newfeature
您将看到来自两个分支的所有提交,但是从分支的角度来看newfeature
,所有这些更改都是由M
提交执行的.
回复
该git revert
命令不会删除任何提交,而是创建一个新的提交,撤消提交所包含的更改.例如,如果你有一个包含这个差异的提交...
-This is the old sentence.
+This is ne new sentence.
Run Code Online (Sandbox Code Playgroud)
然后还原它,revert命令将创建一个刚刚执行相反diff的新提交,它只是翻转符号.
-This is ne new sentence.
+This is the old sentence.
Run Code Online (Sandbox Code Playgroud)
这对于撤消其他开发人员已经拥有的提交造成的损害非常有用.它推动历史向前发展,而不是改变历史.
恢复合并
但是,在非快速合并的情况下,它可能具有不期望的效果.
develop
|
A---B---C
\ \
E---F---M---W
|
newfeature
Run Code Online (Sandbox Code Playgroud)
假设W是一个reversion提交,你可以看到如何运行git log newfeature
仍然包含来自develop分支的所有提交.因此,其他合并develop
将无效,因为它不会从您的分支中看到任何遗漏.
使用git reset而不是revert.
在将来,如果未与其他开发人员共享该合并,您可能需要考虑使用git reset --hard <ref>
(<ref>
合并的提交哈希值)撤消合并.在上面的示例中,在创建合并提交后M
,运行该命令git reset --hard F
将导致以下结果.
develop
|
A---B---C
\ \
E---F---M
|
newfeature
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这种技术并没有像某些人所想的那样消除提交,它只是将您的分支移回您选择的提交.现在,如果你跑了git log newfeature
,你只会得到承诺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
Run Code Online (Sandbox Code Playgroud)
如果合并develop
到newfeature
现在,你只会得到D
,因为它的唯一的承诺,是不是已经是历史的一部分newfeature
分支.你还需要做的是恢复W
提交 - git revert W
应该遵循的技巧git merge develop
.
develop
|
A---B---C-----------D
\ \ \
E---F---M---W---M---G
|
newfeature
Run Code Online (Sandbox Code Playgroud)
这将恢复原始合并提交所做的所有更改 - 这些更改实际上是由C
并且B
已被还原W
,然后D
通过新的合并提交引入,我G
建议在合并最近的更改之前恢复还原develop
,我怀疑这样做按此顺序触发冲突的可能性较小.
TL; DR
还原会创建"还原提交".撤消还原时,需要在第一次还原时创建的还原提交上运行revert命令.它应该很容易找到,git倾向于自动评论恢复,以便它们以"Reverted"一词开头.
git revert <commit>
找到了一个hacky解决方案。但它有效。
无论eddiemoya回答了什么,都非常有帮助。非常感谢您的解释。我遇到了类似的情况。在哪里,我能够看到很多内容,git diff <branch>
但 git merge 说已经是最新的。
由于日志中有很多还原,我无法找到确切的还原提交。(是的,坏事。一开始就不应该发生)
解决方案
git checkout branchX -- .
Run Code Online (Sandbox Code Playgroud)
这会将所有更改从 branchX 转移到我当前的分支。使用您最喜欢的 git 客户端,取消暂存并还原任何不想要的东西。
进行新的提交并感到高兴:)