This blog post will describe how to setup a central repository where everybody pulls from and pushes to. This is actually the default work flow in Subversion.

Create a “git” user on your server.

sudo adduser git
nano /etc/group
git:x:1000:myusername,www-data,nobody
sudo mkdir /opt/git_projects
sudo chown git.git /opt/git_projects
sudo chmod 2770 /opt/git_projects
cd /opt/git_projects

Git has a naming convention that repositories that you share with others have a “.git” suffix. Local repositories have just a name.
To create a git bare (also called shared remote) repository do the following on the command line.

su git
mkdir example.git
chmod 770 example.git
cd example.git
umask 007
git init --bare
git config core.sharedrepository 1
git config receive.denynonfastforwards true
nano description // Set project name for example, this will be visible in Gitweb

The repository is successfully created! The “core.sharedrepository” flag tells git to keep everything group readable and writable. The “receive.denynonfastforwards” flag makes sure that merges can’t happen when you push to the repository.

Lets clone the repository to our local machine now.

git clone https://username@domain.com/git/example.git

or

git clone ssh://username@domain.com/git/example.git

If you want to use “https” (my preference) instead of the git protocol through “SSH” you have to add the following to your Apache 2 configuration:

SetEnv GIT_PROJECT_ROOT /opt/git_projects
SetEnv GIT_HTTP_EXPORT_ALL
#SetEnv GIT_SSL_NO_VERIFY

ScriptAliasMatch \
        "(?x)^/git/(.*/(HEAD | \
                info/refs | \
                objects/(info/[^/]+ | \
                [0-9a-f]{2}/[0-9a-f]{38} | \
                pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                git-(upload|receive)-pack))$" \
        /usr/lib/git-core/git-http-backend/$1

ScriptAlias /git/ /usr/lib/cgi-bin/gitweb.cgi

<Location /git>
        AuthType Basic
        AuthUserFile /opt/git_projects/.git_htpasswd
        AuthGroupFile /dev/null
        AuthName "Private Git Access"
        Require valid-user
</Location>

<Location /gitweb>
        AuthType Basic
        AuthUserFile /opt/git_projects/.git_htpasswd
        AuthGroupFile /dev/null
        AuthName "Private Git Access"
        Require valid-user
</Location>

Step into the project directory on your local machine:

cd example
nano .gitignore (nbproject, etc.)
git add .

I added the netbeans project folder “nbproject” to the git ignore list. Make sure you add some file to your “example” folder, and than add it to the staging area with “git add .”. If you don’t you’ll get errors below. Now execute the following:

git commit
git push origin master (for the first time, this will created a branch remote master branch)
git push (for the following times)

You’re done! You have a perfectly setup Git bare repository and a local clone that is tracking the repository for changes and updates.