Git Push 错误:拒绝更新签出的分支
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11117823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git Push error: refusing to update checked out branch
提问by Funky
I have solved some merge conflicts, committed then tried to Push my changes and received the following error:
我已经解决了一些合并冲突,提交然后尝试推送我的更改并收到以下错误:
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'
Does anyone know what could be causing this error?
有谁知道是什么导致了这个错误?
回答by Shahbaz
Reason:You are pushing to a Non-Bare Repository
原因:您正在推送到非裸存储库
There are two types of repositories: bare and non-bare
有两种类型的存储库:裸和非裸
Bare repositories do not have a working copy and you can push to them. Those are the types of repositories you get in Github! If you want to create a bare repository, you can use
裸存储库没有工作副本,您可以推送到它们。这些是您在 Github 中获得的存储库类型!如果你想创建一个裸仓库,你可以使用
git init --bare
So, in short, you can't push to a non-bare repository(Edit: Well, you can't push to the currently checked out branch of a repository. With a bare repository, you can push to any branch since none are checked out. Although possible, pushing to non-bare repositories is not common). What you can do, is to fetch and merge from the other repository. This is how the pull request
that you can see in Github works. You ask them to pull from you, and you don't force-push into them.
因此,简而言之,您不能推送到非裸存储库(编辑:嗯,您不能推送到存储库的当前检出分支。使用裸存储库,您可以推送到任何分支,因为没有被检出。虽然可能,但推送到非裸存储库并不常见) . 您可以做的是从另一个存储库中获取和合并。这就是pull request
您在 Github 中看到的工作方式。你要求他们从你身边拉开,而不是强行推入他们。
Update: Thanks to VonC for pointing this out, in the latest git versions (currently 2.3.0), pushing to the checked out branch of a non-bare repository is possible. Nevertheless, you still cannot push to a dirtyworking tree, which is not a safe operation anyway.
更新:感谢 VonC 指出这一点,在最新的 git 版本(当前为 2.3.0)中,可以推送到非裸存储库的检出分支。尽管如此,您仍然无法推送到脏工作树,这无论如何都不是安全的操作。
回答by Sasha Pachev
I solved this problem by first verifying the that remote did not have anything checked out (it really was not supposed to), and then made it bare with:
我通过首先验证那个遥控器没有检查任何东西(它真的不应该检查)来解决这个问题,然后让它裸露:
$ git config --bool core.bare true
After that git push worked fine.
在那之后 git push 工作正常。
回答by Nowhere man
Summary
概括
You cannot push to the one checked out branch of a repository because it would mess with the user of that repository in a way that will most probably end with loss of data and history. But you can push to any other branch of the same repository.
您不能推送到存储库的一个检出分支,因为它会以一种很可能以丢失数据和历史记录而告终的方式干扰该存储库的用户。但是您可以推送到同一存储库的任何其他分支。
As bare repositories never have any branch checked out, you can always push to any branch of a bare repository.
由于裸存储库永远不会检出任何分支,因此您始终可以推送到裸存储库的任何分支。
Autopsy of the problem
问题的解剖
When a branch is checked out, committing will add a new commit with the current branch's head as its parent and move the branch's head to be that new commit.
当一个分支被检出时,提交将添加一个以当前分支的头作为其父级的新提交,并将该分支的头移动到该新提交。
So
所以
A ← B
↑
[HEAD,branch1]
becomes
变成
A ← B ← C
↑
[HEAD,branch1]
But if someone could push to that branch inbetween, the user would get itself in what git calls detached headmode:
但是如果有人可以推送到中间的那个分支,用户就会进入 git 所谓的分离头模式:
A ← B ← X
↑ ↑
[HEAD] [branch1]
Now the user is not in branch1 anymore, without having explicitly asked to check out another branch. Worse, the user is now outside any branch, and any new commit will just be dangling:
现在用户不再在 branch1 中,而没有明确要求签出另一个分支。更糟糕的是,用户现在在任何分支之外,任何新的提交都将悬而未决:
[HEAD]
↓
C
↙
A ← B ← X
↑
[branch1]
Hypothetically, if at this point, the user checks out another branch, then this dangling commit becomes fair game for Git's garbage collector.
假设,如果此时用户签出另一个分支,那么这个悬空提交对于 Git 的垃圾收集器来说就变成了公平的游戏。
回答by Ricky
cd into the repo/directory that you're pushing into on the remote machine and enter
cd 进入您在远程机器上推送的 repo/目录并输入
$ git config core.bare true
回答by Stephen G Tuggy
For me, the following did the trick:
对我来说,以下是诀窍:
git config --global receive.denyCurrentBranch updateInstead
git config --global receive.denyCurrentBranch updateInstead
I set up drive F:, almost in its entirety, to sync between my Windows 10 desktop and my Windows 10 laptop, using Git. I ended up running the above command on both machines.
我设置了驱动器 F:,几乎完整地使用 Git 在我的 Windows 10 桌面和我的 Windows 10 笔记本电脑之间同步。我最终在两台机器上运行了上述命令。
First I shared the desktop's F drive on the network. Then I was able to clone it on my laptop by running:
首先我在网络上共享了桌面的F盘。然后我可以通过运行在我的笔记本电脑上克隆它:
F:
git clone 'file://///DESKTOP-PC/f'
F:
git clone 'file://///DESKTOP-PC/f'
Unfortunately, all the files ended up under "F:\f\" on my laptop, not under F:\ directly. But I was able to cut and paste them manually. Git still worked from the new location afterwards.
不幸的是,所有文件最终都在我的笔记本电脑上的“F:\f\”下,而不是直接在 F:\ 下。但我能够手动剪切和粘贴它们。之后,Git 仍然在新位置工作。
Then I tried making some changes to files on the laptop, committing them, and pushing them back to the desktop. That didn't work until I ran the git config command mentioned above.
然后我尝试对笔记本电脑上的文件进行一些更改,提交它们,然后将它们推回桌面。直到我运行上面提到的 git config 命令,这才起作用。
Note that I ran all these commands from within Windows PowerShell, on both machines.
请注意,我在两台计算机上从 Windows PowerShell 中运行了所有这些命令。
UPDATE: I still had issues pushing changes, in some cases. I finally just started pulling changes instead, by running the following on the computer I want to pull the latest commit(s) to:
更新:在某些情况下,我仍然遇到推动更改的问题。我终于开始拉取更改,通过在我想拉取最新提交的计算机上运行以下命令:
git pull --all --prune
git pull --all --prune
回答by Johnny
As there's already an existing repository, running
由于已经有一个现有的存储库,运行
git config --bool core.bare true
on the remote repository should suffice
在远程存储库上就足够了
From the core.bare documentation
来自 core.bare 文档
If true (bare = true), the repository is assumed to be bare with no working directory associated. If this is the case a number of commands that require a working directory will be disabled, such as git-add or git-merge (but you will be able to push to it).
如果为 true (bare = true),则假定存储库是裸的,没有关联的工作目录。如果是这种情况,许多需要工作目录的命令将被禁用,例如 git-add 或 git-merge(但您将能够推送到它)。
This setting is automatically guessed by git-clone or git-init when the repository is created. By default a repository that ends in "/.git" is assumed to be not bare (bare = false), while all other repositories are assumed to be bare (bare = true).
创建存储库时, git-clone 或 git-init 会自动猜测此设置。默认情况下,以“/.git”结尾的存储库被假定为非裸(bare = false),而所有其他存储库都被假定为裸(bare = true)。
回答by kenorb
TLDR
TLDR
- Pull & push again:
git pull &&& git push
. - Still a problem? Push into different branch:
git push origin master:foo
and merge it on remote repo. - Alternatively force the push by adding
-f
(denyCurrentBranch
needs to be ignored).
- 再次拉动:
git pull &&& git push
。 - 还是有问题?推入不同的分支:
git push origin master:foo
并将其合并到远程仓库中。 - 或者通过添加
-f
(denyCurrentBranch
需要被忽略) 来强制推送。
Basically the error means that your repository is not up-to-date with the remote code (its index and work tree is inconsistent with what you pushed).
基本上该错误意味着您的存储库与远程代码不是最新的(它的索引和工作树与您推送的不一致)。
Normally you should pull
first to get the recent changes and push
it again.
通常,您应该pull
首先获取最近的更改,push
然后再次获取。
If won't help, try pushing into different branch, e.g.:
如果没有帮助,请尝试推入不同的分支,例如:
git push origin master:foo
then merge this branch on the remote repository back with master.
然后将远程存储库上的这个分支与 master 合并。
If you changed some past commits intentionally via git rebase
and you want to override repo with your changes, you probably want to force the push by adding -f
/--force
parameter (not recommended if you didn't do rebase
). If still won't work, you need to set receive.denyCurrentBranch
to ignore
on remote as suggested by a git message via:
如果您有意通过 via 更改了一些过去的提交,git rebase
并且想用您的更改覆盖 repo,您可能希望通过添加-f
/--force
参数来强制推送(如果您没有这样做,则不推荐rebase
)。如果仍然不起作用,您需要按照 git 消息的建议设置receive.denyCurrentBranch
为ignore
远程:
git config receive.denyCurrentBranch ignore
回答by JZAU
Maybe your remote repo is in the branch which you want to push. You can try to checkout another branch in your remote machine. I did this, than these error disappeared, and I pushed success to my remote repo. Notice that I use ssh to connect my own server instead of github.com.
也许您的远程仓库位于您要推送的分支中。您可以尝试在远程机器上签出另一个分支。我这样做了,然后这些错误消失了,我把成功推到了我的远程仓库。请注意,我使用 ssh 连接我自己的服务器而不是 github.com。
回答by xastor
I has this error because the git repo was (accidentally) initialised twice on the same location : first as a non-bare repo and shortly after as a bare repo. Because the .git folder remains, git assumes the repository is non-bare. Removing the .git folder and working directory data solved the issue.
我有这个错误,因为 git repo 被(意外地)在同一个位置初始化了两次:首先是一个非裸仓库,不久之后又是一个裸仓库。因为 .git 文件夹仍然存在,git 假定存储库是非裸的。删除 .git 文件夹和工作目录数据解决了这个问题。
回答by Nathan Chappell
I got this error when I was playing around while reading progit. I made a local repository, then fetched it in another repo on the same file system, made an edit and tried to push. After reading NowhereMan's answer, a quick fix was to go to the "remote" directory and temporarily checkout another commit, push from the directory I made changes in, then go back and put the head back on master.
我在阅读 progit 时玩弄这个错误。我创建了一个本地存储库,然后在同一文件系统上的另一个存储库中获取它,进行编辑并尝试推送。阅读 NowhereMan 的回答后,快速修复是转到“远程”目录并临时签出另一个提交,从我进行更改的目录推送,然后返回并将头放回 master。