1

I have a git repo on a remote linux box and another repo on a windows machine.

I would like to:

  • checkout a branch from the linux machine
  • work on it locally(from my windows machine)
  • commit locally
  • then push to the remote branch.

That's what i do:

At Linux (remote)

  #currently on master branch
  git checkout -b remote_trunk
  #currently on remote_trunk branch

At Windows (locally)

  git fetch origin 
  git checkout remote_trunk
  #currently on remote_trunk branch
  # then I modify some files
  git commit -a -m"I modified some files"
  git push origin remote_trunk 

Result

Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 432 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/remote_trunk
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 Z:/shadow.git/ets/src/trunk/src
 ! [remote rejected] remote_trunk -> remote_trunk (branch is currently checked out)
error: failed to push some refs to 'Z:/shadow.git/ets/src/trunk/src'
Florian Neumann
  • 5,587
  • 1
  • 39
  • 48
Kam
  • 5,878
  • 10
  • 53
  • 97
  • 2
    Possible duplicate of [Git push error '\[remote rejected\] master -> master (branch is currently checked out)'](http://stackoverflow.com/questions/2816369/git-push-error-remote-rejected-master-master-branch-is-currently-checked) –  May 16 '14 at 19:11
  • Kam, in Cupcake's reference, see the answers posted by Charles Bailey and the 'Autopsy' in the answer by Nowhere Man for a good explanation. – jkyako May 16 '14 at 19:22
  • I added the receive.denyCurrentBranch option, and I push with -f option, that works. But at the remote end I would need to stash to see the changes! it seams that push -f replaces the last commit but keeps the old files in the current directory... – Kam May 16 '14 at 19:56

2 Answers2

2

By default git will disallow a push to a non-bare repository.

When you push to the remote server, you are updating its branch refs which can lead to some confusion if you have changes in the remote repo's working directory. You can avoid that confusion by:

  • Your best bet is to set up a separate bare repository and push from both development areas to the shared repo. check git help init and the --bare option.
  • only perform git fetch/pulls between the two repos (and no git pushes)
  • you can set the 'receive.denyCurrentBranch' variable as the warning suggests. This will allow the push but is not the recommended option unless you know what you're doing and are careful.
  • it sounds from the warning that it will allow the push as long as the remote Linux repository doesn't currently have remote_trunk checked out. So on the remote repo, you could check out a different branch (eg, in your case git checkout master) or checkout a detached state (git checkout --detached) while you are doing git pushes from the local repo, and then after pushing you can git checkout remote_trunk on the remote repository without it silently clobbering your index.

The short story: Avoid pushes to non-bare repositories -- prefer git pull to incorporate changes into them. If you want to git push to a common area, set up a bare repository with git init --bare

jkyako
  • 616
  • 4
  • 6
  • Thank you for your reply.... But I would like to be able to work on both repos....Isn't that possible? if I make the remote repo bare then I wouldn't be able to work on it correct? – Kam May 16 '14 at 19:08
  • Correct. You might try doing a `git checkout master` on the remote Linux repo during periods where you expect to be pushing from your Windows repo (or at least, that's what I'm taking from the error message). Or you could set the 'receive.denyCurrentBranch' on the Linux repo to allow the push but I'd shy from that. – jkyako May 16 '14 at 19:16
  • I like Don's suggestion best of creating a third (bare) repo and using that as a clearinghouse for the two dev areas. – jkyako May 16 '14 at 19:17
  • I added the receive.denyCurrentBranch option, and I push with -f option, that works. But at the remote end I would need to stash to see the changes! it seams that push -f replaces the last commit but keeps the old files in the current directory... – Kam May 16 '14 at 19:57
  • Right -- that's why git has these safeguards in place. When you push to the remote server, you are updating its branch refs which can lead to some confusion if you have changes in the remote repo's working directory. You can avoid that confusion by: - using a separate bare repository and pushing from both development areas to the shared bare repo - only performing git fetch/pulls between the two repos (and no git pushes) - or on the remote repo, checking out a different branch while you are doing git pushes from the local repo. – jkyako May 16 '14 at 20:32
  • 1
    The shorter story: Avoid pushes to non-bare repositories -- prefer `git pull` to incorporate changes into them. If you want to `git push` to a common area, set up a bare repository with `git init --bare`. – jkyako May 16 '14 at 20:36
  • Please Update your answer with everything you mentioned above, as they were helpful so I accept the answer and finalize this question :) – Kam May 16 '14 at 21:27
  • Updated the answer with some copy/pastes from the comment thread. Glad to help – jkyako May 18 '14 at 22:40
1

It looks like your remote repository is not a bare repository, and it needs to be. When you create it, use:

git init --bare
Don Branson
  • 13,631
  • 10
  • 59
  • 101
  • Thank you for your reply.... But I would like to be able to work on both repos....Isn't that possible? if I make the remote repo bare then I wouldn't be able to work on it correct? – Kam May 16 '14 at 19:05
  • No, but you could either do as @jkyako suggests, or create a second clone on the same host as the bare repo. I do the latter. – Don Branson May 16 '14 at 19:14
  • I added the receive.denyCurrentBranch option, and I push with -f option, that works. But at the remote end I would need to stash to see the changes! it seams that push -f replaces the last commit but keeps the old files in the current directory... – Kam May 16 '14 at 19:58
  • BTW - you don't have to post the same comments on each question. We'll all see them. :) – Don Branson May 16 '14 at 20:01
  • I won't do that anymore :) – Kam May 16 '14 at 21:29
  • No worries, just trying to help. :) – Don Branson May 16 '14 at 23:58