master 分支和 'origin/master' 已经发散了,如何' undiverge' 分支'?
Posted
技术标签:
【中文标题】master 分支和 \'origin/master\' 已经发散了,如何\' undiverge\' 分支\'?【英文标题】:master branch and 'origin/master' have diverged, how to 'undiverge' branches'?master 分支和 'origin/master' 已经发散了,如何' undiverge' 分支'? 【发布时间】:2011-01-27 23:26:00 【问题描述】:不知何故,我的 master
和我的 origin/master
分支出现了分歧。
我其实不希望他们分道扬镳。
如何查看这些差异并合并它们?
【问题讨论】:
发散是什么意思? 在推送它之后,你会重新调整你的主人吗? 我收到一条消息,说“您的分支和 'origin/master' 已经分歧,# 并且分别有 1 和 1 个不同的提交。” 我已更新我的答案以反映“分歧”警告信息。 这个博客的解释对我的帮助比下面的任何答案都大:sebgoo.blogspot.com/2012/02/… 在我自己的本地分支“分歧”后撤消对它的所有更改(需要推拉,当我没有做任何更改时,我记得): git reset --hard origin/my-branch 。仅当您知道自己没有进行任何要保留的本地更改时才执行此操作。 【参考方案1】:您可以review the differences 使用:
git log HEAD..origin/master
pulling it 之前(获取 + 合并)(另见 "How do you get git to always pull from a specific branch?")
当您收到如下消息时:
“您的分支和 'origin/master' 已经分道扬镳,分别有 1 个和 1 个不同的提交。”
,检查你是否need to update origin
。如果 origin
是最新的,那么当您在本地进行自己的提交时,一些提交已从另一个仓库推送到 origin
。
... o ---- o ---- A ---- B origin/master (upstream work)
\
C master (your work)
您将提交 C 基于提交 A,因为那是您当时从上游获取的最新工作。
但是,在您尝试推回原点之前,其他人推送了提交 B。 发展历史已经分道扬镳。
然后您可以合并或变基。详情请见Pro Git: Git Branching - Rebasing。
合并
使用 git 合并命令:
$ git merge origin/master
这告诉 Git 将来自 origin/master
的更改集成到您的工作中并创建一个合并提交。
历史图表现在看起来像这样:
... 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 只是在提交和变基步骤之间添加了明确的分隔。
历史图表现在如下所示:
... o ---- o ---- A ---- B origin/master (upstream work)
\
C' master (your work)
提交 C' 是由 git rebase 命令创建的新提交。 它在两个方面与 C 不同:
-
它有不同的历史:B 而不是 A。
它的内容解释了 B 和 C 的变化;它与合并示例中的 M 相同。
请注意,C' 背后的历史仍然是线性的。
我们选择(目前)仅允许 cmake.org/cmake.git
中的线性历史记录。
这种方法保留了以前使用的基于 CVS 的工作流程,并且可以简化过渡。
将 C' 推送到我们的存储库的尝试将起作用(假设您有权限并且在您变基时没有人推送)。
git pull 命令提供了一种从源获取并在其上重新定位本地工作的简写方式:
$ git pull --rebase
这将上述 fetch 和 rebase 步骤组合成一个命令。
【讨论】:
我在查找同样的问题时发现了这个问题,你能解释一下为什么 'git reset --hard HEAD' 没有解决问题吗? @Neth:因为它不是关于分阶段的修改(即修改存在于索引中但尚未提交),而是关于 本地提交(与偏僻的)。git reset --hard HEAD
只会删除任何本地索引的未提交修改,并且不会协调本地和远程 commits 之间的差异。只有合并或变基才能将两组提交(本地提交和远程提交)放在一起。
哇,感谢您的精彩回复。我们不小心做了一个没有“--rebase”的“git pull”,而“git rebase origin/master”就是解决方法!
怎么样 - 我只想忽略/转储我的本地更改并与远程所在的本地分支一起使用?换句话说,我希望 master
在您的示例中指向 B
。
@CygnusX1 这将是一个git reset --hard origin/master
,如下面的答案所述:***.com/a/8476004/6309【参考方案2】:
即使在阅读了上述回复之后,我也有这个问题并且对导致它的原因感到困惑。我的解决方案是做
git reset --hard origin/master
然后这只是将我的(本地)master 副本(我认为它搞砸了)重置到正确的点,由(远程)origin/master 表示。
警告:您将丢失所有尚未推送到
origin/master
的更改。
【讨论】:
是的,感觉有点像傻瓜选项,但如果没有真正的危险并且你来这里是为了快速修复 - 这很有效(无论如何对我来说) 这需要在master分支之前(“git checkout master”)。 嗨skiphoppy,感谢您的提示。我同意 PandaWood 的观点(无意冒犯),这似乎有点像一个傻瓜选项。但话说回来,我对 Git 更高级的方面并没有那么丰富。origin/master
位是我所需要的——不知何故,我刚刚在本地搞砸了,真的很想恢复原点,但是没有明确的远程名称的重置是行不通的。谢谢!
@PedroLoureiro 提交确实丢失了,您仍然可以使用git reflog
找到提交或在gitk --all
中查看它们。但是,硬重置当然不是变基。【参考方案3】:
git pull --rebase origin/master
是一个可以在大多数情况下为您提供帮助的命令。
编辑:从源站/主站拉取提交并将您的更改应用于新拉取的分支历史记录。
【讨论】:
请说明该命令的作用,否则人们可能会运行它并最终搞砸 如果没有问题,你应该最终得到你的 master 包含所有更改 origin/master 加上你所有的本地提交将在它之上重放。对我来说似乎很好。 除非存在真正的差异并且它会让您处于中止的变基中。 这会产生一个错误:错误:无法合并更改。补丁在 0024 请求和响应模型中失败【参考方案4】:在我的例子中,我做了什么来导致 diverged 消息:我做了git push
,但随后做了git commit --amend
向提交消息添加了一些内容。然后我也做了另一个提交。
所以在我的例子中,这仅仅意味着 origin/master 已经过时了。因为我知道没有其他人在触摸 origin/master,所以修复很简单:git push -f
(其中-f
表示强制)
【讨论】:
+1 forgit push -f
覆盖之前提交并推送到源的更改。我也确信没有其他人接触过存储库。
非常危险的命令。请写下有关命令风险因素的简短信息。
@Trickster:我已经描述了风险:“因为我知道没有其他人接触过起源/主人”。我相信,在这种情况下,这不是一个冒险的命令。
如果有人在 master 上提交,然后一个人运行命令 git push -f 那么它是高风险命令
感谢您的回答。我的 CI 有一个 git commit --amend 并且会因此而失败。修改本地提交是有意义的,在 CI 中,如果您在提交之前进行修改,那么您在技术上修改了已经推送的远程提交,因此它将其视为一种转移。【参考方案5】:
当我尝试rebase 一个跟踪远程分支的分支时,我发现自己处于这种情况,并且我试图将它重新设置在 master 上。在这种情况下,如果您尝试变基,您很可能会发现您的分支发散,它可能会造成不适合 git nubees 的混乱!
假设您在分支 my_remote_tracking_branch,该分支是从 master 分支的
$ git status
# 在分支 my_remote_tracking_branch
没有提交(工作目录干净)
现在你正试图从 master 变基为:
git rebase master
立即停止,为自己省点麻烦!相反,使用合并:
git 合并大师
是的,您最终会在您的分支上进行额外的提交。但除非你准备好“不分叉”的分支,否则这将是一个比变基更顺畅的工作流程。有关更详细的说明,请参阅 this blog。
另一方面,如果您的分支只是一个本地 分支(即尚未推送到任何远程),您绝对应该做一个变基(并且您的分支不会发散 em> 在这种情况下)。
现在,如果您正在阅读本文是因为您已经 由于此类变基而处于“分歧”场景中,您可以从源返回到最后一次提交(即处于未分歧状态)通过使用:
git reset --hard origin/my_remote_tracking_branch
【讨论】:
一个经验法则是使用rebase
,如果您正在变基的分支尚未发布(并且被其他人使用)。否则,请使用merge
。如果你对已经发布(和使用)的分支进行变基,你必须协调一个阴谋来重写每个使用过你的分支的开发人员的历史。
很遗憾,在git rebase master
...
如果我在分支 'foobar' 上执行 git rebase master ,那么技术上 foobar 与 origin/foobar 不同,直到我执行 git push -f ,对吗?
jarrodspillers.com/git/2009/08/19/…
git reset --hard origin/my_remote_tracking_branch
是真正有效的方法【参考方案6】:
在我的情况下,这是由于没有提交我的冲突解决方案造成的。
问题是由运行git pull
命令引起的。原点的更改导致与我的本地存储库发生冲突,我解决了。但是,我没有提交它们。此时的解决方案是提交更改(git commit
解析的文件)
如果您在解决冲突后还修改了一些文件,git status
命令会将本地修改显示为未暂存的本地修改,并将合并解析显示为暂存的本地修改。这可以通过首先由git commit
提交合并中的更改来正确解决,然后像往常一样添加和提交未暂存的更改(例如,由git commit -a
)。
【讨论】:
【参考方案7】:在我的情况下,我已经将更改推送到 origin/master
,然后意识到我不应该这样做 :-( 由于本地更改位于子树中,这很复杂。所以我回到了最后一个好的提交在“糟糕”的本地更改(使用 SourceTree)之前,然后我得到了“分歧消息”。
在本地修复我的混乱之后(这里的细节并不重要),我想“及时回到”远程origin/master
分支,以便它再次与本地master
同步。我的解决方案是:
git push origin master -f
注意-f
(强制)开关。这删除了错误地推送到origin/master
的“错误更改”,现在本地和远程分支是同步的。
请记住,这是一个具有潜在破坏性的操作,因此只有在您 100% 确定及时“移回”远程主机是可行的情况下才执行此操作。
【讨论】:
总是有用,但肯定不能回答问题。 @ThibaultD。即使没有,这正是我想要的。 我收到了You are not allowed to force push code to a protected branch on this project.
。我正试图推到我的叉子上。
我不得不取消对 gitlab repo ***.com/questions/32246503/…的保护
是的,我在 master 上有一些不应该存在的提交,如果您不关心删除它们,上述或“git push --force”工作(重写历史和删除)分歧的远程提交)。如果您想保留提交但不在 master 上,则可以将它们移动到另一个分支。【参考方案8】:
查看差异:
git difftool --dir-diff master origin/master
这将显示两个分支之间的更改或差异。在 araxis(我最喜欢的)中,它以文件夹差异样式显示。显示每个更改的文件。然后我可以单击一个文件来查看文件中更改的详细信息。
【讨论】:
git-dir 的有趣使用:+1【参考方案9】:我知道这里有很多答案,但我认为git reset --soft HEAD~1
值得关注,因为它可以让您在解决分歧状态的同时保留最后一次本地(未推送)提交中的更改。我认为这是一个比使用rebase
拉取更通用的解决方案,因为可以审查本地提交,甚至可以将其移动到另一个分支。
关键是使用--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
应用最后隐藏的更改,然后根据需要进行新的提交。当想要丢弃本地提交中的更改时,此步骤与 2) 一起是可选的。此外,当想要提交到另一个分支时,应在切换到所需的分支后完成此步骤。
【讨论】:
实际上,这些天来,pull --rebase
无论如何都会自动隐藏。 ***.com/a/30209750/6309【参考方案10】:
当我尝试编辑已推送提交的最后一条提交消息时,我收到了相同的消息,使用:git commit --amend -m "New message"
当我使用 git push --force-with-lease repo_name branch_name
推送更改时
没有问题。
【讨论】:
【参考方案11】:当我基于分支A创建分支时遇到了这个问题
git checkout -b a
然后我将分支a的上游设置为原始分支B
git branch -u origin/B
然后我得到了上面的错误信息。
为我解决这个问题的一种方法是,
删除分支a 创建一个新的分支 b bygit checkout -b b origin/B
【讨论】:
【参考方案12】:将 123 替换为您的分支偏离原点的提交数。
git reset HEAD~123 && git reset && git checkout . && git clean -fd && git pull
【讨论】:
【参考方案13】:git reset --soft origin/my_remote_tracking_branch
This way you will not loose your local changes
【讨论】:
【参考方案14】:我更喜欢更方便、更安全的方式。
# copying your commit(s) to separate branch
git checkout <last_sync_commit>
git checkout -b temp
git cherry-pick <last_local_commit>
git checkout master
git reset --soft HEAD~1 # or how many commits you have only on local machine
git stash # safer, can be avoided using hard resetting on the above line
git pull
git cherry-pick <last_local_commit>
# deleting temporary branch
git branch -D temp
【讨论】:
有趣。赞成。不要忘记使用git switch
而不是git checkout
:***.com/a/57066202/6309。在您的情况下,例如:git switch -c temp <last_sync_commit>
【参考方案15】:
我已通过移动到最后提交给 origin/master 的 commit_sha 来修复它。
git reset --hard commit_sha
警告:在“commit_sha”提交之后,您将丢失所有提交的内容。
【讨论】:
【参考方案16】:我相信这应该对我有所帮助:
git reset --hard origin/master
但事实并非如此,不知何故,我收到了相同的消息,当我从远程分支中提取更改时,冲突正在发生。因为我确信我根本不需要我现有的本地分支,我只需要远程的 master
分支的精确副本,因此我想出了这个解决方案:
git checkout -b placeholder-branch
。注意:这个分支以后可以删除。
git branch -D master
,我这样做是因为我确信我的本地分支被搞砸了,我实际上不需要这个,我只需要来自远程实例的新副本。
git checkout --track origin/master
大功告成,现在您可以使用 git branch -D
删除 placeholder-branch
【讨论】:
以上是关于master 分支和 'origin/master' 已经发散了,如何' undiverge' 分支'?的主要内容,如果未能解决你的问题,请参考以下文章
text git error - master分支和'origin / master'分歧了
git push origin master 遇到的分支问题
如果不再使用本地分支,我应该使用 `git pull --rebase origin master` 还是 `git rebase origin/master`?