“ Git 推送非快进更新被拒绝”是什么意思?

我使用 Git 来管理我的两台计算机和我的开发。我试图提交对 GitHub 的更改,但是我得到了这个错误:

未能将一些参考推到 <repo>。为了防止丢失历史记录,拒绝了非快进更新。合并远程更改,然后再次推动。

是什么导致了这一切,我该怎么解决?

编辑:

撤回回购协议的结果如下:

* 分部总监-> 总监(非快进) 已经更新了

推动仍然给我上述的错误。

267650 次浏览

这意味着已经有其他提交被推送到远程存储库,这些提交与您的提交不同。通常可以用

git pull

在你用力之前

最终,“快进”意味着提交可以直接应用于工作树的顶部,而不需要进行合并。

快进更新是指一方的唯一更改发生在另一方的最近提交之后,因此不需要进行任何合并。这意味着您需要合并更改,然后才能进行推送。

GitHub 有一个很好的部分叫做“ 处理“非快进”错误

这个错误一开始可能有点难以承受,不要害怕。
简单地说,git 不能在远程上进行更改而不丢失提交,因此它拒绝了 push
通常这是由于另一个用户推到同一个分支。您可以通过获取和合并远程分支,或者使用 pull 同时执行这两个操作来解决这个问题。

在其他情况下,这个错误是使用诸如 git commit --amendgit rebase之类的命令在本地进行破坏性更改的结果。
虽然可以通过将 --force添加到 push命令来重写远程,但是只有在完全确定这是您想要做的事情时才应该这样做。
强制推送可能会给已经获取远程分支的其他用户带来问题,这被认为是不好的做法。


Git 不能像快进合并那样在远程进行更改,可视化 Git 引用的例子如下:

alt text

这不是 没错的情况,但有助于了解什么是“快进”(其中分支的 HEAD只是被移动到一个新的更新的提交)。


branch master->master (non-fast-forward) Already-up-to-date”通常用于不跟踪远程对应部分的本地分支。
比如看这个 SO 问题“ Git pull 说是最新的,但是 Git push 拒绝非快进”。
或者,这两个分支是相互联系的,但与它们各自的历史存在分歧:
看“ 永无止境的 GIT 故事——我到底做错了什么?

这意味着您的 subversion 分支和您的远程 git 主分支在某些事情上不一致。
一些改变被推动/承诺给一个不在另一个中的改变。
启动 gitk --all,它应该会给你一个关于错误的线索-寻找历史上的“叉子”。

在这种情况下,可能需要使用推操作和强制操作

Git 推动原点主控器——力

在将更改推送到远程 repo/fork 之前,需要合并并解析 conflicts locally

1)拉(取回并合并)

$ git pull remote branch

2)推动改变

$ git push remote branch

尽管如此,您仍然可以通过使用 --force选项快速选择 push,但应该避免,因为它可能导致更改损失或对其他贡献者造成严重影响。

永远不要做一个 git -fpush,因为它可能导致以后的灾难性后果。

你只需要做一个本地分支的 git pull

例如:

git pull origin 'your_local_branch'

然后做 git push

在我的情况下,完全相同的错误,我也不是唯一的开发人员。

所以我同时提交和推动我的改变,在 Commit对话框弹出窗口的底部可以看到:

Checked option for: Push changes immediately to origin

但我犯了个大错,忘了按 Fetch键看看有没有最新的,我没有。

提交成功执行,但不是推,而是给出同样的错误; ... 即使其他开发人员没有改变相同的文件,我不能拉最新的同样的错误提出。

图形用户界面解决方案

大多数时候我更喜欢坚持使用 Sourcetree 的 图形用户界面(图形用户界面)。这个解决方案可能并不理想,但是正是这个解决方案让我重新开始工作,而不用担心我可能会丢失我的更改或者损害其他开发人员最近的更新。

步骤1

右键单击您前面的提交,撤消本地提交的更改,然后选择 Reset current branch to this commit,如下所示:

Sourcetree window with right-clicked commit and selecting: Reset current branch to this commit

步骤2

一旦所有的加载旋转器消失,Sourcetree 完成了上一个提交,在窗口的左上角,点击 abc0按钮..。

Sourcetree window with with the Pull button highlighted

然后弹出一个对话框,点击右下角的 OK按钮:

Sourcetree window dialog popup with the OK button highlighted

步骤3

拉最新,如果你没有得到任何错误,跳到 步骤4(下一步)。否则,如果您在此时发现任何合并冲突,就像我对 Web.config文件所做的那样:

Sourcetree window showing the error hint: Updates were rejected because the tip of your current branch is behind

... 然后点击顶部的 Stash按钮,弹出一个对话框,你需要写一个描述性的修改名称,然后点击 OK按钮:

Sourcetree window with Stash button highlighted and dialog popup showing input to name your stash with OK button highlighted

... 一旦 Sourcetree 完成存储您更改的文件,在 步骤2中重复操作(上一步) ,然后您的本地文件将有最新的更改。现在你可以重新应用你的改变,打开你在 Sourcetree 左栏底部看到的 STASHES,使用箭头来展开你的存储,然后右键点击选择 Apply Stash 'Descriptive-name-of-your-changes',然后在对话框中选择 OK按钮,弹出:

Sourcetree window with the Stashes section expanded and changes right-clicked with Apply Stash highlighted

Sourcetree dialog popup ask your to confirm if you would like to apply stash you your local copy

如果您现在有任何合并冲突,转到您首选的文本编辑器,如 Visual Studio Code,并在受影响的文件中选择 Accept Incoming Change链接,然后保存:

enter image description here

然后回到 Sourcetree,点击顶部的 Commit按钮:

enter image description here

然后右键单击冲突文件,在 Resolve Conflicts下选择 Mark Resolved选项:

enter image description here

步骤4

终于! ! ! 我们现在可以提交我们的文件了,在点击 Commit按钮之前还要选中 Push changes immediately to origin选项:

enter image description here

另外,在写这篇文章的时候,另一个开发人员在我提交之前提交了一个提交,所以我不得不重复很多步骤。

如果您的远程分支被更新,并且它没有与您的本地回购同步,那么也会发生这种情况。所以在我的例子中,我创建了一个 git repo 并添加了 readme 文件。在我的本地机器上,我创建了新的文件上传到那个回购,所以我试图推,因为我通常会这样做。在那之后,我确实执行了 $git pull,但它抛出了 fatal: refusing to merge unrelated histories错误(在 bash 中是普通文本)。 我尝试了重新定基、重新分段和重新提交,但仍然没有解决这个问题。在这种情况下,我的目标是无论如何都要合并它,因为我想保留这两个文件,而且它们之间没有任何共同的文件。因此,我通过以下方式传递参数来允许不相关的历史记录:

$git pull origin main --allow-unrelated-histories

这个命令将合并——忽略了两者处于不同位置的事实。

然后使用以下方法将其推送到原始分支: $git push -u origin main

如果有人能更好地解释这个问题,请随意编辑这个答案。