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
hap@192.168.1.2'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://hap@192.168.1.2/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://hap@192.168.1.2/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?
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.
Using this to push it to the remote upstream branch solved this issue for me:
The remote had no access to the upstream repo so this was a good way to get the latest changes into that remote
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
always update the repositories by pull (or fetch and merge) or, if you have to,
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 movingHEAD
.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:
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 remoteorigin
and you're on branch master. Then you could doThen you need to merge it when you're in the
origin
remote repo: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
becomes
But if someone could push to that branch inbetween, the user would get itself in what git calls detached head mode:
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:
Hypothetically, if at this point, the user checks out another branch, then this dangling commit becomes fair game for Git's garbage collector.
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:
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:
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.
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"