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

Fun*_*nky 179 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'
Run Code Online (Sandbox Code Playgroud)

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

Sha*_*baz 210

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

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

git init --bare
Run Code Online (Sandbox Code Playgroud)

因此,简而言之,您无法推送到非裸存储库(编辑:好吧,你不能推送到存储库的当前签出分支.使用裸存储库,你可以推送到任何分支,因为没有签出.尽管可能,推送到非裸存储库并不常见) .你可以做的是从另一个存储库中获取和合并.这就是pull request你在Github中看到的工作方式.你要求他们从你身边拉,你不要强行推进他们.


更新:感谢VonC指出这一点,在最新的git版本(目前是2.3.0)中,可以推送到非裸存储库的签出分支.然而,你仍然无法推到一个肮脏的工作树,无论如何这不是一个安全的操作.

  • 实际上,你可以很好地推送到非裸存储库,你只是无法推送到目前已经检出**的一个分支**. (20认同)
  • 实际上你现在有一种安全的方法可以使用Git 2.3.0(2015年2月)和`git config receive.denyCurrentBranch = updateInstead`推送到非裸机:http://stackoverflow.com/a/28262104/6309 (6认同)

Sas*_*hev 103

我通过首先验证远程没有检出任何东西(它真的不应该)来解决这个问题,然后使它裸露:

$ git config --bool core.bare true
Run Code Online (Sandbox Code Playgroud)

之后,git push工作得很好.

  • 这是我正在寻找的一线修复程序。但是也许可以解释像@shahbaz答案这样的裸机仓库 (3认同)

Now*_*man 42

摘要

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

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

尸检的问题

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

所以

A ? B
    ?
[HEAD,branch1]
Run Code Online (Sandbox Code Playgroud)

A ? B ? C
        ?
    [HEAD,branch1]
Run Code Online (Sandbox Code Playgroud)

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

A ? B ? X
    ?   ?
[HEAD] [branch1]
Run Code Online (Sandbox Code Playgroud)

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

      [HEAD]
        ?
        C
      ?
A ? B ? X
        ?
       [branch1]
Run Code Online (Sandbox Code Playgroud)

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


Ric*_*cky 20

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

$ git config core.bare true
Run Code Online (Sandbox Code Playgroud)


Ste*_*ggy 16

对我来说,以下是诀窍:

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

  • 与 git 存储库相比,我更喜欢这个本地版本:`git config receive.denyCurrentBranch updateInstead` (3认同)

小智 13

因为已经有一个现有的存储库,正在运行

git config --bool core.bare true
Run Code Online (Sandbox Code Playgroud)

在远程存储库上就足够了

来自core.bare文档

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

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


ken*_*orb 9

TLDR

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

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

通常你应该pull先得到最近的变化,push然后再来.

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

git push origin master:foo
Run Code Online (Sandbox Code Playgroud)

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

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

git config receive.denyCurrentBranch ignore
Run Code Online (Sandbox Code Playgroud)


Gil*_*oot 8

正如其他答案中提到的,您无法推送到已签出的分支。让我们从这里开始吧。

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

git checkout -b temp
Run Code Online (Sandbox Code Playgroud)

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

git push
Run Code Online (Sandbox Code Playgroud)

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

git config core.bare true
Run Code Online (Sandbox Code Playgroud)

现在您可以毫无问题地推送到远程。

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

git init --bare
Run Code Online (Sandbox Code Playgroud)