node.jsの"git-http-backend"を試す

以前の投稿「Node.jsで動作するgitサーバー"git-server"を試す」で、
すでにgitサーバーは構築済みではあるが、あらためてnpmのサイトで
git関連のモジュールを検索すると、git-http-backendというモジュールが
ダウンロード数で勝っているいるので、構築したときの備忘録を残す。

モジュールのインストールとリモートリポジトリ作成

インストールはいつものコマンド

> npm install git-http-backend --save

テストとしてリモートリポジトリsample.gitを作成する

> mkdir /home/repos
> git init /home/repos/sample.git --bare -q

gitサーバープログラムの作成

README.mdにあるサンプルに対して、以下の修正をしたものを作成。

  1. リポジトリのルートディレクトリやポート番号を変数で指定
  2. 起動時のログ追加

'use strict';
var http = require('http');
var spawn = require('child_process').spawn;
var path = require('path');
var backend = require('git-http-backend');
var zlib = require('zlib');
 
var repo_root = "/home/repos";
var port = 3003;

var server = http.createServer(function (req, res) {
  console.log("git request : " + req.url);
  var repo = req.url.split('/')[1];
  var dir = path.join(repo_root, repo);
  var reqStream = req.headers['content-encoding'] == 'gzip' ? req.pipe(zlib.createGunzip()) : req;

  reqStream.pipe(backend(req.url, function (err, service) {
    if (err){
      return res.end(err + '\n');
    }

    res.setHeader('content-type', service.type);
    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);
});

console.log("-- start git-backend server --");
console.log("port : "+port);

server.listen(port);

プロキシ設定

直接このモジュールとは関係ないが、プロキシ環境下での必要な設定を残す。
外部URLへ接続が必要な場合は以下をconfig設定する。

> git config --global http.proxy http://[user]:[pass]@[host]:[port]
> git config --global https.proxy http://[user]:[pass]@[host]:[port]

が、これだけだと
locahostへの接続もプロキシを経由してしまって、ローカルリポジトリへの接続
ができなくなってしまう。一般にはno_proxyなる環境変数で回避できるらしいが、
gitでは動作しない。localhostへの接続をプロキシを通さないようにするには、
以下のように特定のリポジトリ接続時のhttp.proxyを無効にする。
(例では、ポート3003でgitサーバーを起動する場合)

[http "http://localhost:3003/"]
	proxy = ""
[https "http://localhost:3003/"]
  proxy = ""
[http]
	proxy = http://[user]:[pass]@[host]:[port]
[https]
	proxy = http://[user]:[pass]@[host]:[port]

サーバーの起動

さきほどのサーバープログラムを起動する

node app.js

動作確認

ローカル環境にリポジトリを作成し、push出来ることを確認する

> cd /home/projects/project1
> echo "test" > sample.txt
> git add sample.txt
> git commit -m "test"
> git push http://localhost:3003/sample.git master
Counting objects: 3, done.
Delta compression using up to 8 thread
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 283 bytes
Total 3 (delta 1), reused 0 (delta 0)
To http://localhost:3003/sample.git
   3fe2252..1517653  master -> master

ローカルの別ディレクトリで、上記リポジトリのクローンを作成できることを確認する

> cd /home/temp
> git clone http://localhost:3003/sample.git

少しハマッたこと

Windows版で最初にpushしたときにサーバーがエラー終了した。
メッセージを見て、git-receive-pack云々であれば、このモジュールへのパスが
通ってない可能性が高いので、環境変数PATHに[Install Path]\Git\mingw64\binを追加して解決した。
このモジュールがbackendモジュールをキックしていることが分かる。