Ok, I have been struggling with version-control systems lately. More precisely with switching from svn to git. Subversion really was a pain in the butt. I spent more time on fixing my repositories and worrying about not introducing inconsistencies again, than on actual software development. This added to the horrible workflow of branching and merging, as well as the security nightmare of granting repository access to others, svn just turned out to be totally unsuited for my needs.
The one thing, I really liked about subversion, though, was it's documentation. Git has a lot to catch up here in my opinion and that brings me back to the topic of this blog post: surprisingly, I had trouble finding a recipe for my use case, which is odd, since it's not that exotic at all.
My scenario is as follows: I have a desktop computer, a notebook and a webserver at my disposal. I primarily do software development on the desktop computer, so thats where my main repositories are living. The webserver is used for publishing mirrored copies of my repositories and the notebook might eventually pull sources from there, so I can do work while being on the road.
Regarding the webserver, I have a few security constraints to consider:
- I have SSH access. My account is the only one on that machine. Nobody else is allowed to log into that server.
- I do not want to run git's own daemon. Repositories are to be served by Apache. The fewer ports that are open, the better.
- I have different versions of Git on my desktop, notebook and server. For the time being, I'll stick with that.
- People are allowed to pull from my public repositories, but nobody, except me, is allowed to push. Every patch to my source tree needs my approval first.
In short: I want to push from my desktop to my server via SSH and others may pull from there using HTTP. Web DAV is neither needed nor desired. When people want to submit their work, they can send me a patch file or let me pull from their own repositories. Either way, the updates go to my main repository on my desktop machine first and will be pushed to my server from there.
So much for the constraints. Now for setting things up. Since I do not intent to run git-daemon and have no need for Web DAV, configuring Apache boils down to simply adding a new virtual host and putting the repositories somewhere in it's document root. That's no problem so far.
The fun starts with initializing the repositories on the server. Since I use different versions of git on all my machines, simply copying files might not be the wisest choice, so it's best to use a git aware transport and clone from desktop to server. The command for that is (on the server):
$ cd /var/www/DOCUMENTROOT_OF_VIRTUAL_SERVER
$ git clone --bare ssh://uid@ip-address-of-desktop:port/path/to/my/repository
Mind the "--bare" parameter, which makes git create a bare repository (one, not having any source code checked out) and will therefore be the cause for further trouble. At this point, trying to download the repository from server to notebook, using HTTP will fail (SSH will work though):
$ git clone http://server.example.com/public_repo
Initialized empty Git repository in /tmp/public_repo/.git/
Cannot get remote repository information.
Perhaps git-update-server-info needs to be run there?
The error message is misleading however, since git-update-server-info will just complain about the repository not being a repository:
$ cd /var/www/DOCUMENTROOT_OF_VIRTUAL_SERVER/my_repository
$ git-update-server-info
fatal: Not a git repository
The trick here is to run git instead of git-update-server-info:
$ cd /var/www/DOCUMENTROOT_OF_VIRTUAL_SERVER/my_repository
$ git --bare update-server-info
After that, the bare repository can be cloned via HTTP. Of course, cloning a repository is only half of the story. The other half is being able to push from the desktop to the server via SSH and for this, the local repository has to be configured accordingly:
$ cd ~/my_repository
$ git remote add public_repo ssh://www-data@server.example.com:/var/www/DOCUMENTROOT
Last but not least, remember that update-server-info problem earlier? You get that one after every push (though this time, the client will just checkout an outdated version instead of complaining), when not running the command. Luckily, you do not have to run update-server-info manually, as git supports hooks. You just have to enable them:
$ cd /var/www/DOCUMENTROOT_OF_VIRTUAL_SERVER/my_repository/hooks
$ chmod +x post-update
You may have to modify that file to correctly call update-server-info (see above), though.
Similar posts
- Quick Drupal performance test: The Boost module makes a huge difference
- Suddenly becoming popular on Social Media websites - Drupal tips for surviving a traffic burst
- Unintentionally linking to a bad neighborhood - how to be taken for a ride by black hat SEO
- Protecting your website's content from deep linking, when using the Drupal CMS
- Linux tuning tips, that don't require you to buy new hardware

Delicious
Digg
StumbleUpon
Reddit
Facebook