I've always liked self hosting as it gives you the most flexability. With projects like [gitolite][1] you can ditch the heavy database, the server side scripting languages and run a nicely configured and feature rich server on something as small as a Raspberry Pi.
Gitolite supports gitweb, but when running on Debian it required me to install apache2, and configure CGI. Other distros I've tried were even worse with dependencies. All I want to is give public, read-only access via http. Can't be too difficult, right?
Every time the user interacts with their local and remote repos, a set of hooks are triggered. There are many local and remote hooks, which you can read about [here][2]. The hook we will be using is post-update
. It is called whenever a push occurs from local to remote repos, and after all refs are updated.
If you'd like to play along you can access the code:
$ git clone https://commentedcode.org/git/blog/gitolite-public-access.git \ /tmp/pub_access
The setup has two parts: Gitolite and your WebServer. Once its setup, you can easily enable this feature through your gitolite-admin repo. All the steps are assuming you're running the latest gitlote (v3). I've had it running on v2 just fine and the config wasn't much different.
The first file you'll need to edit is gitolite.rc
. If you followed the gitolite instructions for their basic setup, it will be in the home directory of your git user: $HOME/.gitolite.rc
You'll need to enable site-local code by uncommenting the following line. The default location works fine.
LOCAL_CODE => "$ENV{HOME}/local",
Next you'll need to enable Repo Specific Hooks. Uncomment the following line
# allow repo-specific hooks to be added 'repo-specific-hooks',
You can now create the directory to store the hooks. You can store any hooks you'd like to run, at any stage of the server side process. For this task we'll be creating a hook for the post-update phase of a commit.
user$ sudo su - git git$ mkdir -p $HOME/local/hooks/repo-specific
make-public Hook
The script is pretty simple. When a push is completed the hook will copy the server's contents to a directory that will be hosted via http. Anonymous users will be able to pull the code but won't be able to push anything.
#!/bin/sh # # Description: Creates HTTP R/O Repo when update is pushed # # Name of Repo REPO=$(echo $PWD | sed "s|$HOME/repositories/||") # Location of your repo on the server GIT_DIR=$HOME/repositories/$REPO # Location of your punblic version of the repo HTTP_DIR_BASE=$HOME/http HTTP_DIR=$HTTP_DIR_BASE/$REPO # Update local repo info git update-server-info # Make sure a clean copy is moved if [ -d $HTTP_DIR ] then rm -rf $HTTP_DIR fi mkdir -p $HTTP_DIR cp -rf $GIT_DIR/* $HTTP_DIR # Update index.html cd $HTTP_DIR_BASE ./gen-index.sh # Directories must have Read and Execute Permissions # for apache to be able to navigate them find $HTTP_DIR_BASE -type d -exec chmod a+rx {} \; # Files must have Read Permissions for apache # to be able to read them. find $HTTP_DIR_BASE -type f -exec chmod a+r {} \; # Change owner to git and web chown -R git:www-data $HTTP_DIR_BASE # Display a message on the client side to show # the action has been performed. echo "Updated Public Access"
Modify the script to match your locations. The copy it to your repo-specific directory.
git$ cp /tmp/pub_access/git/local/hoosk/repo-specific/make-public \ $HOME/local/hooks/repo-specific git$ chmod 755 $HOME/local/hooks/repo-specific/make-public
You'll need to create a directory that the git user can copy the git server files to that your web server will have access. The simplest way of doing this is making a directory in the git users's home and giving that user group access to web content. Since your git user can only be accessed via ssh keys, the security threshold is pretty low.
user$ sudo gpasswd -a git www-data user$ sudo su - git git$ mkdir $HOME/http
To give our service a little bit of a UI, we can automatically generate an index.html file every time the hook gets called. The file won't be fancy, just list our license defaults, how to access the repo and a list of all projects. You can modify it to add other features if you'd like.
git$ cp /tmp/pub_access/git/http/gen-index.sh $HOME/http git$ chown -R git:www-data $HOME/http git$ chmod 755 $HOME/http/gen-index.sh git$ $HOME/http/gen-index.sh git$ ls $HOME/http/ gen-index.sh index.html
Running the script we've created the index.html file, but it will not list any repos yet.
Server Configuration
I have included a snippet for nginx, but the concept works for all web servers. You want to point http://example.com/git
to /home/git/http
. With nginx its as easy as
server { ... location /git { alias /home/git/http; } }
The snippet included adds logging support and can be included in any virtual hosted setup.
server { ... include snippets/public-git-repo.conf; }
Restart your webserver and you should be able to access the index.html at
## Usage To use this hook you just need to add an option to any repo, or group of repos you want to be made public. Pull your gitolite-admin project and modify the gitolite.conf file.
repo blog/gitolite-public-access.git
RW+ = @devs
option hook.post-update = make-public
After every push (post update), your repo will run the make-public hook and generate the new static pages. The output from your push will actually printout the results from our hook, see the line "remote:"
user$ git push origin
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 935 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Updated Public Access
To commentedcode.org:testing.git
b813a96..e8b7e6b master -> master
Done
Once the public repo has been updated you'll be able to clone using http/https. **Private R/W Access:** git clone git@example.com:project.git **Public R/O Access:** git clone http://example.com/git/project.git ### Special Case: Adding to pre-existing repos If you are adding a new hook to a preexisting repo you'll need to run `gitolite setup` to have the hooks propogate. Otherwise, if you are adding a new repo this will occur automatically. Then you can run the hook manually to generate the output rather than waiting for the next push.
git$ gitolite setup
git$ cd repositories/gitolite-public-access.git
git$ $HOME/local/hooks/repo-specific/make-public
Updated Public Access
git$
text/gemini
This content has been proxied by September (ba2dc).