246

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Funky
  • 12,890
  • 35
  • 106
  • 161
  • 3
    duplicated: http://stackoverflow.com/questions/2816369/git-push-error-remote-rejected-master-master-branch-is-currently-checked – cregox Oct 10 '12 at 12:44
  • 10
    You actually now have a secure way to push to a non-bare repo with Git 2.3.0 (February 2015) and `git config receive.denyCurrentBranch=updateInstead`:http://stackoverflow.com/a/28262104/6309 – VonC Feb 01 '15 at 12:37
  • Possible duplicate of [Git push error '\[remote rejected\] master -> master (branch is currently checked out)'](https://stackoverflow.com/questions/2816369/git-push-error-remote-rejected-master-master-branch-is-currently-checked) – Soerendip Jul 23 '18 at 17:16

14 Answers14

297

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.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • 1
    Yes! This is correct thank you! As I have about a million things to do, I accidently cloned the working directory....doh! – Funky Jun 20 '12 at 11:10
  • 36
    Actually, you can push to a non-bare repository just fine, you just can't push to the one branch that is **currently checked out**. – Nowhere man Feb 14 '13 at 15:18
  • @Nowhereman, that makes sense. But nevertheless, you either have a remote setup just for pushing, which you'd make bare anyway, or it's somebody's working clone, which you don't know which of their branches is checked out, and either way it's not nice to push to someone's working repository (they may be in the middle of something involving that branch). Thanks for the clarification though. – Shahbaz Feb 14 '13 at 21:01
  • 1
    There are dozens of other scenarios, actually. For example, some of my repositories are just on my workstation and my laptop (not code, but notes I take). On each I have two branches, "workstation" and "laptop". On the workstation, I only check out "workstation", and I only push to the "workstation" branch on the laptop (and vice-versa). – Nowhere man Feb 15 '13 at 16:50
  • 11
    You actually now have a secure way to push to a non-bare repo with Git 2.3.0 (February 2015) and `git config receive.denyCurrentBranch=updateInstead`:http://stackoverflow.com/a/28262104/6309 – VonC Feb 01 '15 at 12:36
  • I have initialized remote repo with `--bare` but still it is producing very same error. What should I do...? My remote repo is bare. – shashwat Feb 24 '15 at 09:48
  • If it is producing the very same error, i.e. saying specifically that you are pushing to a non-bare repository, then you repo is not bare. Try to verify that your remote is who you actually think it is (`git remote show origin`). If you are sure that your remote is bare, but git still complains that it's not bare, try asking another question as it may be a bug. Including your git version as well. – Shahbaz Feb 24 '15 at 12:30
  • "Bare repositories do not have a working copy and you can push to them. Those are the types of repositories you get in Github.." why then when I clone a github repo, the cloned config has `bare=false`? – Carol Skelly Jan 23 '16 at 17:17
  • 1
    @skelly Your clone is not bare, while the copy on github. So, while both clones have all the history, the copy on github doesn't have any commit checked out, but your copy does, to allow you to work! – Shahbaz Jan 23 '16 at 19:26
  • TLDR: `git config --bool core.bare true` – Sridhar Sarnobat Aug 20 '20 at 22:41
  • All these explanations and workarounds to force git to allow the push miss the fundemental question of WHY you are trying to do this in the first place. Chances are either a) the person that created the repo that you cloned from forgot to put --bare on it and the remote needs to be deleted+recreated (as was my case) or b) you cloned the wrong repo. IMO git should give you a giant warning when you do a clone saying "you are cloning a non-bare repo, are you really sure about this?" rather than waiting for you to try to do a push to blow up at you. – nigelg Nov 25 '22 at 13:41
  • @nigelg Since 2012 when I wrote this, I actually do work with clones of non-bare repositories and that's a perfectly valid scenario. Take open source repo X; project Y has X as a submodule, but you also want to have a checkout of X standalone. Some times I make the second clone directly from the source, then add the submodule copy as a remote. Sometimes I do a local clone from the submodule (non-bare) and add upstream as a remote. There's no reason why git should stop me from doing the latter – Shahbaz Mar 15 '23 at 22:19
146

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.

dotancohen
  • 30,064
  • 36
  • 138
  • 197
Sasha Pachev
  • 5,162
  • 3
  • 20
  • 20
54

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.

Nowhere man
  • 5,007
  • 3
  • 28
  • 44
  • I expanded a bit in http://stackoverflow.com/questions/2816369/git-push-error-remote-rejected-master-master-branch-is-currently-checked/14879452#14879452 – Nowhere man Feb 15 '13 at 16:52
32

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
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Stephen G Tuggy
  • 991
  • 10
  • 16
  • 4
    I prefer this local to the git repo: `git config receive.denyCurrentBranch updateInstead` – klor Jan 08 '20 at 11:24
25

cd into the repo/directory that you're pushing into on the remote machine and enter

$ git config core.bare true
Ricky Sahu
  • 23,455
  • 4
  • 42
  • 32
16

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).

Johnny
  • 276
  • 2
  • 6
15

TLDR

  1. Pull & push again: git pull &&& git push.
  2. Still a problem? Push into different branch: git push origin master:foo and merge it on remote repo.
  3. 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
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • Pushing a branch instead of to `master` worked for me. I had my local server check out a remote git repository and I checked it out from the local server. I'm fine with merging my branch to master on the server and then pushing it. +1 – NuclearPeon Sep 17 '20 at 01:39
7

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
Gilbert
  • 2,699
  • 28
  • 29
3

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.

JZAU
  • 3,550
  • 31
  • 37
1

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.

xastor
  • 482
  • 5
  • 17
  • 1
    In my situation, this was the case. Removing the `.git` folder on the remote allowed me to push the initial commit. – tim.rohrer Mar 02 '18 at 01:29
1

It's works for me

  1. git config --global receive.denyCurrentBranch updateInstead

  2. git push origin master

Prasenjit Mahato
  • 1,174
  • 15
  • 10
1

I has the same issue and try to do this:

  1. Ssh to gitlab server (remote server machine not your personal machine) and found [core]:bare value is false in yourRepo/.git/config

enter image description here

2. vim config and edit it to true Now,it's fine.I can push to master.

Simas Joneliunas
  • 2,890
  • 20
  • 28
  • 35
yuan zhu
  • 66
  • 3
0

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.

Nathan Chappell
  • 2,099
  • 18
  • 21
0

In another post's answer explain this problem. In my view, a better way to do is:

  1. For the repository in your remote server: git branch -b work, work is a working branch specially for remote server.
  2. Push your local commits to your remote server and local branch's name (dev) should be different from work to avoid mess up, and now no errors will appear for git push origin dev.
  3. Merge dev to work in your remote server. git merge.