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

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个回答

7

在我的组织的GitLab中,没有任何方法适用于我。最终我使用了以下命令从我的featureBranch中运行:

在feature分支中运行以下命令:

git pull origin featureBranch --rebase

如果您遇到任何冲突,在解决完冲突后:
git rebase --continue
Enter commit messages -> press ESC -> enter “:wq!” and enter
git push origin featureBranch

5
这是我解决问题的方法:
假设上游分支是你从中 fork 下来的,origin 是你的存储库,并且你想将 MR/PR 发送到上游分支。
你已经有了大约四个提交,但出现了 Updates were rejected because the tip of your current branch is behind.
这是我所做的:
首先,将你的四个提交合并成一个:
git rebase -i HEAD~4

您将获得一个包含 pick 文字的提交清单(在编辑器中打开)。

示例

pick fda59df commit 1
pick x536897 commit 2
pick c01a668 commit 3
pick c011a77 commit 4

to

pick fda59df commit 1
squash x536897 commit 2
squash c01a668 commit 3
squash c011a77 commit 4

完成后,您可以保存合并提交。

接下来

您需要将提交内容储存起来。

以下是操作步骤:

git reset --soft HEAD~1
git stash

现在请将您的分支与上游分支进行变基:
git fetch upstream beta && git rebase upstream/beta

现在请取出你存储的提交内容:
git stash pop

提交这些更改并推送它们:
git add -A
git commit -m "[foo] - foobar commit"
git push origin fix/#123 -f

4

如果你真的担心其他方法,这些步骤可以帮助你轻松完成:

1:将您要推送的更改在本地分支中进行 暂存

2:将您的本地分支重命名为备份以备将来使用

3:从远程创建同名分支,它将具有所有更改

4:检出此新分支作为您的新本地分支

5:在该分支中进行更改并保存

6:提交和推送


4

我来帮忙:

git stash
git pull origin master
git apply
git commit -m "some comment"
git push

“Me help next”(似乎无法理解)是什么意思?你能详细说明一下吗? - Peter Mortensen
这个方法可行,但我需要先添加 git reset --soft HEAD~1 - marc-stupid

3
如果您使用TortoiseGit推送对话框

enter image description here

引用来源: https://tortoisegit.org/docs/tortoisegit/tgit-dug-push.html#id692368

已知变更 - 这样可以让远程仓库接受一个安全的非快进式(push)提交。这可能会导致远程仓库丢失提交; 需要小心使用。这可以防止在远程上遗失其他人的未知更改。它检查服务端分支是否与远程跟踪分支(已知变更)指向相同的提交。如果是,则执行强制推送(force push)。否则将被拒绝。由于Git没有远程跟踪标签(remote-tracking tags),因此不能使用此选项覆盖标签。这传递了git push命令的--force-with-lease选项。

未知更改 - 这使远程仓库接受不安全的非快进式(push)提交。这可能会导致远程仓库丢失提交; 需要小心使用。这不检查任何服务器提交,因此可能会在远程上丢失未知更改。使用此选项包括标签以覆盖标签。这传递了git push命令的传统--force选项。


2
在这里,当您尝试从主分支重新设置dev-feature分支的基础时(Git版本为参考 >> git version git version 2.37.1 (Apple Git-137.1)),请按如下步骤操作:

1. git checkout dev-feature

检出功能分支

2. git pull

将头更新到最新提交

3. git pull --rebase origin master

设置重置标志以从主存储库拉取

4. git config pull.rebase true 如果未设置协调方法,因为您有2个不同的分支 5. git pull 成功地重新设置了refs/heads/dev-feature分支** 如果您收到上述消息,则表示已重新设置该分支

6. git push origin dev-feature 将这些更改推送到远程


1
如果您尝试了之前的所有答案,问题仍未解决,请确保推送的分支名称是唯一的且不存在于远程中。
错误消息可能会误导。

我的帖子中没有相关的答案。如果有的话,我会同意你的观点。 - M.Erkan Çam

1

由于您当前分支的末尾落后,推送被拒绝。

当我遇到这种情况时,我只运行了:

git push -f origin main

它已经完成了。


2
git push -f 会覆盖上游的更改,从技术上讲是正确的。但大多数情况下,您希望将自己的更改添加到现有代码中,所以您需要执行 git fetch 来获取这些更改,然后使用 git rebase origin/branchname 将您的更改重新应用到上游。可能需要解决合并冲突,但这样您就不会覆盖其他人的工作了。 - Joe Block

1

这取决于权限。

你可能没有直接推送到主分支(master、development)的权限。如果你在企业项目中,应该将自己的主题分支推送到远程,并提交合并请求(MR)。


1
我在通过Visual Studio Code进行变基后尝试推送时遇到了这个问题。我的问题是通过从Git输出窗口复制命令并在Visual Studio Code的终端窗口中执行解决的。
在我的情况下,命令类似于:
git push origin NameOfMyBranch:NameOfMyBranch

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