Git push error '[remote rejected] master -> master (branch is currently checked out)'
Asked Answered
R

33

1060

Yesterday, I posted a question on how to clone a Git repository from one of my machines to another, How can I 'git clone' from another machine?.

I am now able to successfully clone a Git repository from my source (192.168.1.2) to my destination (192.168.1.1).

But when I did an edit to a file, a git commit -a -m "test" and a git push, I get this error on my destination (192.168.1.1):

git push                                                
[email protected]'s password: 
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error: 
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
error: 
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git+ssh://[email protected]/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://[email protected]/media/LINUXDATA/working'

I'm using two different versions of Git (1.7 on the remote and 1.5 on the local machine). Is that a possible reason?

Rubierubiginous answered 12/5, 2010 at 6:6 Comment(7)
Can any old-timer change the accepted answer to https://mcmap.net/q/11891/-git-push-error-39-remote-rejected-master-gt-master-branch-is-currently-checked-out-39 and move the thread to archive or something? Or change ownership or whatever?Faina
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:https://mcmap.net/q/11431/-what-is-this-git-warning-message-when-pushing-changes-to-a-remote-repositoryHatter
That's the new link of the book that @stigi has mentioned: git-scm.com/book/en/v1/Git-on-the-ServerGirlish
Possible duplicate of What is this Git warning message when pushing changes to a remote repository?Mincey
But I dint understand why and how it works ? Its' working ,Yes but that's All .Kakalina
Github is probably down.. check that too :)Verney
Delete the previous github credentials from machine. Solved: Git Remote - Reject ErrorNoelianoell
G
1220

The error message error: refusing to update checked out branch: refs/heads/master is emitted by the remote repository and it means you're trying to push code to remote non-bare repository that has different code currently checked out in the working directory. The best way to avoid this problem is to push to bare repositories only - this problem cannot ever happen with a bare repository.

You can simply convert your remote repository to bare repository (there is no working copy in the bare repository - the folder contains only the actual repository data).

Execute the following command in your remote repository folder:

git config --bool core.bare true

Then delete all the files except .git in that folder. And then you will be able to perform git push to the remote repository without any errors.

Gramicidin answered 14/7, 2010 at 22:45 Comment(22)
Thanks. I also needed this. I was following the submodules tutorial from the Git Community Book and hit this roadblock.Transubstantiation
I wasn't sure whether you meant to delete files on the server, or the client ... so I didn't delete anything, and the problem goes away after just doing git config --bool core.bare true. Is there any particular reason some files need to be deleted? If so, can you be more precise about what needs to be deleted?Warren
You FFFing ROCK sir! Thank you so much. I'm going to cross-link this answer to another question that didn't even come close to answering my problems.Quintet
@Brian: A bare repository is one with no working tree. Hence these files that formerly were part of the server's working tree will be in limbo after the repository is made bare. Try running commands like git add on the server to see how they are handled.Francophile
Aaah, i think git init undoes it and restores the working tree.Silken
It's the best possible answer and nobody else have provided it in the hole Interwebs. I think that we all googled the same error message and we all were extremely happy to read this.Sherard
Although it got a whole lot of votes, I don't think this is a really adequate answer to that specific question. Instructing the user how to cleanly create a bare repo would be half as bad, but what if the files need to stay checked out, for example when it's the repository the user is working with on two computers?Hifi
Changing the source repo to bare is overkill. All you need to do is push to a new branch in the source repo, as @Robert points out: https://mcmap.net/q/11891/-git-push-error-39-remote-rejected-master-gt-master-branch-is-currently-checked-out-39.Monogamy
Delete all files in that remote folder? You mean delete the entire site? I don't think so...Gulgee
@Titanium that's not what he means. A bare repo just contains the contents of the .git folder, while non-bare repos contain the .git folder itself, plus files checked-out into the working copy. There is really not many reasons where you would want your remote repo to have a working copy, in practice, so you can simply delete the working copy files, but keep .git, so that your remote becomes a bare repo.Fiction
Git documentation assumes you're Linus Torvalds and thus explains (or doesn't explain*) things accordingly. This is simple and right to the point. So thanks for that.Yearling
Should .gitignore be deleted from the remote repository folder as well, since it's outside of .git?Orthogenetic
So how will the site run without any files? O__OFearnought
The repository stays empty after doing that and pushing into it successfully.Truax
@Orthogenetic You can safely delete .gitignore. It's just another file that's tracked so it's contents are contained in .git somewhere assuming you committed it at some point.Gramicidin
Update for 2019: Even if the remote is a bare repository, the push can still be rejected if denyNonFastforwards=true under the [receive] section in the Git config file on the remote.Retire
Even in 2019, MacOS is still on 2.20.1, which means there is no receive section in git config. This answer, though, still works perfectly. Finally able to push to my remoteRaymond
I also needed to git config --unset core.bare after I was finished, otherwise I got an error when I ran git statu: "this operation must be run in a work tree"Publisher
The question is likely about 2 work repos: "from one of my machines to another"..=> Thus the answer here regarding a bare repo on server is probably off-topic. git config receive.denyCurrentBranch updateInstead is the way to go now for "twin" repos of one user. Or advanced, even in more dirty situations, when you know what you are doing: git config receive.denyCurrentBranch warn, + using git reset later on the twin after potentially clarifying index diff vs its previous parent in cases when the index staging status was "valuable" to preserve (git stash / rebase detached / temp branch).Adne
It might help those unfamiliar with bare repos to know what that means. A bare repo does not contain any working copies of the repo. That means there are no actual files stored there. Just the magical .git folder. So when a repo is turned into a bare repo it no longer keeps the files only the .git folder in it. Try converting your repo to a bare repo like @Gramicidin originally said. Then push. You'll see any new files you add are not there but they are recorded in the .git folder! Go to a new area and test it by cloning the repo again. You'll see your new files show up. Worked for me.Redford
@Adne this worked for me. I also don't think that a bare repo is a solution for this case. But why do I have to overcome such difficulties? If I create a repo on github and link it to my local machine then I can push to github origin without any problem. Why does github act differently?Dickdicken
After I run this command The connection between my project and git disconnected. I should not remove all files and folders without .git folder. Because I had some commits in a local branch which I could not publish to remote server because of the main issue [remote rejected]. Therefore I run git config --bool core.bare false and then everything worked successfully.Savage
T
772

I just had the same error while I began learning Git. Some of the other answers are clearly not for someone new to Git!

I am going to use non technical terms to get the idea across. Anyway, what is happening is that you have two repositories, one is the original you first made, and the other the work one you just made.

Right now you are in your work repository and are using the master branch. But you also happen to be "logged in" in your original repository to the same master branch. Now since you're "logged in" in the original, Git fears you might mess up because you might be working on the original and screw things up. So you need to return to the original repository and do git checkout someotherbranch, and now you can push with no problems.

Twelfth answered 29/5, 2010 at 3:26 Comment(16)
+1 Much more helpful, thank you Robert. I didn't make sense to convert to a bare repo in my case. Simply have to 'deactivate' the branch you're attempting to push to. Makes sense.Frisbie
Ok, but as both repository are on the same machine, what should I do ? I mean: how can I "log out" of the original git ? how can I "uncheckout" the origin repository ? I don't have any other branch yet, so I can git checkout anotherbranch.Rearrange
@FMaz008: just create a dummy branch (git checkout -b dummy)Stonecrop
Man this is far better than most voted answer :) Thanks. Although the other answer makes good point also :)Fetiparous
git checkout is completely different than svn checkout. git checkout is simply a "switch current" selector. Thanks for the informative answer Robert!.Tripedal
If we could get the original asker to accept your answer, it would show up at the top. It is a MUCH better answer than converting to a bare repo.Battiste
Just to make this clearer, in the repo that's the target of the push: git checkout -b tmp. Then in the source repo: git push. Then back in the target (optional): git checkout master; git branch -d tmpCaramelize
Hari's comment is the simplest recipe. I just have to say that while git may be great in many ways, coming from svn or probably any other rvs, this whole thing is stunningly non-intuitive.Thesis
I got around this by doing a pull from the other repository. Thanks for the explanation.Satellite
I find it stupid that I have to checkout another branch when I work with two repos I own. There should be an option to allow pushes on checked out branches.Andras
WOW 0_0 this is exactly the way to go !! Just checkout an other branch in the remote repo ! Thank a lotFoursome
@Andras There is, use pull instead instead of push like Mark recommended. Think of it like this: the user whose data is changing needs to explicitly accept those changes. If they execute git pull, that happens; whereas if some other user tries to force a git push and change the state of his/her files without permission, it fails (by default). That makes perfect sense.Lysozyme
I like to keep the repository directory in the dummy_branch. I then added an alias alias gitupdate='git checkout master ;git branch -D dummy_branch ;git checkout -b dummy_branch ;' Which I run whenever a push is made. That way it will always sit in dummy_branch that is most up to dateByzantine
What if I don't want to create a new branch? Is there any option to get out of the current branch (not being in/on any branch)? If I have a repo locally and its remote is set to a Bitbucket repo then I can just push from local, I don't need to pull from Bitbucket. So how this is working with Bitbucket? Am I not checked into any branch on Bitbucket?Flimflam
hi, after trying to get back to master branch in target repository i have some errors: error: The following untracked working tree files would be overwritten by checkout: public/.ftpquota do you know whats that means?Micco
On creating a new branch with git checkout -b tmp and then git branch -d tmp if you git branch you will see you are not in any branch. Maybe that means you are not 'logged onto' any branch - Interesting! Or does that mean something else?Emmet
F
132

The error message describes what has happened. More modern versions of Git refuse to update a branch via a push if that branch is checked out.

The easiest way to work between two non-bare repositories is either to

  1. always update the repositories by pull (or fetch and merge) or, if you have to,

  2. by pushing to a separate branch (an import branch) and then merging that branch into the master branch on the remote machine.

The reason for this restriction is that the push operation operates only on the remote Git repository, it doesn't have access to the index and working tree. So, if allowed, a push on the checked-out branch would change the HEAD to be inconsistent with the index and working tree on the remote repository.

This would make it very easy to accidentally commit a change that undoes all of the pushed changes and also makes it very difficult to distinguish between any local changes that have not been committed and differences between the new HEAD, the index and the working tree that have been caused by push moving HEAD.

Freighter answered 12/5, 2010 at 6:21 Comment(3)
Thanks. So how can I fix my problem? In my 192 box, i did '$ cd (project-directory) $ git init $ (add some files) $ git add .' and then in my 191 box, I did a 'git clone ' and edit some files and than try to 'git push'.Rubierubiginous
Well, I described the possibilities in my answer. Either you can go to the 192 box and fetch from the 191 box (you might want to add the 191 box as a named remote - look at git remote add box191 <191url> ), or you can push from the 191 box to an alternatively named branch (e.g. git push origin master:refs/heads/upload ), then to the 192 box and merge (e.g. git merge upload ).Freighter
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:https://mcmap.net/q/11431/-what-is-this-git-warning-message-when-pushing-changes-to-a-remote-repository: you don't need option 2 anymore.Hatter
H
127

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.

There are multiple solutions, depending on your needs.

Solution 1: Use a Bare Repostiory

As suggested, if on one machine, you don't need the working directory, you can move to a bare repository. To avoid messing with the repository, you can just clone it:

machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo

Now you can push all you want to the same address as before.

Solution 2: Push to a Non-Checked-Out Branch

But if you need to check out the code on your remote <remote>, then you can use a special branch to push. Let's say that in your local repository you have called your remote origin and you're on branch master. Then you could do

machine2$ git push origin master:master+machine2

Then you need to merge it when you're in the origin remote repo:

machine1$ git merge master+machine2

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.

Hifi answered 14/2, 2013 at 16:28 Comment(5)
One technical correction to "autopsy": git won't actually detach HEAD in the pushed-to repository. HEAD will still point to the branch, and the branch will in turn point to the new commit(s) pushed; but the working directory and index/staging-area will be unmodified. Whoever is working on the pushed-to repository now has to work hard to recover from the effects of the push: figure out whether there are any changes to save, and if so carefully arrange to save them.Zilla
To add additional information to your answer, there are very few reasons why you would want a remote repository that people push to to be non-bare, so using a bare repository is the best solution.Fiction
Actually, I found many situations when I need to push to a non-bare repository, and I use the solution 2 quite a lot. Also, the branch where I push on the non-bare repository is in no way a temporary branch, it serves a similar purpose as a remote tracking branch.Hifi
I created a GIT folder in my server which will host ALL repositories created by multiple users using SourceTree. I created a master repositories in my local PC. I added the remotes to the server folder and trying to push my repository into the server so another user can pull/fetch it to work on. I get the following error: ! [remote rejected] master -> master (branch is currently checked out) How can I check it in?Barnette
@SearchForKnowledge, do you realize you're asking exactly the question I'm answering to?!Hifi
P
69

You can get around this "limitation" by editing the .git/config on the destination server. Add the following to allow a git repository to be pushed to even if it is "checked out":

[receive]
denyCurrentBranch = warn

or

[receive]
denyCurrentBranch = false

The first will allow the push while warning of the possibility to mess up the branch, whereas the second will just quietly allow it.

This can be used to "deploy" code to a server which is not meant for editing. This is not the best approach, but a quick one for deploying code.

Penetration answered 16/12, 2010 at 5:17 Comment(9)
Using this to "deploy" code to a server won't work. Even if you disable the warning so you can push to the checked out branch, the working copy is NEVER updated on a push.Gleiwitz
I'm using the above method with cd .. && git reset --hard post-receive hook to deploy. Hackish, but works.Mattheus
the command line version of the latter would be git config receive.denyCurrentBranch warnDrenthe
This should be the accepted answer. Some of us know what we're doing and are not Git beginners. This is the answer for those people.Vivl
Ha, but the question was not asked byt those people.Hifi
Instead of using hacks such as denyCurrentBranch = false you should convert the remote repo as bare repo. Then the whole issue cannot happen anymore.Williemaewillies
This is the correct answer for the question. @MikkoRantalainen This is what is necessary to make the repo push successful, which is useful for automation and hosting webpages via git. The story about why push to current branch is restricted is useful for beginners though.Ford
THANK YOU, @MikkoRantalainen! All these other replies were completely confusing me, as they seem to suggest that I'm somehow checking something out incorrectly. Actually, the problem was with how I created the remote repository in the first place. You should make this an answer in its own right.Decoupage
@Decoupage the top-voted answer to this question already says that the remote repository should be converted to bare repo and even provides the command to do that. Was there something missing from that answer that you think should be added?Williemaewillies
D
59

git config --local receive.denyCurrentBranch updateInstead

https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

Use that on the server repository, and it also updates the working tree if no untracked overwrite would happen.

It was added in Git 2.3 as mentioned by VonC in the comments.

I've compiled Git 2.3 and gave it a try. Sample usage:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Output:

a
b

Yay, b got pushed!

Datnow answered 7/2, 2015 at 14:57 Comment(10)
Does this have any problems with commiting changes that are not up to date with the server?Byzantine
@Byzantine I'm not sure what you mean, if you commit locally before pulling, it will behave exactly as a traditional --bare clone I think: --force is required to push, and it will make you "lose" commits on the remote.Datnow
@CiroSantilli新疆改造中心六四事件法轮功 No worries now. I looked up the meaning of the options. I thought that updateInstead was synonymous with force.Byzantine
updateInstead is no longer a valid value for receive.denyCurrentBranchLatonya
@Xalorous do you have a reference? github.com/git/git/blob/…Datnow
I type the command, git gives the error "invalid value for receive.denyCurrentBranch"Latonya
@Xalorous what's your git version? I can't reproduce on 2.18.Datnow
That explains it. I'm limited to RHEL repos (long story) and ours is 1.8.3.1. I resolved by converting the repo to a bare repo and reconfiguring it as a remote repo accessed via an NFS share. (remote repo through a local path). My overall goal was to allow another admin access to a repo of Ansible plays. With core.bare=yes, I can run through your test.Latonya
@Xalorous OK! Yes, many new git features keep coming, always check your version ;-)Datnow
This answer should be #1. I been going in circles for 3 days now, this finally solved my problem; Thank you!Pleven
P
46

I like the idea of still having a usable repository on the remote box, but instead of a dummy branch, I like to use:

git checkout --detach

This seems to be a very new feature of Git - I'm using git version 1.7.7.4.

Pappose answered 14/2, 2012 at 20:37 Comment(1)
And then after pushing your changes, you can use: git checkout master to get back to the master branch. It's only then that your changes are being applied.Tewfik
F
31

I had the same issue. For me, I use Git push to move code to my servers. I never change the code on the server side, so this is safe.

In the repository, you are pushing to type:

git config receive.denyCurrentBranch ignore

This will allow you to change the repository while it's a working copy.

After you run a Git push, go to the remote machine and type this:

git checkout -f

This will make the changes you pushed be reflected in the working copy of the remote machine.

Please note, this isn't always safe if you make changes on in the working copy that you're pushing to.

Fritzfritze answered 27/1, 2011 at 0:42 Comment(2)
thanks a log, I merge you suggestion denyCurrentBranch and put git checkout -f inside hooks folder like @jack-senechal posted hereTerrarium
Is there a way to make the files appear on the Remote repository without going to it and doing this command? Namely by a command from the local?Cradling
A
25

You can recreate your server repository and push from your local branch master to the server master.

On your remote server:

mkdir myrepo.git
cd myrepo.git
git init --bare

OK, from your local branch:

git push origin master:master
Arvo answered 7/2, 2011 at 8:22 Comment(2)
Thanks this was the solution for me as I had omitted '--bare' on remote server. It seems that answers to this question depend on whether you are using the remote server repo as a working directory or not and for the later case this is the correct answer.Inflated
I don't understand :S I tried to create and clone a bare repo, but clone downloaded nothing and push uploaded nothing, so this is not working... :-) I read tutorials about bare repos, but they saying that a bare repo contains no files... That's definitely not what I'm looking for...Lani
K
25

What you probably did to cause this:

This kind of thing happens when you go to bang out a little program. You're about to change something which was already working, so you cast your level-3 spell of perpetual undoability:

machine1:~/proj1> git init

and you start adding/committing. But then, the project starts getting more involved and you want to work on it from another computer (like your home PC or laptop), so you do something like

machine2:~> git clone ssh://machine1/~/proj1

and it clones and everything looks good, and so you work on your code from machine2.

Then... you try to push your commits from machine2, and you get the warning message in the title.

The reason for this message is because the git repo you pulled from was kinda intended to be used just for that folder on machine1. You can clone from it just fine, but pushing can cause problems. The "proper" way to be managing the code in two different locations is with a "bare" repo, like has been suggested. A bare repo isn't designed to have any work being done in it, it is meant to coordinate the commits from multiple sources. This is why the top-rated answer suggests deleting all files/folders other than the .git folder after you git config --bool core.bare true.

Clarifying the top-rated answer: Many of the comments to that answer say something like "I didn't delete the non-.git files from the machine1 and I was still able to commit from machine2". That's right. However, those other files are completely "divorced" from the git repo, now. Go try git status in there and you should see something like "fatal: This operation must be run in a work tree". So, the suggestion to delete the files isn't so that the commit from machine2 will work; it's so that you don't get confused and think that git is still tracking those files. But, deleting the files is a problem if you still want to work on the files on machine1, isn't it?

So, what should you really do?

Depends upon how much you plan to still work on machine1 and machine2...

If you're done developing from machine1 and have moved all of your development to machine2... just do what the top-rated answer suggests: git config --bool core.bare true and then, optionally, delete all files/folders other than .git from that folder, since they're untracked and likely to cause confusion.

If your work on machine2 was just a one-time thing, and you don't need to continue development there... then don't bother with making a bare repo; just ftp/rsync/scp/etc. your files from machine*2* on top of the files on machine*1*, commit/push from machine*1*, and then delete the files off of machine*2*. Others have suggested creating a branch, but I think that's a little messy if you just want to merge some development you did on a one-time basis from another machine.

If you need to continue development on both machine1 and machine2... then you need to set things up properly. You need to convert your repo to a bare, then you need to make a clone of that on machine1 for you to work in. Probably the quickest way to do this is to do

machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1

Very important: because you've moved the location of the repo from proj1 to proj1.git, you need to update this in the .git/config file on machine2. After that, you can commit your changes from machine2. Lastly, I try to keep my bare repos in a central location, away from my work trees (i.e. don't put 'proj1.git' in the same parent folder as 'proj1'). I advise you to do likewise, but I wanted to keep the steps above as simple as possible.

Kimberleekimberley answered 12/5, 2016 at 21:7 Comment(2)
Very detailed and helpful. My case was the last one, and your instructions worked like a charm.Scissor
I'm in case 3 and I did something slightly different: mk git-server; mv .git git-server/proj.git and then git clone git-server/proj.git to both 1 and 2 (or git remote origin ...), using a proper ssh:// prefix for machine 2. This way I'll keep a bare master copy which will be like the one normally on GH or other HTTP server and I'll keep using push/pull on both machines.Clubman
P
19

With a few setup steps you can easily deploy changes to your website using a one-liner like

git push production

Which is nice and simple, and you don't have to log into the remote server and do a pull or anything. Note that this will work best if you don't use your production checkout as a working branch! (The OP was working within a slightly different context, and I think @Robert Gould's solution addressed it well. This solution is more appropriate for deployment to a remote server.)

First you need to set up a bare repository somewhere on your server, outside of your webroot.

mkdir mywebsite.git
cd mywebsite.git
git init --bare

Then create file hooks/post-receive:

#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

And make the file executable:

chmod +x hooks/post-receive

On your local machine,

git remote add production [email protected]:mywebsite.git
git push production +master:refs/heads/master

All set! Now in the future you can use git push production to deploy your changes!

Credit for this solution goes to http://sebduggan.com/blog/deploy-your-website-changes-using-git/. Look there for a more detailed explanation of what's going on.

Pentateuch answered 15/10, 2012 at 18:16 Comment(1)
Your suggestion helped me a lot, but I didn't use bare, I follow this and merge with hooks (that you suggested) and worked perfectly.Terrarium
A
15

You should only be pushing to a bare repository. A bare repository is a repository that has no checked out branches. If you were to cd to a bare repository directory, you'd only see the contents of a .git directory.

Ajar answered 12/5, 2010 at 6:9 Comment(3)
There's nothing wrong with pushing to a non-checked out branch in a non-bare repository. This is a perfectly valid way of working.Freighter
Fair enough, that would work. But that is not what the user is doing.Ajar
It's not the fact that he isn't using a bare repository that is 'wrong'; it is the fact that he is pushing to a checked out branch. There is no evidence that he has or wants a separate bare repository so your blanket statement that he should only be pushing to a non-bare repository is not giving the asker all the options; one of which might more easily solve his immediate problem.Freighter
C
13

Check your .git/config in the destination project:

$ cat .git/config 
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[receive]
    denyCurrentBranch = updateInstead

If the core. bare is false, you can set it to true:

$ git config core.bare true

and then in your local push to remote:

git push remote_repo   // suppose the destination repo is remote_repo

it will success, in the remote_repo you can check git version.

$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < [email protected]>
Date:   Thu May 17 21:54:37 2018 +0800

and now you can not use git in your "workspace":

$ git status
fatal: This operation must be run in a work tree

you should set bare.bare back to false.

$ git config core.bare false
Curare answered 18/5, 2018 at 2:54 Comment(1)
What protection in being overridden when I do this?Demandant
L
10

You have 3 options

  1. Pull and push again:

    git pull; git push
    
  2. Push into different branch:

    git push origin master:foo
    

    and merge it on remote (either by git or pull-request)

    git merge foo
    
  3. Force it (not recommended unless you deliberately changed commits via rebase):

    git push origin master -f
    

    If still refused, disable denyCurrentBranch on remote repository:

    git config receive.denyCurrentBranch ignore
    
Lampion answered 30/9, 2015 at 15:40 Comment(1)
Option 2 work for me. remote git init local git push origin master:branch remote git merge DONEGlede
I
7

In fact, set the remote to a non-checked out branch is sufficient. After you checked out your remote in a different branch, you can push.

Isabelisabelita answered 11/12, 2010 at 15:3 Comment(0)
G
5

I had the same problem using Git to synchronise repositories on my Android phone and laptop. The solution for me was to do a pull instead of a push, as @CharlesBailey suggested.

git push origin master on the Android repository fails for me with the same error messages that @hap497 got because of a push to a nonbare checkout of a repository + working-copy.

git pull droid master on the laptop repository and working-copy works for me. Of course, you need to have previously run something like git remote add droid /media/KINGSTON4GB/notes_repo/.

Gourd answered 15/4, 2012 at 4:29 Comment(0)
R
5

Older versions of Git used to allow pushes to the currently checked out branch of a non-bare repository.

It turns out this was a terribly confusing thing to allow. So they added the warning message you see, which is also terribly confusing.

If the first repository is just acting as a server then convert it to a bare repository as the other answers recommend and be done with it.

If however you need to have a shared branch between two repos that are both in use you can achieve it with the following setup

Repo1 - will act as the server and also be used for development

Repo2 - will be for development only

Setup Repo1 as follows

Create a branch to share work on.

git branch shared_branch

To be safe, you should also create a $(REPO).git/hooks/update that rejects any changes to anything other than shared_branch, because you don't want people mucking with your private branches.

repo1/.git/hooks  (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"

if [ "${refname}" != "refs/heads/shared_branch" ]
then
   echo "You can only push changes to shared_branch, you cannot push to ${refname}"
   exit 1
fi

Now create a local branch in repo1 where you will do your actual work.

git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch 'my_work'

(may need to git config --global push.default upstream in order for git push to work)

Now you can create repo2 with

git clone path/to/repo1 repo2 
git checkout shared_branch 

At this point you have both repo1 and repo2 setup to work on local branches that push and pull from shared_branch in repo1, without needing to worry about that error message or having the working directory get out of sync in repo1. Whatever normal workflow you use should work.

Rosenfeld answered 27/10, 2014 at 21:28 Comment(0)
H
3

OK, in case you want a normal remote repository, then create an extra branch and check it out. Push it into one branch (which is not checked out) and merge it with one which is currently active later after pushing from locally.

For example, on a remote server:

git branch dev
git checkout dev

On the local setup:

git push 

On remote server:

git merge dev
Havelock answered 31/1, 2013 at 15:28 Comment(0)
M
2

Here is one test you can do to see how the bare server stuff work:

Imagine you have a workstation and a server with live site hosted on it, and you want to update this site from time to time (this also applies to a situation where two developers are sending their work back and forth through a bare middleman).

Initialization

Create some directory on your local computer and cd into it, then execute these commands:

# initialization
git init --bare server/.git
git clone server content
git clone server local
  1. First you create a bare server directory (notice the .git at the end). This directory will serve as a container for your repository files only.
  2. Then clone your server repository to a newly created content directory. This is your live/production directory which will be served by your server software.
  3. The first two directories resides on your server, the third one is a local directory on your workstation.

Workflow

Now here is the basic workflow:

  1. Enter the local directory, create some files and commit them. Finally push them to the server:

    # create crazy stuff
    git commit -av
    git push origin master
    
  2. Now enter the content directory and update the server's content:

    git pull
    
  3. Repeat 1-2. Here content may be another developer that can push to the server too, and local as you may pull from him.

Miscreance answered 18/7, 2012 at 12:59 Comment(0)
C
2

Using this to push it to the remote upstream branch solved this issue for me:

git push <remote> master:origin/master

The remote had no access to the upstream repo so this was a good way to get the latest changes into that remote

Crystacrystal answered 5/10, 2018 at 15:48 Comment(1)
More generally (as this is the net effect of the command), using git push <remote> master:newbranch. The idea is that you push a new branch to the remote, which can then be merged in. This way you avoid any of the inconsistency issues mentioned in the error message.Tarrasa
U
1

An article I found that might be useful to others is Git in 5 minutes.

I had an Xcode project under Git version control that I wanted to push up to a Virtual Distributed Ethernet (VDE) I have in a DC. The VDE runs Centos 5.

None of the articles I read about Git talked about bare repositories. It all sounded so simple until I tried what I thought should be easy coming from an SVN background.

The suggestions here to make the remote repository bare worked. Even better for my requirements was to clone the Xcode project to projectname.git, copy that to the remote server; then pushes magically worked. The next step will be getting Xcode to push without errors about commits, but for now I'm okay doing it from Terminal.

So:

cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git [email protected]:repos/<br/>

To push changes from your Xcode project after you've committed in Xcode:

cd /xcode-project-directory<br/>
git push [email protected]:repos/projectname.git<br/>

I'm certain there is a smoother more sophisticated way of doing the above, but at a minimum this works. Just so everything is clear, here are some clarifications: /xcode-project-directory is the directory your xcode project is stored in. It's probably /Users/Your_Name/Documents/Project_Name. projectname is literally the name of the project, but it can be anything you care to call it. Git doesn't care, you will.

To use scp you need to have a user account on the remote server that's allowed SSH access. Anyone running their own server will have this. If you're using shared hosting or the like, you might be out of luck.

remotehost.com is the name of your remote host. You could as easily use its IP address. Just for further clarity I'm using Gitosis on the remote host with SSH keys, so I'm not prompted for passwords when I push. The article Hosting Git Repositories, the Easy (and Secure) Way tells you how to set all that up.

Unpleasant answered 16/3, 2012 at 12:18 Comment(1)
Your link was dead classic.scottr.org/presentations/git-in-5-minutesWagonette
M
1

The best way to do this is:

mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/

This will clone the repository, but it won't make any working copies in .../remote. If you look at the remote, you'll see one directory created, called currentrepo.git, which is probably what you want.

Then from your local Git repository:

git remote add remoterepo ..../remote/currentrepo.git

After you make changes, you can:

git push remoterepo master
Maestricht answered 2/9, 2012 at 23:55 Comment(0)
M
1

I had to re-run git --init in an existing bare repository, and this had created a .git directory inside the bare repository tree - I realized that after typing git status there. I deleted that and everything was fine again :)

(All these answers are great, but in my case it was something completely different (as far as I can see), as described.)

Misconduct answered 6/9, 2012 at 19:9 Comment(0)
K
1

I'm sure most people viewing this question will stop at the first two huge answers, but I'd still like to offer my solution.

I had an Eclipse + EGit web project setup when encountering the described error. What helped me was simply using the GitHub app, which seemed to magically resolve the issue. While EGit would always refuse the push, the GitHub desktop app would just shrug its shoulders and push my changes. Maybe it handles the multi-login-situation more gracefully.

Kyongkyoto answered 6/5, 2013 at 20:33 Comment(0)
C
1

I just ran into this problem with a deployment git repository on Heroku.

I don't know why Heroku has a non-bare repository on their side, but as a workaround I was able to reset the remote repository, and reupload.

You shouldn't use Heroku's copy of your repository as your only git repository for collaboration, but just in case, I'll say clearly: Do not do this unless you are sure you have a full copy of your repository stored securely somewhere other than Heroku. Doing a reset will delete the repository contents.

To reset:

  1. Install the Heroku toolbelt (which contains the command line client) if you haven't already.
  2. Install the heroku-repo plugin if you haven't already.

    heroku plugins:install https://github.com/heroku/heroku-repo.git
    
  3. Do the reset, which deletes the repository and creates a new, empty one

    heroku repo:reset
    
  4. Push to your Heroku remote as you normally would; it will reupload everything.

Congreve answered 11/9, 2014 at 19:24 Comment(1)
You may need to install the Heroku repo tools for this to work. Do heroku plugins:install https://github.com/heroku/heroku-repo.gitSomnolent
F
1

You will need to change the config file on the remote server once you have created empty(bare) repository, say

root@development:/home/git/repository/my-project# cat config 

there you will see

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

You will make this bare to false to true and I removed logallrefupdates = true (not sure of its use!)

to

[core]
repositoryformatversion = 0
filemode = true
bare = true

You may test following

$ git remote show origin
* remote origin
Fetch URL: my-portal@development:/home/XYZ/repository/XYZ
Push  URL: my-portal@development:/home/XYZ/repository/XYZ
HEAD branch: (unknown)

This HEAD branch: (unknown) will be shown if you are unable to PUSH. So if the HEAD branch is unknow, you should change bare to true and after push successful you can reuse the

git remote show origin

and you will see

 HEAD branch: master
Flautist answered 11/9, 2015 at 13:18 Comment(0)
D
1

If you are using SSH key to connect into github, make sure that your SSH key is still there under your profile settings. For some reason, my key was cleared there and I couldn't push to my master branch. What I did is I just added my SSH key to settings/SSH keys again.

enter image description here

Command to view your existing key: cat ~/.ssh/id_rsa.pub

Dispenser answered 27/3, 2023 at 13:41 Comment(0)
B
0

For me working solution is:

ON REMOTE:

git checkout -b some_tmp_name

ON LOCAL:

git push

ON REMOTE:

git checkout master
git branch -d some_tmp_name

But this is not the real solution it's just workaround.

Barouche answered 28/6, 2014 at 14:10 Comment(1)
This a valid solution if you don't have a central repository.Boulevard
B
0

Just in case someone finds it useful. For me it was a git server permissions issue. I checked out the project from the beggining and push a simple file and then I got the "Push rejected: Push to origin/master was rejected"

Bourbon answered 19/6, 2015 at 6:27 Comment(0)
D
0

Let me add my 50 cents, because the most voted answer https://mcmap.net/q/11891/-git-push-error-39-remote-rejected-master-gt-master-branch-is-currently-checked-out-39 suggests a converting of remote repw to a bare repository, and what if it's not what I want?

In the end I have to have the same code on the remote machine but not just blobs of bytes somewhere in .git limbo.

The second-voted (as of this writing) solution https://mcmap.net/q/11891/-git-push-error-39-remote-rejected-master-gt-master-branch-is-currently-checked-out-39 does the job but after testing this out I ended up having to constantly switch between branches on the remote machine to "free" the branch I want to push from my local machine to.

This worked for me:

Another solution that worked for me so far is not mine, credit is given to a user @kxr who commented on the first solution.

On the remote machine you have to make this command in the repo directory.

git config receive.denyCurrentBranch updateInstead

After this you are done!

Obviously, there might be some drawbacks of this solution but for a simple task of synchronizing your local machine code to your remote repo it's probably good enough.

I would be grateful if someone explaines in comments why it's totally fine to create a brand new repo on github, link your local folder to it and start doing git push origin master without errors.

But trying to make this same thing with the repo on the remote server yields and error:

! [remote rejected] master -> master (branch is currently checked out)

Dickdicken answered 17/11, 2022 at 20:27 Comment(1)
Because on github, it's a bare repo, and theare no working tree.Extradition
R
-1

With Git, two regular (non-bare) repositories can't push/pull files back and forth directly. There must be an intermediary bare repository. Apparently, it's sort of like a married couple who have a kid, and the couple is getting divorced. The parents won't talk to each other, but they will communicate through the kid.

So, you have one repository, you clone this repository to a bare repository, and then you clone that to a third. The first and the third can exchange information via the second repository, the bare one. I guess this makes sense, as you wouldn't want someone able to check stuff into your repository without your consent, as that could cause merge conflicts & the like.

So, here's an example:

On PC, in ~/workspace

git init
echo "line 1" > afile.txt
git add .
git commit -m ‘initial import’
git clone --bare . ../remote-repository.git
git remote add origin ../remote-repository.git
git push --set-upstream origin master

On laptop, in ~/workspace (do not do git init, etc.)

git clone //LJZ-DELLPC/remote-repository.git/ .

// Then make various commits, and push them:

echo "line 2" > afile.txt
git add afile.txt
git commit -m 'added line 2'
git push    

Then back on PC, in ~/workspace

git pull

// Then make various commits, and push them:

git push

On laptop git pull

and so forth..

Here's an absolute concrete example all on one machine, copied straight from the command window, so that we'll know that no steps were left out, that it really did work, etc:

lylez@LJZ-DELLPC ~
$ cd gitdir
/home/lylez/gitdir

lylez@LJZ-DELLPC ~/gitdir
$ ls

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1
/home/lylez/gitdir/repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git init
Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 1" > afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'initial import'
[master (root-commit) f407e12] initial import
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git clone --bar . ../repo1-bare-clone
Cloning into bare repository '../repo1-bare-clone'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git remote add origin ../repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push --set-upstream origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ..

lylez@LJZ-DELLPC ~/gitdir
$ ls
repo1  repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1-remote

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1-remote
/home/lylez/gitdir/repo1-remote

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git clone ../repo1-bare-clone .
Cloning into '.'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ echo "line 2" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git commit -m 'added line 2'
[master 5ad31e0] added line 2
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   f407e12..5ad31e0  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cd ../repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../repo1-bare-clone
   f407e12..5ad31e0  master     -> origin/master
Updating f407e12..5ad31e0
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 3" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'added line 3'
[master 3fa569e] added line 3
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../repo1-bare-clone
   5ad31e0..3fa569e  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ../repo1-remote/

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   5ad31e0..3fa569e  master     -> origin/master
Updating 5ad31e0..3fa569e
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
line 3

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git --version
git version 2.1.1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
Rms answered 18/10, 2014 at 20:43 Comment(12)
It's an example of what works, and an explanation of why. There is no misinformation here at all, except for your comment.Rms
"With Git, two regular (non-bare) repositories can't push/pull files back and forth directly" - Except that they can.Rosenfeld
Fine, post a concrete example instead of an attack.Rms
Or you could google it ? stackoverflow.com/questions/1764380/…Rosenfeld
The first response in the thread you site begins with, "... but according to git ready and the official git wiki, you should only push to a bare repo.". The next response states, "If you want to try just pushing master -> master, then the command is just: git push origin", and that simply does not work, and there are a zillion postings to that affect. The last response begins with, "I would suggest to have a bare-repository and a local working (non-bare) repos in your server.", which is exactly what I proposed.Rms
No one is saying that pushing to a checked out branch on a non-bare remote is a good idea, although it is possible. Quoting out of context is poor form.Rosenfeld
Again, a concrete example.Rms
I'm happy to answer but I'm not clear at all on what your question is, or how it isn't answered by other posters already. How to push a ref that is checked out by the remote? How to push any other branch? What's a viable work flow for 2 engineers to do this without having a bare repo in between?Rosenfeld
Do exactly what I did in my concrete example which was copied straight from a command window without modifications, but do it without using bare repositories.Rms
Done. Should be enough info for anyone to duplicateRosenfeld
It is not done! Next time you're about to flame someone's perfectly good posting, make sure you know what you're talking about.Rms
I have no idea what you are talking about nowRosenfeld
S
-2

I ran into this issue when I had cloned a repo on my NAS and then cloned that repo on to my machines.

The set up is something like this:

ORIGINAL (github):

  • cloned to network storage in my private home network (my home network)
    • branch checked out: DEVELOPMENT
  • cloned to other machines (laptops, small data center server in my office, etc)
    • branch checked out: DEVELOPMENT

When I tried to commit to the from the laptop to the NAS server the error which comes up is

! [remote rejected]   development -> development (branch is currently checked out)

The root cause is that DEVELOPMENT branch is checked out on the NAS server. My solution was on the NAS repository to switch to any other branch. This let me commit my changes.

Silvio answered 2/2, 2021 at 18:26 Comment(0)
R
-3

My solution (in use)

  1. Checkout "master" on remote server
  2. Work locally on "dev" branch
  3. Push changes to remote dev
  4. Merge dev into master on remote

bingo

Raviv answered 15/9, 2013 at 0:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.