Oct 29, 2012
So you have a Git repository running on a server and you want to have public access via http but you don't feel like installing some fancy Git web service. We can use some built-in features of Git to generate our web-access output, toss in a little nginx or lighttp and we have a super simple setup.
First step is to create a location where we will store our read-only repo.
Depending on your servers setup, you'll need to make sure that the user
connecting to Git has access to write here. On my server all my users have
$HOME/html that converts to
When you initialize a repository directory on your server a couple of files
and directories are created. Most are the paperwork to keep the whole
version control thing working but the ones we want are contained in the
hooks directory. Reading through the documentation on hooks we
find that there is a plethora of cases when a transaction between a Git
client and server including before and after applying a patch, a commit,
a checkout or a merge.
So the next step is to create your repository, initialize, check-in, etc. Once you have your repo working we can go in and edit our hook. Remember, this is on the server side and not in your local instance of the repo.
~/git/proj.git> ls HEAD description info refs config hooks objects
We want to create a hook that updates our web access whenever changes are
applied to the server. For this we will edit
post-update which will be
triggered any time a client performs a
git push to the server. Makes
sense. The job of this script is to copy the git server's files to our
web server, do a little clean up and exit out gracefully. So here we go...
#!/bin/sh # # File: ~/git/proj.git/hooks/post-update # # Description: Called when an update is pushed to the server # # Location of your repo on the server GIT_DIR=/home/jecxjo/git/proj.git # Location of your public version of the repo HTTP_DIR=/home/jecxjo/html/devel/proj.git # Update local repo info git update-server-info # Make sure a clean copy is moved rm -rf $HTTP_DIR cp -rf $GIT_DIR $HTTP_DIR chgrp -R nobody $HTTP_DIR # Directories must have Read and Execute Permissions # for apache to be able to navigate them. for d in `find $HTTP_DIR -type d`; do chmod a+rx $d done # Files must have Read Permissions for apache # to be able to read them. for f in `find $HTTP_DIR -type f`; do chmod a+r $f done # Display a message on the client side to show # the action has been performed. echo "Updated Public Access"
For the most part the comments are self explanatory. We start by making
sure our server's copy of the repo is all clean and tidy using
git update-server-info. Next we clear out our web directory, copy,
change permissions, etc.
NOTE You may have to do a little bit of permissions work here depending on your web server.
The last line is actually kind of interesting. Whatever is printed by the
script is displayed by the client after a
git push. For the moment we
will just print that our public access has been updated, but all sorts
of information could be printed here.
Last step is to make sure the script can run.
chmod a+x ~/git/proj.git/hooks/post-update
You can run the script directly from your terminal or perform a push to get your site updated.
$ git push Counting objects: 5, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 256 bytes, done. Total 3 (delta 1), reused 0 (delta 0) remote: Updated Public Access To jecxjo@server:git/proj.git e60a9de..1f8a43f master -> master $
We see the line
remote: Updated Public Access which tells us that our
hook executed. Thats how we get public and private access. Very easy,
no 3rd-party services, just git...plain and simple.
Private: git clone jecxjo@server:git/proj.git
Public: git clone http://jecxjo.server/devel/proj.git