Git说本地分支落后于远程分支,但实际上并不是这样。

87

场景:

  1. 我创建了一个新的分支
  2. 在它上面进行修改
  3. 提交更改
  4. 推送更改
  5. 继续在它上面进行修改
  6. 再次提交更改
  7. 尝试再次推送

Git 响应:

更新被拒绝,因为您当前分支的末端落后于远程分支。等等。

我是唯一在这个分支上进行修改的人 - 没有其他人在操作它。远程分支实际上落后于本地分支。 我不应该需要拉(pull)。

(如果我确实拉取(pull),Git会报告两个分支之间的冲突,并强制我将该分支合并到自己中)

为什么会出现这种情况?我该如何诊断/解决它?

明确一点,我没有在任何地方创建分支,而且没有其他人在操作它:

Remote: Commit A -------- Commit B  

Local:  Commit A -------- Commit B -------- Commit C  

C是B的直接延续,没有分支。但是git认为C是A的一个分支:

Remote: Commit A -------- Commit B  

                  ------- Commit C  
                /  
Local:  Commit A -------- Commit B  

不是这样的;它是B的直接延续。


1
git remote -vgit show remote origin 的输出(假设 origin 是你遇到问题的远程仓库)可能会有所帮助。 - Ben Graham
4个回答

201

你可能进行了一些历史记录重写操作?你的本地分支与服务器上的分支产生了分歧。运行以下命令可以更好地了解发生了什么:

gitk HEAD @{u}

我强烈建议您尝试理解此错误的来源。要修复它,只需运行:

git push -f

使用-f参数会将此推送视为“强制推送”,并且会在服务器上覆写分支。当您与团队合作时,这是非常危险的。但是,如果你确定自己本地的状态是正确的,那么这应该没问题。如果不是这种情况,你可能会失去提交历史记录。


13
就是这样了。在第二步,我执行了“修正最后提交”操作,然后推送,接着进行了一些修改,然后尝试再次推送。我误解了“修正”操作的方式。谢谢! - Tim Janke
4
这似乎非常有用 - 但是可以有人解释一下 'HEAD @{u}' 的语法吗? - ChrisV
5
HEAD@{u} 都是指代提交记录的。它们告诉 gitk 要显示哪些分支。HEAD 指代当前被检出的分支,@{u}HEAD@{u} 的缩写,表示当前被检出分支的上游分支。所以例如对于 master 分支来说,通常就是 origin/master - Chronial
遇到了相同的情况 - 必须进行重新扫描和合并冲突。使用 gitk 很有帮助! - brichins
如果我在本地进行了许多简单的提交(而不是修改),然后尝试推送,就会发生这种情况。我知道没有其他人在github上更改东西。Gitk确实显示远程与本地不同,尽管预期应该将本地显示为比远程更新的版本,而不是将远程显示为分叉(看起来像那样,我不太了解gitk)。 - Aquarius Power

6
解决方案非常简单,对我很有效。请尝试以下方法:
```html

解决方法:

尝试这个:

```
git pull --rebase <url>

那么

git push -u origin master

4

我曾经在尝试推送develop分支时遇到了这个问题(我使用的是git flow)。有人已经将更新推送到了master分支。为了修复它,我执行了以下操作:

git co master
git pull

这将获取这些更改。然后,

git co develop
git pull

这似乎没有任何作用。我认为开发分支已经被推送,尽管有错误消息。现在一切都是最新的,也没有错误。


0

要诊断它,请按照this answer的步骤。

但是为了修复它,因为只有你在更改它,所以请执行以下操作:
1-备份您的项目(我只备份了git上的文件,./src文件夹)
2-git pull
3-将备份还原到许多“混乱”的文件中(带有合并指示符)

我尝试过git pull -s recursive -X ours,但它没有按照我想要的方式工作,虽然这可能是一个选项,但首先要备份!!!

确保差异/更改(在git gui中)不存在。这是我的情况,根本没有需要合并的内容,但github仍然会提示我应该合并...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接