murawaki の雑記

はてなグループから移転してきました

Life with git

最近 home の主だったファイルを git につっこんでデータの同期をとっている。そこそこ快適な git 生活をまとめてみるテスト。

目的。マシン間でのデータの共有というか一元化。対象となる計算機は以下。Linux のデスクトップが 2 台。Windows の入ったノート PC が 3 台。*1ノート PC は研究室と家の両方にある。git を使いだしてからは家にノート PC を持ち帰らなくてすむようになった。研究室に行くときや家に帰る時に git push し、移動先で git pull する。やはり A4 のノート PC はそう持ち歩くものではない。

準備。git のプログラムは、Linux はパッケージ化されたもの。Windows 側もやはり cygwin でパッケージ化されたもの。

運用方針。git は分散型のバージョン管理システムだが、運用上はハブ (あるいは中央サーバ) を用意する。各マシンはハブに push し、またハブから pull して同期をとる。通信には ssh を使う。ハブにはデスクトップの Linux マシンを任命。固定 IP アドレスを振っていないノート PC へアクセスするのは面倒なので。もっとも、デスクトップのマシンも private address を持っているだけで、外から直接アクセスできない。そこで ssh の ProxyCommand 機能を使う。~/.ssh/config に以下を記述すると、gateway-host を踏み台にして private-host に透過的にアクセスできる。この機能は、git に限らず、rsyncsubversion にも使える。


Host private-host
ProxyCommand ssh gateway-host nc %h 600000670

初期設定。ノート PC で git init。ハブも --bare で init。ノート PC 側で


git remote add origin ssh://private-host/repository-path
としてハブの所在を教える。.git/config に

[branch "master"]
remote = origin
merge = refs/heads/master
と書き加えたのは確か手動。git add, git commit ののち、git push するとハブにデータが転送された。

他のマシンでは


git clone private-host:repository-path repository-name
とするとレポジトリがコピーされる。

実は git を使いだしてからハブとなる Linux マシンを新しく買ったのだが、簡単にハブの移行ができた。新しいマシン側で以下を実行してレポジトリをコピー。


git clone --bare old-private-host:repository-path repository-name.git
つまり --bare を追加するだけで普通の clone とかわらない。あとは各マシンの .git/config で origin の url を新しいマシンに書き換える。

特殊な用途なので、git の機能の一部しか使わない。一人で使っているので基本的に衝突は起きない。一度だけハブに push し忘れて conflict が起きたけど、違いが permission の変更だけだったので、git が自動的に解消してくれた。

レポジトリに突っ込んでいるのは基本的にはデータ。プログラムは各マシンに個別にインストールしている。ただし、しばらく使っていて問題点に気付いた。私物のノート PC には PowerPoint が入っていない。一応 Open Office を入れてみたが、きれいに再現してくれない。

他のデータ、mail, calendar, RSS reader はウェブサービスを使っている。天下の G 社だから Doblog のようにデータが消えたりはしないだろうし、いずれもちゃんと export 機能が用意されているから、こちらでバックアップをとれる。

研究のプログラムは今のところ git に突っ込んでいない。研究室のプロジェクトはいまだに CVS で管理されている。私は耐えられないので Subversion を使っている。自分の Linux マシンにレポジトリを作って。一人で好き勝手にプログラムを書いているので、これまでのところ問題になっていない。それにしても Subversion の素直な移行方法がわからない。レポジトリは svnadmin dump と svnadmin load で移せる。しかしクライアント側はどうすればいいのかわからない。追記: svn switch でよいらしい。

2010年4月9日 追記: Windows XP 上の cygwin 1.7 から ssh 越しに git clone をやろうとすると、fatal: The remote end hung up unexpectedly とか fatal: early EOFs と言われて死ぬ。Windows 7 で同じ処理をやると成功。ググると同じ症状をうったえる人が多数。未解決らしい。workaround として、puttyplinkpageant が使えるという。しかし、ssh-keygen で作った鍵を認識してくれない。

Windows XP 上の別の repository での git pull で同じエラーが発生。Cygwin 1.7.5 に update したら発生しなくなった。しかし上記の git clone は相変わらずうまくいかない。再現条件がわからない。問題は git ではなく、cygwin のライブラリのどこからしい。

2010年5月13日 追記: また Windoes 上で git pull をやると fatal: The remote end hung up unexpectedly というエラーが発生。困ったので msysgit というパッケージを試してみた。msysgit のバイナリで git pull すると通った。しかし cygwin の git で作ったレポジトリに対して git status などをやるとやたら処理に時間がかかる。内部で何をやっているのか知らない。また、msysgit で更新したレポジトリを再度 cygwin の git で読もうとしても、やはり時間がかかる。レポジトリ全体を検査している様子。あとは cygwin とのパーミッションの違いの問題もある。これは git checkout で手動で対処。

2010年11月4日 追記: HTTP 上の通信をサポートする必要があってやってみた。レポジトリから clone はできたけど、push ができない。エラーにしたがって、./configure に CFLAGS=-DUSE_CURL_MULTI とする。それでも駄目。curl を新しいバージョンにしたら、とりあえず git-http-push は動くようになった。

*1:こうして改めて書くいてみるとえらくブルジョアに見えるが、古くなったマシンを後生大事に抱えているだけ。