#!/usr/bin/python # fusegit - use a git repo directly as a filesystem - python prototype # public domain )c( 2012, Sam Watkins # DONE: # - mount git HEAD readonly # # TODO: # - file modes # - cache directory # - stop using routefs, make it more efficient import routes import routefs import subprocess import sys import os from os import path import re class FuseGit(routefs.RouteFS): def __init__(o, *args, **kwargs): if not os.environ.get('GIT_DIR'): os.environ['GIT_DIR'] = path.realpath('.git') super(FuseGit, o).__init__(*args, **kwargs) def make_map(o): m = routes.Mapper() m.connect('/{pathname:.*}', controller='get') return m def get(o, pathname): git_pathname = 'HEAD:'+pathname proc = subprocess.Popen(['git', 'ls-tree', '-z', git_pathname], env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate() ; status = proc.returncode if err and err != 'fatal: not a tree object\n': err = re.sub(r'^fatal: ', '', err) sys.stderr.write(err) return None if status == 0: entries = [line.split('\t',2)[1] for line in out.split('\0')[:-1]] return entries else: proc = subprocess.Popen(['git', 'show', git_pathname], env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate() ; status = proc.returncode sys.stderr.write(err) if status == 0: return out else: return None if __name__ == '__main__': routefs.main(FuseGit)