Node.jsで動作するgitサーバー"git-server"を試す

以前Apache上で動作するgitサーバーの構築を試してみました。

Smart HTTPを使ってHTTPS経由でGitのリモートリポジトリへアクセスできるようにする

今回も「Apacheの使用を廃止してNode.jsに一本化する」作業の一環として、gitサーバーをNode.jsで構築する方法がないか探したところ、git-serverなるものを発見。どうやって動かすのか確認したときのメモを残す。

git-server https://www.npmjs.com/package/git-server

インストール

> npm install git-server

よくよく見ると、Node.jsのモジュールというよりも、gitサーバーを実現する為の本体ソース?のようです。git-serverをルートとしてすぐに実行できます。
プログラムの構成はexample.jsを本体としてhost.jsが内部でコールされている。

example.jsのソース

// Generated by CoffeeScript 1.6.1
var GitServer, repoOne, repoTwo, repos, _git;

GitServer = require('./host.js');

/*
	##Create example repo 1
	
	This repo does NOT allow Anonymous access
*/


repoOne = {
  name: 'stackdot',
  anonRead: false,
  users: [
    {
      user: {
        username: 'demo',
        password: 'demo'
      },
      permissions: ['R', 'W']
    }
  ]
};

/*
	##Create example repo 2
	
	This repo allows Anonymous reading (fetch,clone) access
*/


repoTwo = {
  name: 'anon',
  anonRead: true,
  users: [
    {
      user: {
        username: 'demo2',
        password: 'demo2'
      },
      permissions: ['R', 'W']
    }
  ],
  onSuccessful: {
    fetch: function() {
      return console.log('Successful fetch on "anon" repo');
    },
    push: function() {
      return console.log('Success push on "anon" repo');
    }
  }
};

repos = [repoOne, repoTwo];

/*
	#Create the GitServer object
	
		We are passing in `repos` array for the list of Repos we want to run  return
		We are passing in `true` to enable verbose logging  return
		We are passing in `/tmp/repos` to specify where the .git repos should live  return
		We are passing in `7000` for the port to run on ( port 80 requires sudo )
*/


_git = new GitServer(repos, true, '/tmp/repos', 7000);

サンプルでは、リポジトリを2個(stackdotとanon)を定義して、一番最後の処理で、/tmp/repos直下に上記2個のbareリポジトリを新規作成して、7000番ポートでhttpリクエストを待機する処理になっている。

> node example.js
LOG: Server listening on 7000

起動後、/tmp/reposを確認すると、bareリポジトリがちゃんと作成されている。

> ls /tmp/repos
stackdot  anon

もちろん2回目以降のサーバー起動のときはbareリポジトリが既にあるので、リポジトリを上書き作成してしまうことはない。

実際に動作するか確認する

ローカルディレクトリにgitリポジトリを作成して、サーバー上のstackdotにpushしてみる。

> mkdir repo1
> cd repo1
> git init repo1
Initialized empty Git repository in /work/repo1/.git/
> echo hello>memo.txt
> git add .
> git commit -m "release1"
[master (root-commit) 77a7df2] release1
 1 file changed, 1 insertion(+)
 create mode 100644 memo.txt
>
> git remote add origin http://demo:demo@localhost:7000/stackdot.git
> git push origin master:master
Counting objects: 3, done.
Writing objects: 100% (3/3), 213 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://localhost.com:7000/stockdot.git
 * [new branch]      master -> master

pushが成功すると、サーバープログラムexample.jsの以下のコールバックが発火してコンソールにログが表示されていれば動作していることが分かる。

 onSuccessful: {
    push: function() {
      return console.log('Success push on "anon" repo');
    }
  }

別の場所にcloneを作成してみる

> git clone http://demo:demo@localhost:7000/stackdot.git ./repo2
Cloning into ./repo2 ...
remote: Counting objects 3, done.
remote: Total 3 (delta0), reused 0 (delta 0)
Unpacking objects: 100% (3/3) done.
> cd repo2
> git log
commit 2c7cd897ds....
Autor: hoge <hoge@hoge.com>
Date: Fri May 13 21:30:31 2016 +0900

  release1
>

onSuccessfulにほかのイベントを追加すれば、各種ログが取れそうだが、必要なければリポジトリの定義を修正するだけで、とりあえず動作するようだ。
sslを使った送受信もできそうだが、今のところ未検証である。