Kikuchy's Second Memory

技術のこととか、技術以外のこととか、思ったことを書き留めています。

PHP で git を使うライブラリ "PHP-Git2" を CentOS 環境にインストールしてみた

PHP-Git2 は、PHP で git を使うためのライブラリです。
巷の PHP から git を使うためのライブラリと違うのは、git を外部プロセスとして実行しない事! PHP の中にモジュールとして組み込まれて、そこから実行されます。なので、外部プロセス呼び出しにまつわる面倒が無い、という訳です。素敵。



http://libgit2.github.com/images/libgit2/logo@2x.png



PHP-Git2 自体は、 libgit2 という「リンク可能で完全にクロスコンパイル可能」を謳うライブラリの PHPバインディングになっています。Ruby や Node.js など、他にも多くの言語のバインディングがあるので、用途に合わせて選ぶと良いでしょう。

この PHP-Git2CentOS 環境にインストールしようとした所、躓いたことがあったので、インストール方法と一緒に紹介します。

試した環境

  • CentOS 6.3(64bit)
  • git 1.7.1 導入済み
  • gcc 4.4.7 導入済み
  • PHP 5.3.3 導入済み

手順

1. 依存ライブラリの類をインストールする

PHP-Git2 は、 cmake, php-devel, pcre-devel に依存しているので、それぞれインストールしておきます。
以下のコマンドを実行します。

sudo yum install cmake
sudo yum install php-devel
sudo yum install pcre-devel

2. PHP-Git2 をビルドする

適当な作業ディレクトリ*1で、以下のコマンドを実行します。

git clone https://github.com/libgit2/php-git.git --recursive
cd php-git
git remote add patch https://github.com/workstars/php-git.git
git pull patch develop
cd libgit2
mkdir build && cd build
cmake ..
cmake -DBUILD_SHARED_LIBS=OFF -build .
make
cd ../../
phpize
./configure
make
# ちゃんとビルドできたかが心配なら、ここで make test を実行
sudo make install


一行ずつ実行してゆけば問題なく通ると思います*2
これで、PHP-Git2/usr/lib/php/modules/ (64bit 環境だと /usr/lib64/php/modules/)にインストールされました。

3. PHP から PHP-Git2 のモジュールを読み込むようにする

以下の内容を、 root 権限で /etc/php.d/git2.ini というファイルに保存します。

; Enable git2 extension module
extension=git2.so

Web アプリケーションなど、 Apache から PHP を実行するときにこの機能を使う場合は、 Apache を再起動します。

sudo /etc/rc.d/init.d/httpd restart

これで、 PHP から git を使えるようになりました。

4. 使ってみる

Web アプリケーションに組み込んだときに使えるかどうか、早速試しに使ってみましょう。
testgit.php に以下の内容を書き込みます。

<?php
date_default_timezone_set('Asia/Tokyo');
$path = "./writable/repotest";
$repo = Git2\Repository::init($path);

$content = "Hello, git";
$oid = Git2\Blob::create($repo, $content);

$author = new Git2\Signature("Kikuchy", "hoge@example.com", new DateTime());

$bld = new Git2\TreeBuilder();
$bld->insert(new Git2\TreeEntry(array(
	"name" => "hello.txt",
	"oid" => $oid,
	"attributes" => octdec('100644'),
)));
$tree = $bld->write($repo);

$parent = "";
$parents = array();
$parent = Git2\Commit::create($repo, array(
	"author"    => $author,
	"committer" => $author,
	"message"   => "initial commit",
	"tree"      => $tree,
	"parents"   => $parents,
));

この test.php と同じディレクトリに、 writable というディレクトリを作って、apache ユーザー/グループの書き込み権限を付与*3しておきます。
ブラウザから testgit.php にアクセスすると、 writable/repotest/ というディレクトリができているはずです。

cd writable/repotest/
git log	# "initial commit" というコメントのコミットがされていることがわかる
git cat-file blob aa5522f7cd3fd6a572cac43fa9e659dcbae8817d	# Hello, git と表示される

ワーキングツリーにファイルはありませんが、確かにリポジトリに文字列が書き込まれているのがわかります。
無事に動作確認できました。

所感

PHP のような手軽に扱えるスクリプト言語から git のリポジトリが扱える、ということは、自分が作る Web サービスに git の利点を活かした機能を取り込めるという事でもあるはずです。
git の利点と言えば、

  • バージョン管理
  • コミット間のコンクリフト検出
  • 分散管理


ですから、

  • バージョン管理機能付きファイルストレージ
  • 複数人で一つのドキュメントを編集するドキュメント編集アプリ
  • スタンドアロンのクライアントアプリケーションが存在する文章編集アプリ


などが実現できるという訳ですね。
アイデア次第で色々なものが作れそうです。



libgit2/php-git · GitHub

*1:例えば、 ~/tmp などのディレクトリを作って、そこを作業ディレクトリにするとか

*2:3, 4行目で、 libgit2/php-git 以外のリポジトリから pull していることが気になったかも知れません。 libgit2/php-git のリポジトリから clone してきたままでビルドすると、実行時に undefined symbol: git_index_get in Unknown on line 0 のエラーが出ます。これを修正したものが workstars/php-git に上がっていて、 libgit/php-git に pull request を出しているようです。が、未だに取り込まれていないので、ここでは自力でパッチをあてています

*3:パーミッションを777にしておけば、取り合えず試しに動かせます