更新被拒绝,因为您当前分支的最新提交落后于其远程分支。

828

我们的工作流程如下。我们有一个名为dev的分支,在origin/dev处可以访问它。当我们进行更改时,我们会从dev创建一个分支:

git checkout -b FixForBug origin/dev

现在我有一个名为FixForBug的分支,它正在跟踪(我认为这是正确的词语)origin/dev。 因此,如果我执行git pull,它将从origin/dev引入新的更改,非常棒。 现在,当我完成我的修复后,我将其推送到同名的远程分支。

首先,我从origin/dev下载任何更改,并进行变基:

git pull --rebase

然后我将更改推送到同名的远程分支:

git push origin FixForBug

现在,远程服务器上有一个分支,我可以创建一个拉取请求来批准并合并该更改到dev分支中。我从不自己推送任何东西到origin/dev。我猜这是一个很常见的工作流程。
第一次进行git push时,它能够正常工作并创建远程分支。但是,如果我第二次推送(比如在代码审核期间,有人指出了问题),我会收到以下错误信息:
“error: failed to push some refs to 'https://github.mydomain.info/Product/product.git' Updates were rejected because the tip of your current branch is behind its remote counterpart. Integrate the remote changes (e.g. git pull ...) before pushing again. See the 'Note about fast-forwards' in 'git push --help' for details.”
但是,如果我运行git status,它说我比origin/dev多了1个提交(这是有道理的),如果我遵循提示并运行git pull,它会说一切都是最新的。 我认为这是因为我将更改推送到与上游分支不同的分支。 我可以通过运行以下命令来解决此问题: git push -f origin FixForBug 在这种情况下,它会将更改推送到远程分支,显示(forced update),并且在远程分支上一切似乎都很好。
我的问题是:在这种情况下,为什么需要使用-f?通常情况下,当您强制某些内容时,是因为您做错了事情或者至少是违反标准惯例。 这样做是否正确,或者它会搞乱远程分支中的某些东西,或者为最终将我的东西合并到dev中的人创建麻烦?

4
看起来你收到的信息是在告诉你远程分支FixForBug比本地分支FixForBug领先。在推送之前,你应该拉取那个远程分支的更改并将它们合并到你的本地分支中。 - mhatch
15
所以,在我推送之前,基本上要运行 git pull origin FixForBug 对吗?好的,这很有道理。你可以将其作为一个答案添加! - Mike Christensen
7
Stack Overflow最常被复制的问题(纯文本版): https://stackoverflow.blog/2021/04/19/how-often-do-people-actually-copy-and-paste-from-stack-overflow-now-we-know/ - Peter Mortensen
如果您刚刚克隆了此存储库,请尝试拉取远程原始数据。我曾经克隆过我们的repo,但在第一次推送之前忘记拉取“develop”分支,并成功解决了这个错误。 - Paul G
1
不确定,但有时当您在远程分支中具有与您正在推送的相同名称的分支(可能是从该分支创建的PR)时会发生此错误。 您需要删除该分支并关闭PR。 - Neeraj Sonaniya
显示剩余4条评论
30个回答

894

-f 是必需的,因为涉及到 rebase。每当进行 rebase 操作时,由于远程分支无法快进到你的提交,因此需要强制推送。在推送之前,你始终要确保先拉取最新代码,但如果你不想向 master 或 dev 分支强制推送,可以创建一个新分支来推送并合并或发起 pull request。


13
您能否澄清一下“在推送之前,您始终要确保先执行拉取操作”的意思?在本地分支变基后执行“push -f”为什么是必需的已经很明显了。但在这种情况下,在推送之前进行与远程相关的拉取操作,不会撤销本地的变基操作吗? - Hari
3
我也是这么想的,如果我拉取我重新基于的文件,那我就白白地进行了一次重新基于。还是谢谢你的强制推送,我在解决这个问题上遇到了困难。 - claudiodfc
1
谢谢。我喜欢你解释为什么我们必须使用-f(强制)的原因。现在很有道理。 - No One
2
我尝试了 git push -f 但是它显示一切都是最新的。还有其他想法吗? - arielma
我收到了 抱歉,不允许强制推送到主分支 的错误信息。 - Shubham Saroj
显示剩余2条评论

518

*"当前分支的 tip 落后于其远程分支"* 的意思是远程分支已有本地代码库没有的变更,Git 提醒你需要将 REMOTE 的新更改合并到你的代码中,并使用 push 命令上传到远程。

你可以使用此命令强制将本地代码库推送到服务器上()。远程代码库将被你的本地代码库替换。

git push -f origin master

使用-f标签,您将使用本地仓库的代码覆盖远程分支代码。


1
最好启用强制推送,以防您的分支受到保护。 - Waleed93
2
这对我来说实际上在几分钟的挣扎后起作用了。 - NMukama
3
我尝试了 git push -f,但是它说一切都是最新的。还有其他想法吗? - arielma
4
这个命令会不会把所有本地更改推送到主分支并覆盖远程更改? - Yashank
2
这并没有解决原帖作者的情况和/或问题;原帖作者在远程分支上没有任何本地分支没有的更改。 - Olivier
显示剩余4条评论

124

在推送之前,确保你本地的 FixForBug 分支没有领先于远程 FixForBug 分支,需要先拉取并合并变更。

git pull origin FixForBug
git push origin FixForBug

30
楼主说他已经进行了git pull并尝试了push操作。你的回答并不适用于楼主的问题。 - Patrick
2
它确实适用。git pull和git pull origin是不同的东西。 - Vasyl Gutnyk
这对我很有帮助,因为当你本地有多个分支时,除非你执行 git pull origin <branch-name> 否则它不会起作用。 - Jai Prakash

56
设置当前分支名称,例如master
git pull --rebase origin master
git push origin master

或者分支名称 develop
git pull --rebase origin develop
git push origin develop

41

如果您想避免使用-f,则可以仅使用

git pull

而不是

git pull --rebase

非变基操作会从origin/dev获取更改,并将它们合并到您的FixForBug分支中。然后,您就可以运行

git push origin FixForBug

不使用-f选项。


7
"Rebase是我们的工作流程的一部分。如果我不这样做,我会被喊叫的。" - Mike Christensen
2
@MikeChristensen:好的,那么当然要遵循文档中记录的程序。根据你所描述的情况,你需要使用 -f,因为你正在用具有不同(重新基于)历史记录的不同提交替换上游存储库上的提交。如果你使用 Gerrit 等产品,则支持此类重新基于代码审查工作流程,而无需在推送时使用 -f。我们在工作中以这种方式使用 Gerrit,效果非常好。 - Greg Hewgill

32
我们可以使用以下命令将本地存储库强制推送到GitHub以进行更改:
git push -f origin main

我正在本地设置中工作,我只需要强制推送我的更改到主分支存储库,这对我来说很好用。 - Janardhan Reddy

13

我在使用Azure DevOps时遇到了“由于当前分支的顶部落后而拒绝更新”的消息,我使用的命令是/是这个命令:

当我遇到“由于当前分支的顶部落后而拒绝更新”的消息时,在Azure DevOps中使用的命令是:

git pull origin master

(或者可以开始一个新的文件夹并进行克隆)...

这个回答没有直接回答提出的问题,具体而言,Keif已经回答了这个问题,但它确实回答了问题的标题和这将是Azure DevOps用户的常见问题。

我注意到评论中说:"你总是希望在推送之前先执行拉取",这是来自Keif的回答!

我还使用了Git GUI工具以及Git命令行工具。

(我不确定如何在Git GUI中执行等效于命令行命令 "git pull origin master" 的操作,所以我又回到了命令行来执行这个命令)。

显示各种Git命令以及您可能想要执行的各种操作的图表如下:

输入图像描述


11

这可能是因为提交在您当前推送的代码之前。

  1. git pull origin "想要推送的分支名"

  2. git rebase

    如果git rebase成功,则很好。否则,您需要解决所有本地合并冲突,并一直进行下去,直到与远程的rebase成功为止。

  3. git rebase --continue


7

在我的情况下,远程仓库已经有一个与我正在开发的dev分支同名的分支。我只是将该分支重命名并推送代码。这对我起作用。

git checkout -b new-branch-name
git push origin new-branch-name

1
这适用于我! - Vkl125
是的,这是我多年来一直在使用的解决方法。但我想我们需要的是自动化的修复。 - havryliuk

7

这刚刚发生在我身上。

  • 昨天我向我们的主分支提交了一个pull request。
  • 我的同事今天正在审核它时发现它与我们的主分支不同步,因此他合并了主分支到我的分支中,目的是帮助我。
  • 我不知道他那样做了。
  • 然后我在本地合并了主分支,尝试推送,但失败了。为什么?因为我同事合并主分支创建了一个我本地没有的额外提交

解决方案:拉取我的自有分支,这样就可以得到那个额外的提交。然后将其推送回我的远程分支。

在我的分支上,我实际上只做了以下操作:

git pull
git push

1
没错。但我认为问题描述中的情况是,与本地分支相比,远程实际上没有新的更改。 - havryliuk

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