up vote 2 down vote favorite
1
share [g+] share [fb]

Is there any way to serve files from branches in a git repo without checking them out into different directories?

I'd love the convenience of being able to create a new branch, push it to a test server repo and then do something like browse to http://branchname.test.com. I can use rewrite rules to handle branch name subdomain to point to different root paths but Apache can't read bare repos of course.

gitfs might work, but seems abandoned.

I don't especially need Apache either.

link|improve this question
1  
It is possible to read the ‘blob’s out of a repository without having a working tree (checkout). Tools like gitweb git.wiki.kernel.org/index.php/Gitweb serve primarily from bare repositories. Probably gitweb and its ilk offer more than you want, but maybe you could strip one down to just serve the bare files (git.kernel.org/?p=git/git.git;a=blob_plain;f=README) in a way where relative links would work. – Chris Johnsen Feb 2 '10 at 1:47
Interesting idea, but probably too much work atm. I'm trying to test branches of a Django app, so Python needs to be able to import modules from the repo, etc. – Van Gale Feb 2 '10 at 16:58
Except in the most basic scenarios (static content), serving general content with a web server does not require actual files. If what you wanted was a way provide normal access to files in a Git repository without actually creating real files (a virtual file system; an updated/maintained/working version of gitfs), then you probably should have left out all mentions of Apache, URLs, etc. – Chris Johnsen Feb 3 '10 at 12:32
feedback

1 Answer

up vote 1 down vote accepted

The simplest approach would be checking out each branch and creating clones for each branch in subdirectories. It's very easy to do that with a script runned by cron (or in a post-commit hook) like:

#!/bin/sh
ROOT=/srv/repos/control
cd ${ROOT} # it's an internal repo
git fetch
for ref in .git/refs/remotes/origin/*; do
  BRANCH=`basename ${ref}`
  if ! [ -d ../${BRANCH} ]; then
    git clone --local ${ROOT} ../${BRANCH}
    cd ../${BRANCH}
    git branch --track ${BRANCH} remotes/origin/${BRANCH}
    git checkout ${BRANCH}
  else
    cd ../${BRANCH}
    git pull
  fi
done

After it's work you will get a bunch of directories with branches in /srv/repos.

git clone --local is very fast and optimal even on huge repositories like Linux kernel because it does not create all the objects in repository but instead creates hardlinks to them, so you won't waste any space on repository copies. You will, through, waste space on checked-out copies, but a) they're probably not very big and b) this will make web-based access much easier and faster.

link|improve this answer
Thanks, this looks reasonable to implement. Hopefully I can find time in the next week to try it out :) – Van Gale Feb 2 '10 at 16:58
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.