Git推送错误:拒绝更新签出分支

我已经解决了一些合并冲突,然后尝试推送我的更改并收到以下错误:

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master Done remote: error: refusing to update checked out branch: refs/heads/master remote: error: By default, updating the current branch in a non-bare repository remote: error: is denied, because it will make the index and work tree inconsistent remote: error: with what you pushed, and will require 'git reset --hard' to match remote: error: the work tree to HEAD. remote: error: remote: error: You can set 'receive.denyCurrentBranch' configuration variable to remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into remote: error: its current branch; however, this is not recommended unless you remote: error: arranged to update its work tree to match what you pushed in some remote: error: other way. remote: error: remote: error: To squelch this message and still keep the default behaviour, set remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'. To C:/Development/GIT_Repo/Project ! [remote rejected] master -> master (branch is currently checked out) error: failed to push some refs to 'C:/Development/GIT_Repo/Project' 

有谁知道什么可能导致这个错误?

存储库有两种types: 裸露和非裸露

裸仓库没有工作副本,您可以推送给他们。 这些是你在Github中获得的仓库types! 如果你想创build一个裸仓库,你可以使用

 git init --bare 

所以,简而言之, 你不能推送到非裸仓库 (编辑:那么,你不能推送到存储库的当前检出分支。在裸仓库中,你可以推送到任何分支,因为没有检出。虽然可能推送到非裸仓库是不常见的) 。 你可以做的是从另一个仓库中获取和合并。 这就是你在Github中看到的pull request工作原理。 你要求他们从你身上拉出来,而你不要强迫他们。


更新 :感谢VonC指出这一点,在最新的git版本(目前是2.3.0), 推送到非裸仓库的检出分支是可能的 。 尽pipe如此,你仍然无法推到一棵干净的工作树,无论如何这不是一个安全的操作。

我解决了这个问题,首先validation那个遥控器没有检出任何东西(它真的不应该这样做),然后用下面的方法把它弄干净:

 $ git config --bool core.bare true 

之后,git推工作正常。

概要

您不能推送到存储库的一个签出分支,因为它会以最可能以数据和历史丢失而结束的方式混淆该存储库的用户。 但是你可以推送到同一个仓库的其他分支。

裸仓库永远不会检出任何分支,您可以随时推送到裸仓库的任何分支。

解决问题的方法

当一个分支签出时,提交将添加一个新的提交与当前分支的头作为其父,并移动分支的头是新的提交。

所以

 A ← B ↑ [HEAD,branch1] 

 A ← B ← C ↑ [HEAD,branch1] 

但是如果有人可以推送到这个分支之间,用户会自己在什么git调用分离头模式:

 A ← B ← X ↑ ↑ [HEAD] [branch1] 

现在用户不再是分支1了,没有明确要求检出另一个分支。 更糟糕的是,用户现在在任何一个分支之外 ,任何新的提交只会是悬而未决的

  [HEAD] ↓ C ↙ A ← B ← X ↑ [branch1] 

假设,如果在这一点上,用户检出另一个分支,那么这个悬而未决的提交就变成了Git的垃圾收集器的公平游戏。

cd到您正在远程机器上推入的repo /目录并进入

 $ git config core.bare true 

由于已经存在一个存储库,正在运行

 git config --bool core.bare true 

在远程仓库上就够了

从core.bare文档

如果为true(裸=真),则假定存储库是空的,没有工作目录关联。 如果是这样的话,需要工作目录的许多命令将被禁用,比如git-add或者git-merge(但是你可以推送到它)。

当创build仓库时,这个设置会被git-clone或者git-init自动猜到。 默认情况下,以“/.git”结尾的存储库被假定为不是裸(裸=假),而所有其他存储库被假定为裸(裸=真)。

TLDR

  1. 再次推拉: git pull &&& git push
  2. 还是一个问题? 推入不同的分支: git push origin master:foo并将其合并到远程repo上。
  3. 或者通过添加-fdenyCurrentBranch需要被忽略)强制推送。

基本上这个错误意味着你的版本库并不是最新的远程代码(它的索引和工作树与你推送的版本不一致)。

通常情况下,您应该首先获取最近的更改并再次push

如果没有帮助,请尝试推入不同的分支,例如:

 git push origin master:foo 

然后将这个分支与远程资源库合并在一起。

如果你通过git rebase有意地改变了一些以前的提交,并且想要用你的改变覆盖repo,那么你可能想要通过添加-f / --force参数来强制推送(如果你没有进行rebase不build议这么做)。 如果仍然无法工作,您需要设置receive.denyCurrentBranch以通过以下方式在git消息中build议的远程ignore

 git config receive.denyCurrentBranch ignore 

对我来说,下面的诀窍是:

git config --global receive.denyCurrentBranch updateInstead

我设置了驱动器F:,几乎全部使用Git在Windows 10桌面和我的Windows 10笔记本电脑之间进行同步。 我结束了在两台机器上运行上述命令。

首先,我在networking上共享桌面的F驱动器。 然后,我可以通过运行以下代码将其克隆在笔记本电脑上:

F: git clone 'file://///DESKTOP-PC/f'

不幸的是,所有文件都在笔记本电脑的“F:\ f \”下,而不是直接在F:\下。 但是我能够手动剪切和粘贴。 之后Git仍然从新的位置开始工作。

然后,我尝试对笔记本电脑上的文件进行一些更改,将它们提交并将其推回桌面。 直到我运行上面提到的git config命令时,这才工作。

请注意,我在两台机器上从Windows PowerShell中运行了所有这些命令。

更新:在某些情况下,我仍然遇到推送更改的问题。 我终于刚开始拉改变,通过在计算机上运行以下内容我想将最新的提交(s):

git pull --all --prune

也许你的远程回购是在你想推的分支。 您可以尝试在远程计算机上签出另一个分支。 我做到了,比这些错误消失了,我把成功推向了我的远程仓库。 注意我使用ssh来连接我自己的服务器而不是github.com。

我有这个错误,因为在同一地点(意外)初始化两次git回购:首先作为一个非裸露的回购,并作为裸回购后不久。 由于.git文件夹仍然存在,git假定存储库不是裸露的。 删除.git文件夹和工作目录数据解决了这个问题。