I’ve been using git at work for the past few years and absolutely love it. I also use it for my home projects. In all cases I use Github to hosts the remote copies/versions of my projects. Github is a great service but when you have a free account (as I do for personal projects) your project will be public. However recently when I had some personal projects I didn’t necessarily want/care to make public as they were largely PoC or Hello World type projects but I still wanted to use version control. So I decided to set up my own remote git repository. This turned out to be not as I expected.
My initial understanding was that all git repositories for a project are the same. With that understanding I did the following:
- Created a local repo.
- On my server I created a new git repo.
- Made some changes on my local repo, set the remote origin as the repo on my server.
- Commit and push the changes to the server.
At this point I was surprised by an error message
$ git push origin master
Counting objects: 16, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (16/16), 4.17 KiB | 0 bytes/s, done.
Total 16 (delta 0), reused 0 (delta 0)
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: 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: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'email@example.com:/home/vagrant/Document/workspace/git-test'
As the error message says
By default, updating the current branch in a non-bare repository is denied, because it will make the index and work tree inconsistent with what you pushed, and will require ‘git reset –hard’ to match the work tree to HEAD.
To solve the problem I had to create the repo on the server using:
$ git init --bare
This created a repo with the following structure:
-rw-rw-r-- 1 vagrant vagrant 23 Dec 29 22:01 HEAD
drwxrwxr-x 2 vagrant vagrant 4096 Dec 29 22:01 branches/
-rw-rw-r-- 1 vagrant vagrant 66 Dec 29 22:01 config
-rw-rw-r-- 1 vagrant vagrant 73 Dec 29 22:01 description
drwxrwxr-x 2 vagrant vagrant 4096 Dec 29 22:01 hooks/
drwxrwxr-x 2 vagrant vagrant 4096 Dec 29 22:01 info/
drwxrwxr-x 4 vagrant vagrant 4096 Dec 29 22:01 objects/
drwxrwxr-x 4 vagrant vagrant 4096 Dec 29 22:01 refs/
As you can see this is very similar to what is in your local .git folder and stores the history and miscellaneous information and configuration for the repo.
Once I’ve done this then my push was successful. WIN!