不知何故,我的 master
和我的 origin/master
分支出现了分歧。
我实际上不希望它们分歧。
如何查看这些差异并将它们合并?
您可以通过以下方式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)
您基于提交 A 提交 C,因为那是您当时从上游获取的最新工作。
但是,在您尝试推回原点之前,其他人推了提交 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 origin/master
然后,这只是将我的(本地)master 副本(我假设它搞砸了)重置到正确的点,如(远程)origin/master 所示。
警告:您将丢失所有尚未推送到 origin/master 的更改。
origin/master
位是我所需要的——不知何故,我只是在本地搞砸了,真的很想恢复到原始状态,但是在没有显式远程名称的情况下重置是行不通的。谢谢!
git reflog
找到提交或在 gitk --all
中查看它们。但是,当然,硬重置与变基不同。
git pull --rebase origin/master
是一个可以在大多数情况下为您提供帮助的命令。
编辑:从 origin/master 拉取提交并将您的更改应用于新拉取的分支历史记录。
当我尝试重新定位一个跟踪远程分支的分支时,我发现自己处于这种情况,并且我试图在 master 上重新定位它。在这种情况下,如果您尝试 rebase,您很可能会发现您的分支出现分歧,并且可能会造成不适合 git nubees 的混乱!
假设您在分支 my_remote_tracking_branch 上,该分支是从 master 分支的
git status # 在分支上 my_remote_tracking_branch 没有提交(工作目录干净)
现在你正试图从 master 变基为:
git rebase 大师
立即停止并为自己省点麻烦!相反,使用合并:
git 合并大师
是的,你最终会在你的分支上得到额外的提交。但是除非你准备好“不发散”的分支,否则这将是一个比 rebase 更顺畅的工作流程。有关更详细的说明,请参阅 this blog。
另一方面,如果您的分支只是一个本地分支(即尚未推送到任何远程),您绝对应该做一个 rebase(在这种情况下您的分支不会发散)。
现在,如果您正在阅读本文是因为您已经由于这种变基而处于“分歧”场景中,您可以使用以下命令从原始提交(即处于未分歧状态)返回到最后一次提交:
git reset --hard origin/my_remote_tracking_branch
rebase
。否则,使用 merge
。如果你对已经发布(和使用)的分支进行变基,你必须协调一个阴谋来重写每个使用你的分支的开发人员的历史。
git rebase master
之前我没有阅读此消息...
git reset --hard origin/my_remote_tracking_branch
是真正有效的
就我而言,这是我为导致 diverged 消息所做的事情:我做了 git push
,但随后做了 git commit --amend
以在提交消息中添加一些内容。然后我也做了另一个提交。
所以在我的情况下,这仅仅意味着 origin/master 已经过时了。因为我知道没有其他人在触摸 origin/master,所以修复很简单:git push -f
(其中 -f
表示强制)
git push -f
+1 以覆盖先前提交并推送到源的更改。我也确信没有其他人接触过存储库。
我相信这应该对我有所帮助:
git reset --hard origin/master
但它没有,不知何故我得到了同样的信息&一旦我从远程分支中提取更改,冲突就发生了。因为我确信我根本不需要我现有的本地分支机构 &我只需要远程的 master
分支的精确副本,因此我想出了这个解决方案:
结帐到新分支,例如 git checkout -b placeholder-branch。注意:此分支可以稍后删除。
git branch -D master,我这样做是因为我确信我的本地分支被搞砸了,我实际上不需要这个,我只需要来自远程实例的新副本。
git checkout --track origin/master & 你已经完成了,现在你可以使用 git branch -D 删除占位符分支
就我而言,我已将更改推送到 origin/master
,然后意识到我不应该这样做:-( 由于本地更改位于子树中,这很复杂。所以我回到了“糟糕的”本地更改(使用SourceTree),然后我得到了“分歧消息”。
在本地修复了我的混乱之后(这里的细节并不重要),我想“及时回溯”远程 origin/master
分支,以便它再次与本地 master
同步。我的解决方案是:
git push origin master -f
请注意 -f
(强制)开关。这删除了错误推送到 origin/master
的“错误更改”,现在本地和远程分支已同步。
请记住,这是一个潜在的破坏性操作,因此只有在您 100% 确定及时“移回”远程主机是可以的时才执行它。
You are not allowed to force push code to a protected branch on this project.
。我正试图推到我的叉子上。
我知道这里有很多答案,但我认为 git reset --soft HEAD~1
值得关注,因为它可以让您在解决分歧状态的同时保留上一次 local(未推送)提交中的更改。我认为这是一个比使用 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
无论如何都会自动隐藏。 stackoverflow.com/a/30209750/6309
我已经通过移动到最后提交给 origin/master 的 commit_sha 来修复它。
git reset --hard commit_sha
警告:在“commit_sha”提交之后,您将丢失所有提交的内容。
要查看差异:
git difftool --dir-diff master origin/master
这将显示两个分支之间的更改或差异。在 araxis(我的最爱)中,它以文件夹差异样式显示。显示每个更改的文件。然后我可以单击一个文件来查看文件中更改的详细信息。
在我的情况下,这是由于没有提交我的冲突解决方案造成的。
该问题是由运行 git pull
命令引起的。原点的更改导致与我的本地存储库发生冲突,我解决了。但是,我没有提交它们。此时的解决方案是提交更改(git commit
已解决的文件)
如果您在解决冲突后还修改了一些文件,git status
命令会将本地修改显示为未暂存的本地修改,并将合并解决显示为暂存的本地修改。这可以通过首先由 git commit
提交来自合并的更改,然后像往常一样添加和提交未暂存的更改来正确解决(例如,通过 git commit -a
)。
将 123 替换为您的分支偏离原点的提交数。
git reset HEAD~123 && git reset && git checkout . && git clean -fd && git pull
git reset --soft origin/my_remote_tracking_branch
This way you will not loose your local changes
为了更直接地回答原始问题,您可以检查实际的冲突差异:
git diff HEAD..origin/master
并使用此信息来决定是将源的更改拉入本地存储库还是将本地更改推送到源。
我更喜欢这样做更方便和更安全的方式。
# 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 commit --amend -m "New message"
当我使用 git push --force-with-lease repo_name branch_name
推送更改时没有问题。
当我创建一个基于分支 A 的分支时遇到了这个问题
git checkout -b a
然后我将分支a的上游设置为原始分支B
git branch -u origin/B
然后我收到上面的错误消息。
为我解决这个问题的一种方法是,
删除分支a
创建一个新的分支 b 通过
git checkout -b b origin/B
就我而言,当我将 X ver.1 提交从分支 B 推送到其远程跟踪分支 remote_B 时,我收到了这条消息。然后在我的本地存储库中,我进行了更改并将其修改为相同的提交,即 X ver.2。
现在我们在远程仓库提交 X ver1 并在本地提交 X ver.2。然后 git 会告诉你警告
您的本地分支和 remote_ 分别有 1 个和 1 个不同的提交
要解决这个问题,您有两个选择:
1.从远程跟踪分支中拉取更改。
git reset --hard HEAD
git checkout --track remoteRepoName/branch_name
2.强制将修改后的提交推送到远程仓库。 (仅在推送 X ver1 提交后没有任何人拉取远程仓库时推荐)
git push -f remote_repo_name remote_branch_name
master
覆盖远程 master
,从而永远删除任何尚未拉到本地的协作工作。我认为他们想重新组合一个有多个更改的分歧分支,而不是删除一个以支持另一个。 2. 您必须删除分支才能使用 git checkout --track
命令 - 如果分支已经存在,它会发出警告。
不定期副业成功案例分享
git reset --hard HEAD
只会删除任何本地索引的未提交修改,并且不会协调本地和远程 提交 之间的差异。只有合并或变基才能将两组提交(本地提交和远程提交)放在一起。master
在您的示例中指向B
。git reset --hard origin/master
,如下面的答案所述:stackoverflow.com/a/8476004/6309