Git Push error: refusing to update checked out branch
GitGit PushGit Problem Overview
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?
Git Solutions
Solution 1 - Git
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
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.
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 dirty working tree, which is not a safe operation anyway.
Solution 2 - Git
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.
Solution 3 - Git
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 head mode:
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:
[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.
Solution 4 - Git
For me, the following did the trick:
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.
First I shared the desktop's F drive on the network. Then I was able to clone it on my laptop by running:
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.
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.
Note that I ran all these commands from within Windows PowerShell, on both machines.
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
Solution 5 - Git
cd into the repo/directory that you're pushing into on the remote machine and enter
$ git config core.bare true
Solution 6 - Git
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).
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.
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.
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:
git config receive.denyCurrentBranch ignore
Solution 7 - Git
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
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).
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).
Solution 8 - Git
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.
Solution 9 - Git
As mentioned in other answers, you can not push to a checked-out branch. Let's start there.
From the remote server, Let's checkout our remote repository to a temporary branch.
git checkout -b temp
Now from our local repository, we can push to the master branch.
git push
But this is not a permanent solution. Future pushes will bring the same problem. To solve this once and for all, you need to turn the remote repository into a bare repository. From the remote server, enter:
git config core.bare true
Now you can push to the remote without any problems.
In future, create your remote repositories using the --bare
option like so:
git init --bare
Solution 10 - Git
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.
Solution 11 - Git
It's works for me
-
git config --global receive.denyCurrentBranch updateInstead
-
git push origin master
Solution 12 - Git
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.