3

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
[email protected]'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://[email protected]/home/orangetux/www/
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'ssh://[email protected]/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?

I've seen you can't push to a non-bare repository, but how does it 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.

2 Answers 2

4

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:

    #!/bin/sh
    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)
            fi
        done
    fi
    

    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:

    #!/bin/sh
    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" -- .
            fi
        done
    fi
    

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).

1
  • Could you explain both scripts? Although I know a little of Bash schripting I don't understand both scripts completely.
    – OrangeTux
    Commented Jul 8, 2012 at 15:30
0

[remote rejected] master -> master

It's rejected by remote, so make sure your repo which you're pushing is up-to-date by pulling and pushing again:

git pull; git push

If still refused, try pushing into different branch first:

git push origin master:foo

so the repo owner can merge your branch.

If you did some changes to commits via rebase, then you probably want to force it via -f.

Alternatively disable denyCurrentBranch on remote via (not recommended):

git config receive.denyCurrentBranch ignore

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .