serve a git repository over http
Bring your own git-{receive,upload}-pack implementations or shell out to the
system versions.
var http = require('http');
var spawn = require('child_process').spawn;
var path = require('path');
var backend = require('git-http-backend');
var server = http.createServer(function (req, res) {
    var repo = req.url.split('/')[1];
    var dir = path.join(__dirname, 'repos', repo);
    
    req.pipe(backend(req.url, function (err, service) {
        if (err) return res.end(err + '\n');
        
        console.log(service.action, repo, service.fields);
        
        var ps = spawn(service.cmd, service.args.concat(dir));
        ps.stdout.pipe(service.createStream()).pipe(ps.stdin);
        
    })).pipe(res);
});
server.listen(5000);first create a repo with git init and run the server:
$ mkdir repos
$ git init repos/falafel.git --bare -q
$ node server.js &
[1] 10685
now you can push at http://localhost:5000/falafel.git:
$ cd ~/projects/node-falafel
$ git push http://localhost:5000/falafel.git master
info falafel.git {}
push falafel.git { name: 'master',
  head: 'c1cb53f6dd18cc814f42c4205e8c7efef007c171',
  last: '008a0000000000000000000000000000000000000000',
  type: 'heads',
  branch: 'master' }
To http://localhost:5000/falafel.git
 * [new branch]      master -> master
and you can clone from http://localhost:5000/falafel.git too:
$ cd /tmp
$ git clone http://localhost:5000/falafel.git
Cloning into 'falafel'...
info falafel.git {}
pull falafel.git { head: 'c1cb53f6dd18cc814f42c4205e8c7efef007c171' }
remote: Counting objects: 247, done.
remote: Compressing objects: 100% (101/101), done.
remote: Total 247 (delta 139), reused 247 (delta 139)
Receiving objects: 100% (247/247), 55.40 KiB, done.
Resolving deltas: 100% (139/139), done.
var backend = require('git-http-backend')Return a duplex stream b from a request url req.url.
You should pipe an http request into b and pipe b into an http response,
like this:
http.createServer(function (req, res) {
    var b = backend(req.url);
    req.pipe(b).pipe(res);
})
If you pass in a cb, it will register an errback for the 'service' and
'error' events.
Return a writable side-band stream sb.
For info actions, you can write a response back to the user with this stream.
When the service header metadata has been parsed, this event fires. service is
a stream that outputs the request stream data from the remote git endpoint and
expects the git-{receive,upload}-pack data as input. You should wire up the
service has these handy properties:
- service.cmd- the git command name string
- service.args- the arguments array that the git command expects
- service.action- the type of request:- 'info',- 'tag',- 'push', or- 'pull'
- service.fields- the field data associated with the request action type
For 'info' actions, the service.fields is an empty object {}.
For 'pull' actions, the service.fields are:
- service.fields.head- the commit hash of the requested HEAD
For 'push' actions, the service.fields are:
- service.fields.last- the last commit in the commit payload range
- service.fields.head- the first commit in the commit payload range
- service.fields.branch- the branch name
For 'tag' actions, the service.fields are:
- service.fields.last- the last commit in the commit payload range
- service.fields.head- the first commit in the commit payload range
- service.fields.tag- the tag text
Handle errors here.
With npm do:
npm install git-http-backend
MIT