GitHub有一个名为"处理“非快进”错误"的很好的部分。
起初,这个错误可能会让人感到有些压抑,不要害怕。
简单来说,如果没有丢失提交,git无法在远程进行更改,因此拒绝推送.
通常情况下,这是由另一个用户向同一分支推送导致的。您可以通过获取并合并远程分支或使用pull一次性执行两个操作来解决此问题。在其他情况下,此错误是通过使用如
git commit --amend
或git rebase
等命令在本地进行破坏性更改而导致的。
虽然您可以通过将--force
添加到push
命令来覆盖远程内容,但只有在您完全确定要这样做时才应该这样做。
强制推送可能会对已获取远程分支的其他用户造成问题,并被认为是不良实践。 如果有疑问,请不要强制推送。
Git不能像快进合并一样在远程进行更改,Visual Git Reference将其描述如下:
虽然这不是完全符合您的情况,但可以帮助您了解什么是“快进”(其中一个分支的HEAD
简单地移动到新的更近提交)。
"branch master->master(非快进)已经是最新的
"通常是针对不跟踪其远程副本的本地分支。
例如,请参见此SO问题 "git pull says up-to-date but git push rejects non-fast forward"。
这意味着您的Subversion分支和远程Git主分支在某些方面存在不一致。
在其中一个中提交了某些更改,而在另一个中则没有相应的更新。
运行gitk --all
命令,它应该会给你一些线索,帮助你找到错误所在——查看历史记录中的“分叉”。
这意味着远程仓库中已经有其他与您的提交不同的提交。通常可以使用
解决此问题。git pull
在你执行推送操作之前
最终,“快进”意味着提交可以直接应用于工作树,而不需要合并。
在这种情况下,您可能需要使用强制推送操作
git push origin master --force
--force
的副作用。 - Miles Erickson快进式更新是指另一侧最新提交之后,仅该侧有更改,因此不需要合并。这意味着您需要在推送之前合并您的更改。
不要使用 git -f
来进行 push
操作,因为这可能会导致之后灾难性的后果。
你只需要对本地分支执行 git pull
命令。
例如:
git pull origin 'your_local_branch'
然后执行git push
$ git pull
,但它抛出了fatal: refusing to merge unrelated histories
错误(在bash中作为普通文本显示)。
我尝试了重新基础、重新暂存和重新提交,但问题仍未解决。在这种情况下,我的目标是无论如何都要合并它,因为我想保留两者,并且它们之间没有任何共同的文件。因此,我通过传递以下参数允许不相关的历史记录:
$ git pull origin main --allow-unrelated-histories
此命令将合并-忽略它们位于不同位置的事实。
然后使用以下命令将其推送到origin分支:
$ git push -u origin main
如果有人更擅长解释这一点,请随意编辑此答案。
在将更改推送到远程仓库/分支之前,您需要合并和解决本地的冲突。
1)拉取(获取和合并)
$ git pull remote branch
2) 推送更改
$ git push remote branch
你仍然可以通过使用--force
选项强制进行push
,但应该避免这样做,因为它可能会导致更改丢失或对其他贡献者产生不良影响。
...但我犯了一个巨大的错误,忘记点击Fetch
按钮查看最新版本,结果我没有看到。
提交成功执行,但是没有推送,而是出现了同样的错误; 即使其他开发人员没有更改与我相同的文件,我也无法拉取最新版本,因为同样的错误被呈现。
大多数时候,我更喜欢使用Sourcetree的GUI(图形用户界面)。这个解决方案可能不是理想的,但这是让我重新开始而不必担心可能会丢失我的更改或妥协其他开发人员的更新的方法。
右键单击你之前提交的提交以撤消本地提交的更改,并选择Reset current branch to this commit
,如下所示:
当所有的加载图标消失并且Sourcetree已经完成上一个提交的加载时,在窗口左上角,单击Pull
按钮...
...然后会弹出一个对话框,点击右下角的确定
按钮:
拉取最新版本后,如果没有出现任何错误,请跳过步骤四(下一步)。否则,如果您在此时发现任何合并冲突,比如我在Web.config
文件中遇到的情况:
...然后点击顶部的Stash
按钮,会弹出一个对话框,您需要编写一个描述性名称来说明您的更改,然后点击OK
按钮:
...一旦Sourcetree完成了你修改文件的暂存,重复步骤2(上面的先前步骤),然后你的本地文件就会有最新更改。现在你可以通过打开Sourcetree左列底部看到的STASHES
来重新应用你的更改,使用箭头展开暂存,然后右键选择Apply Stash '描述你的更改名称'
,然后在弹出的对话框中选择OK
按钮:
如果你现在有任何合并冲突,请前往你偏好的文本编辑器,如Visual Studio Code,在受影响的文件中选择 接受传入的更改
链接,然后保存:
然后回到Sourcetree,在顶部点击Commit
按钮:
终于!!!我们现在可以提交我们的文件,还要在点击“提交”按钮之前勾选“立即将更改推送到源”的选项:
顺便说一下,写这篇文章的时候,我刚要提交代码时,另一个开发人员已经提交了一次,所以我不得不重复之前的步骤。
关于我的回答,可以参考这里... Git push失败,"非快进式更新被拒绝"
最安全的解决方法是使用 --rebase
例如:
git pull <remote> <branch> --rebase
--force-with-lease
推送更改。git push <remote> <branch> --force-with-lease
使用此标志,Git 将检查分支的远程版本是否与您正在 rebase 的版本相同,即如果有人在您 rebase 时推送了新的提交,则该推送将被拒绝,您将被强制重新 rebase 分支。
如果您正在处理每小时数百个提交的大型项目,则这很烦人,但仍然是解决此问题的最佳方法。
除非您确切知道自己在做什么,否则请避免使用 --force。
使用 --force
是具有破坏性的,因为它会无条件地用本地内容覆盖远程存储库。
但是使用 --force-with-lease
,可以确保不会覆盖其他人的工作。
在 Atlassian 的开发者博客中阅读此文章以获取更多信息。