主分支和“起源/主”分歧,怎样“分支”?
不知何故,我的主人和我的起源/主人分支已经分歧。 我其实不希望他们分歧。 我如何看待这些差异并“合并”它们?
您可以使用以下方法查看差异 :
git log HEAD..origin/master
(取+合并)(另请参阅“如何让git总是从特定分支中拉出来?” )
当你有这样的消息:
“你的分支和'起源/主'分开了,分别有1个和1个不同的提交。
,检查是否需要更新origin
。 如果origin
是最新的,那么当您在本地进行自己的提交时,某些提交已经被推送到另一个回购站。
... o ---- o ---- A ---- B origin/master (upstream work) \ C master (your work)
你基于commit A提交C,因为那是你从上游取得的最新工作。
但是,在你试图推回来之前,别人推送了commit B.
发展历史已经分化为不同的path。
然后你可以合并或重新绑定。 请参阅Pro Git:Git分支 – 重新获取详细信息。
合并
使用git merge命令:
$ git merge origin/master
这告诉Git将来自origin/master
的更改集成到您的工作中,并创build一个合并提交。
历史图现在看起来像这样:
... o ---- o ---- A ---- B origin/master (upstream work) \ \ C ---- M master (your work)
新的合并提交M有两个父母,每个代表一条发展的道路,导致存储在提交中的内容。
请注意M背后的历史现在是非线性的。
变基
使用git rebase命令:
$ git rebase origin/master
这告诉Git重放提交C(你的工作),就好像你已经基于提交B而不是A.
当CVS和Subversion用户在提交之前进行更新时,通常会在上游工作之上重新定位本地更改。
Git只是增加了commit和rebase之间的显式分隔。
历史图现在看起来像这样:
... o ---- o ---- A ---- B origin/master (upstream work) \ C' master (your work)
提交C'是由git rebase命令创build的新提交。
它有两个不同的C:
- 它有不同的历史:B而不是A.
- 它是B和C两个变化的内容帐户:它与合并示例中的M相同。
请注意,C'后面的历史仍然是线性的。
我们select(现在)在cmake.org/cmake.git
只允许线性历史。
这种方法保留了以前使用的基于CVS的工作stream程,并且可以简化转换。
试图将C'推入我们的仓库将会工作(假设您有权限,并且在您重新绑定时没有人推送)。
git pull命令提供了从原点获取和重新绑定本地工作的简便方法:
$ git pull --rebase
这将上面的获取和重build步骤组合成一个命令。
即使阅读了上述的回答,我对此也感到困惑。 我的解决办法是做
git reset --hard origin/master
然后,这只是重置我的(本地)的主(我认为是搞砸了)的副本,正确的点,由(远程)起源/主表示。
git pull --rebase origin/master
是一个单一的命令,可以帮助大部分时间。
编辑:从原点/主控制器提交提交,并将更改应用于新提取的分支历史logging。
当我尝试重新绑定一个正在跟踪远程分支的分支时,发现自己处于这种情况,我试图在master上重新绑定它。 在这种情况下,如果你尝试重新绑定,你很可能会发现你的分支分歧 ,它可以创build一个混乱,而不是混帐nubees!
假设你在分支my_remote_tracking_branch,它是从主分支
$ git status
#分支my_remote_tracking_branch
没有提交(工作目录清洁)
现在,你正在试图从主人rebase来作为:
git rebase master
立即停止并节省一些麻烦! 相反,使用合并作为:
混帐主混帐
是的,你最终会在你的分支上提交额外的提交。 但是,除非你是“不分歧”的分支机构,否则这将是一个更平滑的工作stream程。 看到这个博客更详细的解释。
另一方面,如果你的分支只是一个本地分支(即还没有推送到任何远程),你应该做一个rebase(和你的分支不会在这种情况下分歧 )。
现在,如果您正在阅读这个内容,因为您已经处于由于这种重新分配而出现的“分散”情形,那么可以使用以下方法返回到最后一次从源(即处于未分散状态)的提交:
git reset –hard origin / my_remote_tracking_branch
在我的情况下,这是我做了什么导致分歧的消息:我做了git push
但是然后做git commit --amend
以添加一些东西到提交消息。 然后我也做了另一个提交。
所以在我的情况下,只是意味着起源/主人已经过时了。 因为我知道没有其他人触摸起源/主,修复是微不足道的: git push -f
(其中-f
表示强制)
在我的情况下,我已经把变化推给了origin/master
,然后意识到我不应该这样做:-(这是由于局部变化在一个子树中的事实而变得复杂了,所以我回到了“坏“的本地变化(使用SourceTree),然后我得到了”分歧消息“。
在本地修理我的混乱之后(细节在这里不重要),我想要“及时移回”远程origin/master
分支,以便它再次与本地master
同步。 我的解决scheme是:
git push origin master -f
注意-f
(强制)开关。 这就删除了被错误origin/master
推到origin/master
的“不好的改变”,现在本地和远程分支同步。
请记住,这是一个潜在的破坏性操作,所以只有在100%确定远程主机及时“移回”的情况下才能执行。
在我的情况下,这是由于没有执行我的冲突解决。
这个问题是由运行git pull
命令造成的。 原产地的变化导致了我本地的回购,我解决了这个问题。 但是,我没有犯下这些错误。 现在的解决scheme是提交更改( git commit
parsing的文件)
如果你在解决冲突后也修改了一些文件,那么git status
命令将显示本地修改为非暂时性本地修改,合并parsing为本地修改。 这可以通过首先通过git commit
从合并提交更改来正确解决,然后像往常一样添加和提交未分离的更改(例如通过git commit -a
)。
查看差异:
git difftool --dir-diff master origin/master
这将显示两个分支之间的变化或差异。 在araxis(我最喜欢的)它显示在一个文件夹diff样式。 显示每个更改的文件。 然后,我可以点击一个文件来查看文件中更改的详细信息。
我知道这里有很多答案,但是我认为git reset --soft HEAD~1
值得注意,因为它可以让你在解决分散状态的同时保持最后一个本地 (未被压入)提交的改变。 我认为这是一个比rebase
更全面的解决scheme,因为可以检查本地提交,甚至移动到另一个分支。
关键是使用 – --soft
,而不是苛刻 – --hard
。 如果有超过1个提交, HEAD~x
的变体应该工作。 所以这里是解决我的情况的所有步骤(我有1个本地提交和远程8个提交):
1) git reset --soft HEAD~1
撤销本地提交。 对于接下来的步骤,我使用了SourceTree中的接口,但是我认为下面的命令也应该可以工作:
2) git stash
从1)存储更改。 现在所有的变化都是安全的,不再有分歧了。
3) git pull
来获得远程更改。
4) git stash pop
或git stash apply
于应用最后git stash apply
更改,如果需要的话,接着是新的提交。 这一步是可选的,以及2) ,当想要垃圾在本地提交的变化。 另外,当想要提交到另一个分支时,这个步骤应该在切换到所需的分支之后完成。