Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to have configurate a GIT repo for a website. Multiple users will have a clone of the repo on their local machine and on the end of each day they push their work to the server. I can setup a bare repo, but I want a working dir/non-bare repository.

The idea is that the working dir of the repository will the root folder for the website. At the end of each day all changes will be visible directly. But I can't find a way to do this.

Initializing the server repo with git init gives the following error when a client is trying to push some files:

git push origin master
orangetux@xxx.xxx.xxx.xxx's password: 
Counting objects: 3, done.
Writing objects: 100% (3/3), 227 bytes, done.
Total 3 (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: 
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 ssh://orangetux@xxx.xxx.xxx.xxx/home/orangetux/www/
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'ssh://orangetux@xxx.xxx.xxx.xxx/home/orangetux/www/'

So I'm wondering if this the right way to setup a GIT repo for a website? If so, how do I have to do this? If not, what is a better way to setup a GIT repo for the development of a website?


you can't push to a non-bare repository

Oke, clear. But whats the way to solve my problem? Create a bare repository on the server and have a clone of this repo on the same server in the htdocs folder? This looks a bit clumsy to me. To see the result of a commit I've to clone the repository each time.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

To see the result of a commit I've to clone the repository each time.

You don't have to re-clone, just git pull the newest changes each time.

To do this automatically, you just need to add the right commands to the <barerepo>/hooks/post-update hook in your bare repository.

  • Method A, website is a full clone of the main repository:

    git update-server-info
    if dir=$(git config hooks.checkoutTo); then
        for ref; do
            if [ "$ref" = "refs/heads/master" ]; then
                (unset GIT_DIR && cd "$dir" && git pull --quiet --ff-only)

    Tip: If both repos are in the same machine, use git clone --shared /path/to/bare to save space by reusing the bare repo's object directory.

    Note: There are possible security issues with method A – an outsider could just download the .git directory with your site's source code, if you do not move it to another location.

  • Method B, website is only a checkout:

    git update-server-info
    if dir=$(git config hooks.checkoutTo); then
        for ref; do
            if [ "$ref" = "refs/heads/master" ]; then
                # Must give a path (such as ".") to avoid switching HEAD.
                git --work-tree="$dir" checkout -f "$ref" -- .

For both hooks, run git config hooks.checkoutTo /var/www inside the bare repository (or edit the <barerepo>/config file manually) to set the target path.

Both hooks are written to only activate when the master branch is updated.

Make sure the hook file is executable (chmod +x). See githooks(5) for details.

Note: Technically you can push to a non-bare repository – Git will simply reject pushing to the currently checked-out branch (pushing to other branches is okay). Even this check can be disabled, but it's just an invitation for trouble... It is also much cleaner and better for backups to keep the bare repositories in a single directory (e.g. ~/srv/git or ~/Public/Git).

share|improve this answer
Could you explain both scripts? Although I know a little of Bash schripting I don't understand both scripts completely. –  OrangeTux Jul 8 '12 at 15:30
@OrangeTux: Partial explanation in gist.github.com/0ecc522ad43df4edba78 –  grawity Jul 9 '12 at 12:26

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.