不知怎的,我的主人和我的起源/主人的分支出现了分歧。事实上,我不想让他们分道扬镳。如何查看这些差异并"合并"它们?
- 分流是什么意思?你推了它之后,会重新调整你的主人的姿势吗?
- 我收到一条消息,说"您的分支和‘源站/主服务器’已经分开,并且分别有1个和1个不同的提交。"
- 我更新了我的答案,以反映"分歧"的警告信息。
- 对另一个问题的公认答案也可能有助于解决某些可能会起作用的情况(例如,您试图移动您的主控形状,但它已经被推过):stackoverflow.com/questions/2862590/…
- 这个博客上的解释对我的帮助远远超过以下任何答案:sebgoo.blogspot.com/2012/02/…
- 顺便说一下,你要找的词是"聚合"。
- 要在分支"分叉"后撤消对本地分支的所有更改(当我没有进行任何更改时,需要推和拉):git reset--硬原点/我的分支。只有当你知道你没有做任何你想保留的本地更改时才这样做。
您可以通过以下方式查看差异:
1
| git log HEAD..origin/master |
在拉它之前(fetch+merge)(另请参见"如何让git总是从特定的分支拉?")
当您收到如下信息时:
"Your branch and 'origin/master' have diverged, # and have 1 and 1 different commit(s) each, respectively."
号
,检查是否需要更新origin。如果origin是最新的,那么当您在本地作出自己的承诺时,一些承诺已从另一个回购协议推送到origin。
1 2 3
| ... o ---- o ---- A ---- B origin/master (upstream work)
\
C master (your work) |
号
您将commit c基于commit a,因为这是您当时从上游提取的最新工作。
但是,在您试图将其推回到源站之前,其他人推送了commit b。发展史已分道扬镳。
然后可以合并或重新设置基。有关详细信息,请参见pro-git:git分支-重新平衡。
合并
使用git merge命令:
1
| $ git merge origin/master |
这告诉Git将来自origin/master的更改集成到您的工作中,并创建合并提交。历史图表如下:
1 2 3
| ... o ---- o ---- A ---- B origin/master (upstream work)
\ \
C ---- M master (your work) |
。
新的合并commit m有两个父级,每个父级表示一个开发路径,该开发路径导致存储在该commit中的内容。
注意,m后面的历史现在是非线性的。
重碱
使用git-rebase命令:
1
| $ git rebase origin/master |
这告诉Git重放commit c(您的工作),就好像您是基于commit b而不是a。cvs和subversion用户在提交前更新时,通常会在上游工作的基础上重新调整本地更改。Git只是在commit和rebase步骤之间添加了显式的分离。
历史图表如下:
1 2 3
| ... o ---- o ---- A ---- B origin/master (upstream work)
\
C' master (your work) |
。
commit c'是由git-rebase命令创建的新commit。它与C有两种不同之处:
它有着不同的历史:B而不是A。
它的内容解释了B和C中的变化;它与合并示例中的m相同。
注意,c'后面的历史仍然是线性的。我们选择(目前)只允许cmake.org/cmake.git中的线性历史。这种方法保留了以前使用的基于CVS的工作流,并可能简化转换。尝试将C'推送到我们的存储库中是可行的(假设您有权限,并且在重新平衡时没有人推)。
git pull命令提供了一种从源站获取并重新设置本地工作的快捷方式:
。
这将上述获取和重新平衡步骤组合成一个命令。
- 我在查找相同问题时发现了这个问题,你能解释一下为什么"Git重置——硬头"没有解决问题吗?
- @neth:因为它不是关于阶段性修改(即索引中存在但尚未提交的修改),而是关于本地提交(与远程上存在的提交不同)。git reset --hard HEAD将只删除任何本地索引的未提交修改,并且不会对协调本地和远程提交之间的差异做任何操作。只有一个合并或一个REBASE将两组提交(本地提交和远程提交)放在一起。
- 哇,谢谢你的回应。我们意外地做了一个"git-pull"没有"-rebase",而"git-rebase-origin/master"只是修复方法!
- +1个用于git pull --rebase。
- 如何-我只想忽略/转储我的本地更改,并与远程所在的本地分支在一起?换句话说,我希望master在您的示例中指向B。
- @cygnusx1就是下面答案中提到的git reset --hard origin/master:stackoverflow.com/a/8476004/6309
- 是的,我现在看到了。不知怎么的,我昨天没看到它:(
- 很好的答案,我只想补充一点,如果你陷入了合并的中间,你可以"git合并--中止",然后选择合并或重新平衡选项。
- +1个用于git pull --rebase。
我有过这样的经历,即使在阅读了以上的回答之后,我仍然对造成这种情况的原因感到困惑。我的解决办法是
1
| git reset --hard origin/master |
然后,这只会将我的(本地)主文件副本(我认为是错误的)重置到正确的点,如(远程)源文件/主文件所示。
WARNING: You will lose all changes not yet pushed to origin/master.
号
- 是的,这感觉有点像傻瓜的选择,但是如果没有真正的危险,你来这里是为了快速修复-这是可行的(无论如何对我来说)
- 谢谢,我忘记添加原点/主对象了
- 这要求之前在主分支上("git checkout master")。
- 有一次,当我从源代码处获得最新的信息时,我遇到了这种情况,然后其他人强行推到源代码处,这导致先前的源代码提交被还原。所以我的本地分支机构有了恢复的提交,当我试图从源代码中提取最新的内容时,它说我必须合并。在这种情况下,重置——硬原点/(分支)是有意义的,因为问题已经在原点修复。
- 嗨,斯基普皮,谢谢你的小费。我同意潘达伍德的观点(没有冒犯的意思),认为这似乎是一个有点愚蠢的选择。但这么说来,我对Git更高级的方面没有那么有经验。
- 您可能应该警告用户,这将使他们丢失尚未推送到源站的所有更改。
- 我需要的是origin/master位——不知怎么的,我只是在本地出了点问题,真的想恢复到原点,但是没有明确的远程名称的重置是不起作用的。谢谢!
- @Pedroloureiro提交确实丢失了,您仍然可以在git reflog中找到提交,或者在gitk --all中看到它们。但是,当然,硬重置是另一回事,而不是一个平衡。
- 我总是忘了打壁球,后来和吉特·里巴斯一起打,结果搞砸了。你的解决方案帮了我很大的忙。
- 我喜欢这个捷径
- 很好的解决方案。谢谢。
1
| git pull --rebase origin/master |
。
是一个可以在大部分时间帮助您的命令。
编辑:从源站/主服务器提取提交,并将您的更改应用于新提取的分支历史记录。
- 请提一下这个命令的作用,否则人们可能会运行它,结果搞砸了。
- 如果没有问题,您应该以包含所有更改的主服务器结束,并且所有本地提交都将在主服务器上重播。我觉得不错。
- 除非存在真正的差异,它会让您陷入一个中止的重新平衡。
- 这会产生一个错误:错误:未能合并更改。在0024请求和响应模型时修补程序失败
当我尝试重新平衡跟踪远程分支的分支时,我发现自己处于这种情况,我尝试在master上重新平衡它。在这种情况下,如果你尝试重新平衡,你很可能会发现你的分支分叉,它会造成一个混乱,而不是吉特努比!
假设你在我的远程跟踪分支上,它是从master分支的。
BLCK1
现在,您正试图从master重新设置为:
墨水
现在停下来,省去一些麻烦!相反,使用go as:
黑色1-2
是的,您的分支最后会得到额外的提交。但是,除非您准备使用"不分散"的分支,否则这将是一个比重新平衡更平滑的工作流。有关更详细的解释,请参阅本博客。
另一方面,如果您的分支只是一个本地分支(也就是说,还没有被推到任何远程分支),那么您一定要重新平衡(在这种情况下,您的分支不会出现分歧)。
现在,如果您阅读此内容是因为您已经处于由于这种重新平衡而导致的"分散"场景中,那么您可以使用以下命令从源站(即处于未分散状态)返回到最后一次提交:
黑色1-3
- 经验法则是,如果您要重新平衡的分支尚未发布(并由其他人使用),则使用rebase。否则,使用merge。如果您重新设置已经发布(并使用)的分支的基,那么您必须协调一个阴谋,在使用分支的每个开发人员之间重写历史。
- 不幸的是,我在做git rebase master之前没有读到这条消息…
- 如果我在分支"foobar"上执行git rebase master,那么从技术上讲foobar与源站/foobar分离,直到执行git push-f,对吗?
- jarrodspillers.com/git/2009/08/19/…
- git reset --hard origin/my_remote_tracking_branch才是真正有效的
在我的例子中,我是这样做的:我做了git push,然后做了git commit --amend,在commit消息中添加了一些内容。然后我又做了一个承诺。
所以在我的例子中,这意味着原点/主节点已经过时了。因为我知道没有其他人接触到原点/主点,所以修复是微不足道的:git push -f(其中-f表示力)
- +1对于git push -f,覆盖先前提交并推送到原点的更改。我也确信没有其他人接触过存储库。
- 非常危险的命令。请就命令的风险因素写一个简短的信息。
- @骗子:我已经描述过这种风险:"因为我知道没有其他人接触过源头/主人"。我相信,在这种情况下,这不是一个冒险的命令。
- 如果有人在master上提交,然后有一个人运行命令git push-f,那么这就是高风险命令
在我的例子中,我已经将更改推到了EDOCX1,然后意识到我不应该这样做:(由于局部更改是在子树中的,所以这很复杂。所以我回到了"坏"本地更改(使用sourcetree)之前的最后一次好提交,然后得到了"分歧消息"。
在本地修复了我的混乱之后(细节在这里并不重要),我想"及时地返回"远程EDOCX1-5分支,以便它再次与本地EDOCX1同步。我的解决方案是:
ZZU1
注意EDOCX1-8(强制)开关。这删除了错误推送到EDOCX1的"错误更改",现在本地和远程分支同步。
请记住,这是一个潜在的破坏性操作,因此只有在您100%确定"向后移动"远程主机在时间上是正常的情况下才执行它。
- 总是有用,但肯定回答不了问题。
- @蒂博有限公司即使没有,这正是我想要的。
我知道这里有很多答案,但我认为git reset --soft HEAD~1值得注意,因为它让您在解决分歧状态的同时保持最后一个本地(而不是推送)承诺的更改。我认为这是一个比使用rebase更通用的解决方案,因为本地提交可以被审查,甚至可以移动到另一个分支。
关键是使用--soft,而不是使用苛刻的--hard。如果提交次数超过1次,则可以对HEAD~x进行更改。下面是解决我的情况的所有步骤(我在远程有1个本地提交和8个提交):
1)git reset --soft HEAD~1撤销本地提交。在接下来的步骤中,我使用了sourcetree中的接口,但我认为以下命令也应该有效:
2)git stash到stash的变化从1)。现在所有的变化都是安全的,不再有分歧。
3)git pull获取远程更改。
4)git stash pop或git stash apply应用最后一次隐藏的更改,如果需要,随后执行新的承诺。当想要在本地提交中废弃更改时,此步骤是可选的,还有2)。此外,当想要提交到另一个分支时,应该在切换到所需分支之后完成此步骤。
- 事实上,最近,江户一号〔2〕无论如何都会自动藏匿起来。stackoverflow.com/a/30209750/6309
要查看差异:
EDOCX1-10型
这将显示两个分支之间的更改或差异。在Araxis(我的最爱)中,它以文件夹diff样式显示它。显示每个更改的文件。然后我可以单击一个文件以查看该文件中更改的详细信息。
在我的案例中,这是由于没有提交我的冲突解决方案造成的。
问题是由运行EDOCX1命令引起的。源代码的更改导致了与本地回购协议的冲突,我解决了这一问题。但是,我没有承诺。此时的解决方案是提交更改(EDOCX1)
如果在解决冲突后修改了一些文件,那么EDOCX1命令将本地修改显示为未过时的本地修改,并将解决方案合并为阶段性本地修改。这可以通过首先由EDOCX1提交来自合并的更改,然后像往常一样添加和提交未老化的更改(例如由EDOCX1)来正确解决。
当我试图编辑最后一条提交消息时,我收到了相同的消息:已经推送提交,使用:git commit --amend -m"New message"。当我使用git push --force-with-lease repo_name branch_name推动更改时没有问题。