225

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

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'

有谁知道可能导致此错误的原因?

4

13 回答 13

267

原因:您正在推送到非裸存储库

有两种类型的存储库:裸存储库和非裸存储库

裸存储库没有工作副本,您可以推送到它们。这些是您在 Github 中获得的存储库类型!如果要创建裸存储库,可以使用

git init --bare

所以,简而言之,你不能推送到非裸存储库(编辑:好吧,您不能推送到存储库的当前签出分支。对于裸存储库,您可以推送到任何分支,因为没有签出。虽然可能,但推送到非裸存储库并不常见) . 您可以做的是从其他存储库中获取和合并。这就是pull request你可以在 Github 中看到的工作方式。你要求他们从你身边拉开,而不是强行推入他们。


更新:感谢 VonC 指出这一点,在最新的 git 版本(当前为 2.3.0)中,推送到非裸存储库的签出分支是可能的。尽管如此,您仍然不能推送到的工作树,这无论如何都不是安全的操作。

于 2012-06-20T10:47:46.270 回答
136

我解决了这个问题,首先验证遥控器没有检查任何东西(它真的不应该),然后让它裸露:

$ git config --bool core.bare true

之后 git push 工作正常。

于 2014-06-20T21:11:44.817 回答
53

概括

您不能推送到存储库的已签出分支,因为它会以一种很可能以丢失数据和历史记录的方式与该存储库的用户混淆。但是您可以推送到同一存储库的任何其他分支。

由于裸存储库从未检出任何分支,因此您始终可以推送到裸存储库的任何分支。

问题的尸检

当一个分支被签出时,提交将添加一个以当前分支的头部作为其父分支的新提交,并将分支的头部移动到该新提交。

所以

A ← B
    ↑
[HEAD,branch1]

变成

A ← B ← C
        ↑
    [HEAD,branch1]

但是如果有人可以在中间推送到那个分支,用户就会进入 git 所说的分离头模式:

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

现在用户不再在 branch1 中,没有明确要求签出另一个分支。更糟糕的是,用户现在在任何分支之外,任何新的提交都只是悬空

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

假设,如果此时用户签出另一个分支,那么这个悬空提交对于 Git 的垃圾收集器来说是公平的游戏。

于 2013-02-14T15:35:27.443 回答
27

对我来说,以下是诀窍:

git config --global receive.denyCurrentBranch updateInstead

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

首先我在网络上共享了桌面的F盘。然后我可以通过运行在我的笔记本电脑上克隆它:

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

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

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

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

更新:在某些情况下,我仍然在推动更改时遇到问题。我终于开始拉动更改,而是在我想拉动最新提交的计算机上运行以下命令:

git pull --all --prune
于 2016-03-12T02:17:10.713 回答
22

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

$ git config core.bare true
于 2015-05-20T03:09:24.577 回答
15

TLDR

  1. 再次拉和推:git pull &&& git push
  2. 还是有问题?推入不同的分支:git push origin master:foo并将其合并到远程仓库。
  3. -f或者通过添加(denyCurrentBranch需要忽略) 来强制推送。

基本上,该错误意味着您的存储库与远程代码不是最新的(其索引和工作树与您推送的内容不一致)。

通常,您应该pull首先获取最近的更改,push然后再次获取。

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

git push origin master:foo

然后将远程存储库上的这个分支与 master 合并。

如果您有意更改了一些过去的提交,git rebase并且您想用您的更改覆盖 repo,您​​可能希望通过添加-f/--force参数来强制推送(如果您没有这样做,则不推荐rebase)。如果仍然无法工作,您需要按照 git 消息的建议通过以下方式设置receive.denyCurrentBranch为远程:ignore

git config receive.denyCurrentBranch ignore
于 2014-07-31T10:34:35.120 回答
15

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

git config --bool core.bare true

在远程存储库上就足够了

来自 core.bare 文档

如果为真(bare = true),则假定存储库是裸露的,没有关联的工作目录。如果是这种情况,许多需要工作目录的命令将被禁用,例如 git-add 或 git-merge(但您将能够推送到它)。

创建存储库时,git-clone 或 git-init 会自动猜测此设置。默认情况下,假设以“/.git”结尾的存储库不是裸露的(bare = false),而所有其他存储库都假定是裸露的(bare = true)。

于 2014-12-18T17:11:45.747 回答
3

也许您的远程仓库位于您要推送的分支中。您可以尝试在远程机器中检出另一个分支。我这样做了,然后这些错误消失了,我将成功推送到我的远程仓库。请注意,我使用 ssh 来连接我自己的服务器,而不是 github.com。

于 2013-06-23T05:25:14.427 回答
3

正如其他答案中提到的,您不能推送到已签出的分支。让我们从那里开始。

从远程服务器,让我们将远程存储库签出到一个临时分支。

git checkout -b temp

现在从我们的本地存储库,我们可以推送到主分支。

git push

但这不是一个永久的解决方案。未来的推动将带来同样的问题。为了一劳永逸地解决这个问题,您需要将远程存储库变成裸存储库。从远程服务器,输入:

git config core.bare true

现在您可以毫无问题地推送到遥控器。

将来,使用如下--bare选项创建远程存储库:

git init --bare
于 2021-10-02T18:17:51.443 回答
1

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

于 2017-06-16T08:20:49.840 回答
1

这对我有用

  1. git config --global receive.denyCurrentBranch updateInstead

  2. git push origin master

于 2020-07-11T08:00:02.443 回答
0

当我在阅读 progit 时玩耍时出现此错误。我创建了一个本地存储库,然后在同一文件系统上的另一个存储库中获取它,进行了编辑并尝试推送。在阅读了 NowhereMan 的答案后,一个快速的解决方法是转到“远程”目录并临时签出另一个提交,从我进行更改的目录中推送,然后返回并将头放回 master。

于 2019-12-31T16:13:55.730 回答
0

我有同样的问题并尝试这样做:

  1. SSH 到 gitlab 服务器(远程服务器机器不是你的个人机器)并发现 [core]:bare value is false in yourRepo/.git/config

在此处输入图像描述

2. vim config 并将其编辑为 true 现在,很好。我可以推送到 master。

于 2022-01-26T06:29:31.470 回答