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

时间:2012-06-20 10:40:18

标签: git git-push

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

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'

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

11 个答案:

答案 0 :(得分:195)

有两种类型的存储库:bare and non-bare

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

git init --bare

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


更新:感谢VonC在最新的git版本(目前为2.3.0)中指出了这一点,pushing to the checked out branch of a non-bare repository is possible。尽管如此,您仍然无法推送到工作树,无论如何这都不是一个安全的操作。

答案 1 :(得分:96)

我通过首先验证遥控器没有检出任何东西(它确实不应该)来解决这个问题,然后让它裸露出来:

$ git config --bool core.bare true

之后git push工作正常。

答案 2 :(得分:38)

摘要

您无法推送到存储库的一个已检出分支,因为它会以最有可能以数据丢失和历史记录结束的方式混淆该存储库的用户。但是你可以推送到同一个存储库的任何其他分支。

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

问题的解剖

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

所以

A ← B
    ↑
[HEAD,branch1]

变为

A ← B ← C
        ↑
    [HEAD,branch1]

但是如果有人可以在中间推送到那个分支,那么用户就可以使用git调用分离头模式:

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

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

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

假设,如果此时,用户检出另一个分支,那么这个悬空提交将成为Git的垃圾收集器的公平游戏。

答案 3 :(得分:19)

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

$ git config core.bare true

答案 4 :(得分:13)

对我来说,以下是诀窍:

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

答案 5 :(得分:12)

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

git config --bool core.bare true
远程存储库上的

应该足够了

来自core.bare文档

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

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

答案 6 :(得分:9)

TLDR

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

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

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

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

    git push origin master:foo
    

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

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

    git config receive.denyCurrentBranch ignore
    

答案 7 :(得分:3)

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

答案 8 :(得分:1)

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

对我有用

  1. git config --global receive.denyCurrentBranch updateInstead

  2. git push origin master