我最初在'newfeature'分支工作,我被召唤来紧急修复现场分支上的错误。我创建了一个名为'generalmaintenance'的分支,完成了工作,然后切换到开发并合并它。我现在想要返回'newfeature'分支并合并我之前合并到它的更改。
当我切换到'newfeature'并合并'develop'时,3个文件中存在冲突。
我纠结了解决冲突并最终决定在Aptana Studio 3(这是我的IDE)的'Team'菜单中使用“Revert”命令。我预计这会让我回到合并之前,它似乎已经完成了。
无论如何,当我再次合并'develop'时,它会说Already-up-to-date
,但是当比较两个分支之间的文件时,它们是非常不同的,我在另一个分支中添加的更改没有被合并到
我现在如何合并这两个分支?
答案 0 :(得分:54)
还原合并与重置合并
我的猜测是你实际 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 ne new sentence.
然后还原它,revert命令会创建一个刚刚执行相反diff的新提交,它只是翻转符号。
-This is ne new sentence.
+This is the old sentence.
这对于撤消其他开发人员已经拥有的提交造成的损害非常有用。它推动历史向前发展,而不是改变历史。
还原合并
但是,在非快速合并的情况下,它可能会产生不良影响。
develop
|
A---B---C
\ \
E---F---M---W
|
newfeature
假设W是一个reversion提交,你可以看到运行git log newfeature
仍将包含来自develop分支的所有提交。因此,来自develop
的其他合并将无效,因为它不会从您的分支中看到任何遗漏。
使用git reset代替还原。
将来,您可能需要考虑使用git reset --hard <ref>
(其中<ref>
是合并的提交哈希)来撤消合并,如果该合并尚未与其他开发人员共享。在上面的示例中,在创建了合并提交M
之后,运行命令git reset --hard F
将导致以下结果。
develop
|
A---B---C
\ \
E---F---M
|
newfeature
正如您所看到的,这种技术并没有像某些人所想的那样消除提交,它只是将您的分支移回您选择的提交。现在,如果您运行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
如果您现在将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
我建议在1>}的最近更改中合并之前恢复,我怀疑按此顺序执行此操作会触发更低的机会冲突。
<强> TL; DR 强>
还原会创建“还原提交”。撤消还原时,需要在第一次还原时创建的还原提交上运行revert命令。它应该很容易找到,git倾向于对恢复进行自动注释,以便它们以“Reverted”一词开头。
develop
答案 1 :(得分:2)
找到了一个骇人听闻的解决方案。但这有效。
eddiemoya回答的内容完全有帮助。非常感谢您的解释。我遇到了类似的情况。在哪里,我可以在git diff <branch>
中看到很多内容,但是git merge表示已经是最新的内容了。
由于日志中有大量还原,因此我无法找到确切的还原提交。 (是的,不好的事情。首先不应该发生)
解决方案
git checkout branchX -- .
这会将所有更改从branchX转移到我当前的分支。 在您最喜欢的git客户端上使用,取消登台并还原所有不需要的内容。
重新提交并感到高兴:)
答案 2 :(得分:0)
我也遇到过同样的情况。我所做的是,我刚刚创建了一个新分支,cherry从不同的提交中选择了所有所需的文件,然后合并了该分支。
动作如下:
git cherry-pick -n xxxxxxx
从不同的提交中获取所需的文件git commit -m 'Your commit message'