argius note

プログラミング関連

MacOSX上のGit共有リポジトリをHTTPSで公開してWindowsで使う

タイトルにはありませんが、「プロキシ経由」という条件もあります。
ほぼお手本通りの手順でできたものの、いくつかつまずいた箇所がありました。


まずは、環境について。

  • サーバー
  • クライアント
    • Windows7 Professional 32bit
    • Git 1.7.11 (msysgit)

前置き

普通にHTTP接続するだけなら、公式サイトのお手本(Smart HTTP Transport (Git公式サイト))のとおりに"SmartHTTP"を使って構築すれば使えるようになります。
また、他にも検索すればそれなりに情報は見つかります。


この記事は、以下の条件に重点を置いて説明したものです。

  • サーバー側がMacOSX
  • HomeBrewでGitをインストール
  • HTTPS+PROXY経由のリモート接続

余談−最近のGit

個人的な話です。
今メインで使っているVCSはSubversion(SVN)です。HTTP経由でEclipseから使うのが簡単だったのが採用の理由です。
Gitについては、これまでもEGit(EclipseのGitプラグイン)を介しての単純なオペレーションで利用することはありましたが、理解して使っているとは言えない状況でした。


SVNの不満もあったので、Gitへの移行の機会をうかがっていました。一方Gitは、EGitも不完全で、Windowsサポートがあまり十分とは言えませんでした。


最近はWindowsのツールも充実&安定してきましたし、ドキュメントも日本語の情報が増えてきました。
英語でもなんとか読めないことはありませんが、時間がかかるし分からない場合もあるので、日本語があるとうれしいですね。
Gitに移行するための機は熟した、と言えるのではないでしょうか。



今回は準備として、Git本のオンライン版で学習しつつ、PC単独のfileプロトコルだけで訓練し、remoteリポジトリと、ローカルのcloneされたリポジトリの関係を頭に叩き込みました。


MacOSXにGitを再インストール

MacPortsで既にインストールされていたのですが、MacPortsだとデフォルトでインストールされるバージョンが古かったので、アンインストールして、HomeBrewで再インストールしました。
これ自体は特に問題なくできました。


WindowsのGitクライアントをセットアップ

msysgitをインストールします。今回は、googlecodeのGit-1.7.11-preview20120710.exeを使いました。公式サイトのを使っても良いでしょう。

リポジトリを作成

/var/git/をGitリポジトリのルートディレクトリとして、リポジトリを作ります。
複数のリポジトリが扱えること、サブディレクトリでもアクセスできることを確認するために、次のように2つ作ります。

  • /var/git/p/project1.git
  • /var/git/s/sample.git
$ cd /var/git
$ mkdir p s
$ git init --bare --shared=true p/project1.git
$ git init --bare --shared=true s/sample.git
$ chown -R www p s

共有リポジトリを作る場合は、--bareを付けます。
公開リポジトリには、末尾に.gitを付けるのが通例のようです。
Apache2で公開するために、ディレクトリの所有権をwwwにします。
追記(2012-12-11): ごめんなさい、"--shared=true"を書き忘れていました。最初に作ったリポジトリには付けていたので気づかないでいたら、後から作ったリポジトリでダメになって気づきました。
これをやっていないと

unpack failed: unpack-objects abnormal exit

というエラーが出ます。
あとから"git config --global core.shared true"で訂正できるみたいです。
追記(2012-12-12): もうひとつ書き忘れ。所有権とパーミッション(setgid付)も訂正する必要があります。

# 例
chown -R www project1.git
chmod -R g+ws project1.git

最後に、gitプロトコルも使えるように、git-daemonでデーモンプロセスを起動しておきます。

git-daemon --export-all --enable=receive-pack --base-path=/var/git &

ここで、ローカルでcloneができること、gitプロトコルで操作できることを確認しました。詳細は割愛します。


ApacheにGit公開設定を追加

前置きにも書きましたが、HTTPプロトコルで公開する場合は"SmartHTTP"を使います。"SmartHTTP"以前はWebDAVを使うのが一般的だったそうですが、それだと他のプロトコルと比べてかなり遅いようです。

Apache2のhttpd.confへの設定例を示します。ここでは追加部分のみ示します。実際は、git専用のファイルに分けても良いですし、VirtualHostを使う例もあります。

SetEnv GIT_PROJECT_ROOT /var/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
<LocationMatch "^/git/.*/git-receive-pack$">
  SSLRequireSSL
</LocationMatch>

認証について、上記の例では、設定済みのSSLを使い回しています。SSLの設定については、こちらのエントリを参照してください。
もちろん、個別にパスワードをBasic認証かDigest認証で設定することもできます。下記はDigestの例。

<LocationMatch "^/git/.*/git-receive-pack$">
  AuthType Digest
  AuthName "GitHttpServer"
  AuthUserFile /var/git/.htdigest
  Require valid-user
</LocationMatch>

HTTP接続失敗〜設定追加〜HTTP接続成功

さっそく、HTTPでcloneしてみます。この時点ではproxy経由ではありません。

D:\git\local> git clone http://mymacsv.local/git/s/sample.git
Cloning into 'sample'...
error: The requested URL returned error: 403 while accessing https://mymacsv.local/git/s/sample.git/info/refs
fatal: HTTP request failed

403エラー(forbidden:アクセス禁止)になってしまいました。

apacheのerror_logを見ると、

client denied by server configuration: /usr/libexec/git-core/git-http-backend

SmartHTTPのバックエンドである"git-http-backend"にアクセスできないようです。



問題は2つありました。
注意:回避はできましたが、いずれも対症療法です。正しい解決方法は未だ判明していません。

1つ目は、"/usr/libexec/git-core"自体がありません。HomeBrewのCellarには"git-core/git-http-backend"があるので、"git-core"ごとシンボリックリンクで"/usr/libexec"からたどれるようにしました。
2つ目は、"/usr/libexec/git-core/"がアクセス禁止(403 forbidden)になっているのが原因のようです。
httpd.confに"/usr/libexec/git-core/"ディレクトリの公開設定を追加しました。

<Directory "/usr/libexec/git-core">
  Order allow,deny
  Allow from all
</Directory>


これで、cloneができるようになりました。


WindowsクライアントでProxy設定&パスワード自動設定

ここまではLANで確認したものです。
今度はProxy経由のみ接続可能な外部環境からの接続です。

  • グローバルなドメイン:mygitserver.example.com
  • プロキシサーバー: proxyserver.example.com:8080


プロキシサーバーの設定は、git configで追加します。

git config --global http.proxy proxyserver.example.com:8080


パスワードの自動設定は、Windowsの場合は、%USERPROFILE%/_netrc(.netrcではダメ)があればOK。
※%USERPROFILE%は、Windows7の場合は通常"C:\Users\(ログインユーザー)"です。

machine  mygitserver.example.com
login    argius
password ........


これで、外部のWindowsからも、cloneとpushができるようになりました。


おわりに

実際には、右往左往前後不覚...というのは大袈裟か...とにかく一筋縄ではいかなくて苦労しました。
それでもなんとか、プロキシ経由でのHTTPS接続までは達成できました。



SVNからの移行という点では、まだいくつか問題が残っています。
これについては、また後日。