我的master
和origin/master
分支不知何故发生了分歧。
实际上,我不希望它们分歧。
我该如何查看这些差异并进行合并?
我的master
和origin/master
分支不知何故发生了分歧。
实际上,我不希望它们分歧。
我该如何查看这些差异并进行合并?
您可以通过以下方式查看差异:
git log HEAD..origin/main
# old repositories
git log HEAD..origin/master
在拉取它之前(获取+合并)(另请参见{{link2:“如何让git始终从特定分支拉取?”}})
注意:自Git 2.28(2020年第三季度)以来,默认分支是可配置的,现在(2021+)设置为main
,不再是master
。
答案的其余部分反映了更近期的惯例。
当你遇到以下类似信息:
"Your branch and 'origin/main' have diverged, # and have 1 and 1 different commit(s) each, respectively."
检查是否需要更新 origin
。
如果origin
已经是最新的,那么说明你本地提交代码时,有其他仓库向origin
提交了一些代码。
... o ---- o ---- A ---- B origin/main (upstream work)
\
C main(your work)
你基于提交的A
,进行了C
的提交,因为那是你在那个时候从upstream
中获取到的最新工作。
然而,在你尝试推回到origin
之前,有人已经推送了提交B
。
开发历史已经分为不同的路径。
然后你可以合并或变基。请参见Pro Git:Git分支-Rebasing以获取详细信息。
使用git merge
命令:
$ git merge origin/main
# old repositories
$ git merge origin/master
这告诉 Git 将来自 origin/main
的更改集成到您的工作中并创建合并提交。
现在历史记录的图表如下所示:
... o ---- o ---- A ---- B origin/main (upstream work)
\ \
C ---- M main (your work)
M
有两个父提交,分别代表通向该提交存储的内容的两条开发路径。M
背后的历史现在是非线性的。
git rebase
命令:$ git rebase origin/main
# old repositories
$ git rebase origin/master
这告诉Git将提交C
(您的工作)的重放,就好像您是基于提交B
而不是A
进行的。
当CVS和Subversion用户在提交之前更新时,经常会将他们的本地更改重新命名为upstream
工作的顶部。
Git只是在提交和重新命名步骤之间添加了明确的分离。
历史记录的图现在如下所示:
... o ---- o ---- A ---- B origin/main (upstream work)
\
C' main (your work)
C'
提交是由git rebase
命令创建的新提交。
它与C
有两个不同之处:
B
而不是A
。B
和C
中的更改;它与合并示例中的M
相同。请注意,C'
背后的历史仍然是线性的。
我们目前选择允许cmake.org/cmake.git
中仅有线性历史记录。
这种方法保留了以前使用的基于CVS的工作流,并可能简化过渡。
尝试将C'
推送到我们的存储库将起作用(假设您具有权限且在重定位时没有人推送)。
git pull
命令提供了一种快捷方式,可以从origin
获取并重新设置本地工作:
$ git pull --rebase
这将上述的fetch
和rebase
步骤合并为一个命令。
git reset --hard HEAD
只会删除任何本地已经暂存但未提交的修改,对于本地提交和远程提交之间的差异没有任何作用。只有合并或变基(rebase)才能将两组提交(本地和远程)合并在一起。 - VonCmaster
指向 B
。 - CygnusX1git reset --hard origin/master
命令:https://dev59.com/lHE95IYBdhLWcg3wHqIV#8476004 - VonC我遇到了这个问题,即使阅读了上面的回答,仍然感到困惑。我的解决方案是执行
git reset --hard origin/main
那么这只是将我的(本地)主要副本重置(我认为它已经损坏)到正确的点,如(远程)origin/main所表示的。
警告:您将失去尚未推送到
origin/main
的所有更改。
git reflog
命令找到提交记录,或者在 gitk --all
中查看它们。但是,硬重置和变基当然是不同的事情。 - sebkraemergit pull --rebase origin/main
是一个单一的指令,大多数情况下都可以帮到你。
编辑:从 origin/main 拉取提交,并将您的更改应用于新拉取的分支历史记录。
我相信这应该对我有所帮助:
git reset --hard origin/main
但它没有。不知何故,我收到了相同的消息,只要我从远程分支拉取更改,就会发生冲突。由于我确定根本不需要现有的本地分支,我只需要来自远程的main
分支的副本,因此我想出了这个解决方案:
git checkout -b placeholder-branch
。注意:稍后可以删除此分支。git branch -D main
,我这样做是因为我确定我的本地分支已损坏,我不需要它。我需要从远程实例获取新的副本。git checkout --track origin/main
,然后你就完成了;现在可以使用git branch -D
删除placeholder-branch
当我尝试将一个远程分支上的跟踪分支进行变基并且将其变基到主分支上时,我发现自己陷入了这种情况。在这种情况下,如果你尝试变基操作,你很可能会发现你的分支已经分叉了,并且可能会导致一些对于Git新手来说很麻烦的问题!
假设你现在在my_remote_tracking_branch分支上,该分支是从主分支上派生出来的。
$ git status
# 在分支 my_remote_tracking_branch 上
无文件要提交,干净的工作区
现在你想从主分支上进行变基操作,命令如下:
git rebase main
立即停止并使用合并操作以避免麻烦:
git merge main
是的,你的分支最终会有额外的提交。但是,除非你准备好“取消分歧”的分支,否则这将比变基更顺畅。请参见this blog以获取更详细的解释。
另一方面,如果你的分支只是一个本地分支(即尚未推送到任何远程),你应该绝对进行变基(在这种情况下,你的分支不会分歧)。
现在,如果你正在阅读这篇文章,因为你已经由于这样的变基处于“分歧”状态,你可以使用以下命令回到来自原始的最后一个提交(即处于未分歧状态):
git reset --hard origin/my_remote_tracking_branch
merge
。否则,使用 rebase
。如果你重新定义已经发布(并被使用)的分支,你必须协调一场阴谋,以重写每个使用了你的分支的开发者的历史记录。 - Mikko Rantalainengit rebase master
命令之前我没有读到这条消息... - Vitaly Isaevgit reset --hard origin/my_remote_tracking_branch
是真正起作用的。 - sgohlgit push -f
命令覆盖之前提交并推送到远程代码库的更改。同时我确信没有其他人操作过这个代码库。 - zacharydlorigin/main
,然后意识到我不应该这样做 :-( 由于本地更改位于子树中,这使得事情变得复杂。因此,我回到了“坏”本地更改之前的最后一个好提交(使用SourceTree),然后我收到了“分歧消息”。origin/main
分支与本地的main
再次同步。在我的情况下,解决方案是:git push origin main -f
-f
(强制)开关。这将删除错误地推送到origin/main
的“坏更改”,现在本地和远程分支已经同步。master
分支名称更改为 main
。Git 存储库中的“主”分支与奴隶主毫无关系。或者你拒绝下棋,只因为黑白两色的棋子在黑白相间的棋盘上移动吗?如果是这样,那么你会为棋盘提议什么颜色呢? :-) - András Aszódigit reset --soft HEAD~1
值得关注,因为它可以在解决分歧状态时保留最后一个本地(未推送)提交中的更改。我认为这比使用rebase
的pull更具通用性,因为可以审查本地提交甚至将其移动到另一个分支。--soft
而不是--hard
。如果有多个提交,则应该使用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
命令会自动进行存储。https://dev59.com/J10a5IYBdhLWcg3wipNA#30209750 - VonC我已经通过移动到最后一次提交到 origin/main 的 commit_sha 来解决了这个问题。
git reset --hard commit_sha
警告:在“commit_sha”提交之后,您将失去所有提交的内容。查看差异:
git difftool --dir-diff main origin/main
这将显示两个分支之间的更改或差异。在Araxis(我最喜欢的)中,它以文件夹差异样式显示。显示每个更改的文件。然后我可以单击文件以查看文件中更改的详细信息。