git memo

2009/08/01新規 | 2009/08/04,07追記 | 2009/09/02,30追記 | 2009/10/09,10追記 | 2009/11/20追記
ここでは git による共同開発について備忘録としてまとめておく。

Contents

git の設定

まず、すべてのクライアントマシンについて、~/.gitconfig の初期設定を以下のように行う。
taiji@sakuya:~$ git config --global --add user.name 'Taiji Yamada'
taiji@sakuya:~$ git config --global --add user.email taiji@aihara.co.jp
それが正しく出来たかは、以下のように設定を確認できる。
taiji@sakuya:~$ git config --list
user.name=Taiji Yamada
user.email=taiji@aihara.co.jp

taiji@sakuya:~$ less ~/.gitconfig
[user]
name = Taiji Yamada
email = taiji@aihara.co.jp

ssh によるリポジトリの公開

まずは、以下の前提条件の元で進めてみよう(基本的には、すべてのマシンに git がインストールされているものとする)。
  1. sakuya, ubagami - クライアント、プロジェクトを遂行するマシン
  2. mitsuha - サーバ、リポジトリを公開するマシン、sakuya, ubagami から slogin 可能
例題のプロジェクトとして、sakuya 上に以下のような作業ディレクトリがあるものとしよう。
taiji@sakuya:~$ ls -1 export/fstrftime
fstrftime.c
makefile
中間ファイルや生成されるファイルがある場合は、後に git add . する関係上、予め消しておくこと。

リポジトリの作成

まず、作業ディレクトリに移動して、リポジトリの初期化を以下のように行う。
taiji@sakuya:~$ cd ~/export/fstrftime/
taiji@sakuya:~/export/fstrftime$ git init
すると、.git ディレクトリが作成される。特に気にする必要はないが、一応様子を見てみよう。
taiji@sakuya:~/export/fstrftime$ find .git
.git
.git/branches
.git/config
.git/description
.git/HEAD
.git/hooks
:
.git/info
.git/info/exclude
.git/objects
.git/objects/info
.git/objects/pack
.git/refs
.git/refs/heads
.git/refs/tags
次にリポジトリへの追加を次のように行う。
taiji@sakuya:~/export/fstrftime$ git add .
すると、以下のように .git ディレクトリの objects に何やら追加されていることがわかる。特に気にする必要はないが、様子を見てみよう。
taiji@sakuya:~/export/fstrftime$ find .git
:
.git/objects/8b
.git/objects/8b/1be3bc942138073397164b1b2f30d867bfbba8
.git/objects/9e
.git/objects/9e/34e9f8f990e7efc7ffbeac25dd9d846402eac8
:
次にリポジトリへのコミットを次のように行う。
taiji@sakuya:~/export/fstrftime$ git commit -m 'Initial commit'
すると、以下のように .git ディレクトリの logs, objects, refs に何やら追加されていることがわかる。特に気にする必要はないが、様子を見てみよう。
taiji@sakuya:~/export/fstrftime$ find .git
:
.git/COMMIT_EDITMSG
:
.git/logs/refs
.git/logs/refs/heads
.git/logs/refs/heads/master
:
.git/objects/00
.git/objects/00/91b6c2ab0398c617a16e3a333e1e1bef63358a
.git/objects/41
.git/objects/41/c3beb37a1e6d24908819ca3f5b11e33974fe67
:
.git/refs
.git/refs/heads
.git/refs/heads/master
.git/refs/tags
以上で fstrftime プロジェクトのリポジトリの作成は完了である。

(補遺) この段階で .git/description を編集し、プロジェクトの説明を書いておくとよい。

公開リポジトリの作成

次に mitsuha 上で公開リポジトリの準備を行う。以下のように素の git リポジトリを格納するディレクトリを作成しておく。
taiji@mitsuha:~$ sudo mkdir -p /var/git/fstrftime.git
taiji@mitsuha:~$ sudo chown -R taiji /var/git/fstrftime.git
taiji@mitsuha:~$ sudo chgrp -R staff /var/git/fstrftime.git
とりあえず自分の uid.gid にしたのは、後に ssh 経由でここに書き込むからである(後にここでの taiji アカウント以外から書き込みを許可するには、グループを作成して、グループの書き込みを許可することになる。つまり、「find . -type d -exec chmod g+s {} \;」もしくは「git config --add core.sharedRepository group && chmod -R g+w .」を素のリポジトリの中で実行すればよい。詳しくは git-init(1) を参照)。

次に sakuya 上で素の git リポジトリを以下のように作成する。これは mitsuha に移動すべき一時的なディレクトリである。
taiji@sakuya:~$ cd /tmp/
taiji@sakuya:/tmp$ git clone --bare ~/export/fstrftime fstrftime.git
作成された素の git リポジトリは、ほとんど ~/export/fstrftime/.git と同じものであるが、全く同一ではない。特に気にする必要はないが、一応様子を見てみよう。
taiji@sakuya:/tmp$ diff -r ~/export/fstrftime/.git/ fstrftime.git/
Only in /Users/taiji/export/fstrftime/.git/: COMMIT_EDITMSG
diff -r /Users/taiji/export/fstrftime/.git/config fstrftime.git/config
4,5c4
< bare = false
< logallrefupdates = true
---
> bare = true
Only in /Users/taiji/export/fstrftime/.git/: index
Only in /Users/taiji/export/fstrftime/.git/: logs
Only in fstrftime.git/: packed-refs
Only in /Users/taiji/export/fstrftime/.git/refs/heads: master
最後に、作成された sakuya 上の素の git リポジトリを mitsuha にコピーする。
taiji@sakuya:/tmp$ rsync --rsh=ssh -auv fstrftime.git/ mitsuha.aihara.co.jp:/var/git/fstrftime.git/
この作業が完了すれば、taiji@sakuya:/tmp/fstrftime.git は消去してもよい。

これで ssh プロトコルによるリポジトリの公開は完了である。

公開リポジトリの運用

では、ubagami からリポジトリを取得してみよう。
taiji@ubagami:~$ cd ~/export/
taiji@ubagami:~/export$ git clone ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git

taiji@ubagami:~/export$ ls -1 fstrftime/
fstrftime.c
makefile
また、sakuya でプロジェクトを更新してみよう。ここでは fstrftime.c を改良した。以下のように手元での差分を確認する。
taiji@sakuya:~/export/fstrftime$ git diff
diff --git a/fstrftime.c b/fstrftime.c
index 8b1be3b..9cdb5b8 100644
--- a/fstrftime.c
+++ b/fstrftime.c
@@ -34,12 +34,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
+#if !defined(HAVE_STRLCPY)
/* not completely the same as BSD strlcpy */
#define strlcpy(d, s, z) do {\
strncpy(d, s, z);\
if ((z) > 0)\
d[(z)-1] = '\0';\
} while (0)
+#endif

int usage(int rc)
{
確認したら、以下のように手元のリポジトリにコミットする。
taiji@sakuya:~/export/fstrftime$ git commit -a -m 'use native strlcpy'
ところで、sakuya 上のリポジトリは mitsuha から pull されたものではないので、適宜リモートURLを知らしめる必要があるが、以下のように設定および確認すればよい。
taiji@sakuya:~/export/fstrftime$ git config --add remote.origin.url ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git
taiji@sakuya:~/export/fstrftime$ git config --list
:
remote.origin.url=ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git

taiji@sakuya:~/export/fstrftime$ less .git/config
:
[remote "origin"]
url = ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git
(注) 但し、別のやり方として、以下のように git-remote(1) を使って remote.origin.url を設定すると、remote.origin.fetch も追加される。
taiji@sakuya:~/export/fstrftime$ git remote add -t master -m master -f -- origin ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git
taiji@sakuya:~/export/fstrftime$ git config --list
:
remote.origin.url=ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

taiji@sakuya:~/export/fstrftime$ less .git/config
:
[remote "origin"]
url = ssh://mitsuha.aihara.co.jp/var/git/fstrftime.git
fetch = +refs/heads/*:refs/remotes/origin/*
(注意) 加えて、git-config(1) を使って branch.master.remote 他を以下のように設定すると sakuya から pull されたものと同一の設定になる。
taiji@sakuya:~/export/fstrftime$ git config --add branch.master.remote origin
taiji@sakuya:~/export/fstrftime$ git config --add branch.master.merge refs/heads/master
taiji@sakuya:~/export/fstrftime$ git config --list
:
branch.master.remote=origin
branch.master.merge=refs/heads/master
:
taiji@sakuya:~/export/fstrftime$ less .git/config
:
[branch "master"]
remote = origin
merge = refs/heads/master
そして、以下のように mitsuha の公開リポジトリにプッシュする。
taiji@sakuya:~/export/fstrftime$ git push


では、mitsuha の公開リポジトリ上の更新を ubagami から以下のように取得できるか確認しよう。
taiji@ubagami:~/export/fstrftime$ git pull


今度は、ubagami でプロジェクトを更新してみよう。ここでは fstrftime.c の著作権表示を修正した。以下のように手元での差分を確認する。
taiji@ubagami:~/export/fstrftime$ git diff
diff --git a/fstrftime.c b/fstrftime.c
index 9cdb5b8..9cc16d3 100644
--- a/fstrftime.c
+++ b/fstrftime.c
@@ -17,7 +17,7 @@
* -L|-P use stat(2)
instead of lstat(2), and vice versa.
* -p|-f show the name
of file prior or following time.
*
- * Copyright (c) 2007 Taiji Yamada <taiji@aihara.co.jp>
+ * Copyright (c) 2007,2009 Taiji Yamada <taiji@aihara.co.jp>
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
確認したら、以下のように手元のリポジトリにコミットする。
taiji@ubagami:~/export/fstrftime$ git commit -a -m 'fix copyright notice of fstrftime.c'
そして、以下のように mitsuha の公開リポジトリにプッシュする。
taiji@ubagami:~/export/fstrftime$ git push 


では、sakuya から ubagami における更新を mitsuha 経由で以下のように取得できるか確認しよう。
taiji@sakuya:~/export/fstrftime$ git pull

(補遺)
ssh で git pull/push を許可するのみのログインシェル git-shell(1) が提供されているので、適宜利用する事。これを利用したアカウントは、それ自身で自己管理できないわけなので、.ssh/authorized_keys の設定などはサーバ管理者が代行すること。

http によるリポジトリの公開

まずは、以下の前提条件の元で進めてみよう(基本的には、すべてのマシンに git がインストールされているものとする)。
  1. sakuya, ubagami - クライアント、プロジェクトを遂行するマシン
  2. mitsuha - サーバ、リポジトリを公開するマシン、ウェブサーバが起動されている(書き込みの許可には要WebDAV)
例題のプロジェクトとして、sakuya 上に以下のような作業ディレクトリがあるものとしよう。
taiji@sakuya:~$ ls -1 export/fwho
fwho.c
makefile
中間ファイルや生成されるファイルがある場合は、後に git add . する関係上、予め消しておくこと。

リポジトリの作成

先の fstrftime プロジェクトと全く同様であるが、おさらいのために改めて手順を記す。まず、作業ディレクトリに移動して、リポジトリの初期化を以下のように行う。
taiji@sakuya:~$ cd ~/export/fwho/
taiji@sakuya:~/export/fwho$ git init
次にリポジトリへの追加を次のように行う。
taiji@sakuya:~/export/fwho$ git add .
次にリポジトリへのコミットを次のように行う。
taiji@sakuya:~/export/fwho$ git commit -m 'Initial commit'
以上で fwho プロジェクトのリポジトリの作成は完了である。

(補遺) この段階で .git/description を編集し、プロジェクトの説明を書いておくとよい。

公開リポジトリの作成

次に mitsuha 上で公開リポジトリの準備を行う。以下のように素の git リポジトリを格納するディレクトリを作成しておく。
taiji@mitsuha:~$ sudo mkdir -p /var/git/fwho.git
taiji@mitsuha:~$ sudo chown -R taiji /var/git/fwho.git
taiji@mitsuha:~$ sudo chgrp -R staff /var/git/fwho.git
とりあえず自分の uid.gid にしたのは、後に ssh 経由でここに書き込むからである(後にここでの taiji アカウント以外から書き込みを許可するには、グループを作成して、グループの書き込みを許可すればよいだろう)。

次に sakuya 上で素の git リポジトリを以下のように作成する。これは mitsuha に移動すべき一時的なディレクトリである。
taiji@sakuya:~$ cd /tmp/
taiji@sakuya:/tmp$ git clone --bare ~/export/fwho fwho.git
taiji@sakuya:/tmp$ cd fwho.git/
taiji@sakuya:/tmp/fwho.git$ git --bare update-server-info
taiji@sakuya:/tmp/fwho.git$ cp -p hooks/post-update.sample hooks/post-update
taiji@sakuya:/tmp/fwho.git$ chmod a+x hooks/post-update
作成された素の git リポジトリは、ほとんど ~/export/fwho/.git と同じものであるが、全く同一ではない上に、git-update-server-info(1) により info/refs など、そして hooks/post-update が加わっており、これらが http でリポジトリを公開するには必須となる。

そして、作成された sakuya 上の素の git リポジトリを mitsuha にコピーする。
taiji@sakuya:/tmp$ rsync --rsh=ssh -auv fwho.git/ mitsuha.aihara.co.jp:/var/git/fwho.git/
この作業が完了すれば、taiji@sakuya:/tmp/fwho.git は消去してもよい。

最後に、/etc/〜/httpd.conf にて以下の行を追加する。
Alias /git "/var/git"
これで http によるリポジトリの公開は完了である。

公開リポジトリの運用

では、ubagami からリポジトリを取得してみよう。
taiji@ubagami:~$ cd ~/export/
taiji@ubagami:~/export$ git clone http://mitsuha.aihara.co.jp/git/fwho.git

taiji@ubagami:~/export$ ls -1 fwho/
fwho.c
makefile
また、sakuya でプロジェクトを更新してみよう。ここでは fwho.c を改良した。以下のように手元での差分を確認する。
taiji@sakuya:~/export/fwho$ git diff
diff --git a/fwho.c b/fwho.c
index 89b650f..d588a13 100644
--- a/fwho.c
+++ b/fwho.c
@@ -72,12 +72,14 @@
#define _PATH_WTMPX ""
#endif

+#if !defined(HAVE_STRLCPY)
/* not completely the same as BSD strlcpy */
#define strlcpy(d, s, z) do {\
strncpy(d, s, z);\
if ((z) > 0)\
d[(z)-1] = '\0';\
} while (0)
+#endif

/* swap for arbitrary type */
#define swap(a,b) do {\
確認したら、以下のように手元のリポジトリにコミットする。
taiji@sakuya:~/export/fwho$ git commit -a -m 'use native strlcpy'
そして、以下のように mitsuha の公開リポジトリにプッシュする。但しこの段階では、http による書き込みは許可していないので、取り敢えず ssh プロトコルを使っている。
taiji@sakuya:~/export/fwho$ git config --add remote.origin.url ssh://mitsuha.aihara.co.jp/var/git/fwho.git

taiji@sakuya:~/export/fwho$ git push
(注) 前述のように git-remote(1) で remote.origin.url を設定してもよい。


では、mitsuha の公開リポジトリ上の更新を ubagami から以下のように取得できるか確認しよう。
taiji@ubagami:~/export/fwho$ git pull


さて、次に WebDAV による公開リポジトリへの書き込みを可能にするための設定を行うわけだが、これはウェブサーバ環境に大きく依存するので、apache ウェブサーバに限定しつつも基本的な解説のみに留めることにする。さらに git-http-push(1) は新しめの curl, expat と共にビルドした git が必要となる。ちなみに、Tiger の Apache/1.3.41 DAV/1.0.3 ではうまく動作しない。Leopard の Apache/2.2.11 DAV/2 であれば成功している。

/etc/〜/httpd.conf にて以下の行が有効になっていることを確認する。
LoadModule dav_module libexec/httpd/libdav.so
AddModule mod_dav.c
次に、/etc/〜/httpd.conf にて以下を追加する。
<IfModule mod_dav.c>
DAVLockDB "/tmp/.davlock"
<Location "/git/fwho.git">
DAV on
AuthType Basic
AuthName "/git/fwho.git"
AuthUserFile "/var/git/passwd"
<LimitExcept GET HEAD PROPFIND OPTIONS>
# Require valid-user
Require user taiji
</LimitExcept>
Order allow,deny
Allow from all
</Location>
</IfModule>
さらに、/var/git/passwd を以下のように作成する(次に ~/.netrc へ平文でパスワードを記述する都合上、万が一漏れても影響が少ないパスワードにすること)。
taiji@mitsuha:~$ sudo htpasswd -c /var/git/passwd taiji
New password:
Re-type new password:
Adding password for user taiji
さらに、/var/git/fwho.git 配下は www アカウントで書き込み許可されている必要があるので、そのように調整する事。作業が終わったら apache を再起動する。

以上で、公開リポジトリへの taiji アカウントでの書き込み許可の設定は完了である。

次に、クライアントに以下のように ~/.netrc ファイルを作成する。
taiji@ubagami:~$ touch ~/.netrc
taiji@ubagami:~$ chmod go-r ~/.netrc
taiji@ubagami:~$ cat >> ~/.netrc
machine mitsuha.aihara.co.jp login taiji password ********
^D
何か変更し、コミットした後、git-push が成功すれば完了である(もしうまく行かない場合、apache に実行ユーザ、/var/git/fwho.git/ 配下のパーミッション、オーナー、グループ、そして、apache のアクセスログ、エラーログを確認すること)。
taiji@ubagami:~/export/fwho$ git push
また、sakuya から同様に git-push したいのであれば以下のように設定を追加するとよい。
taiji@sakuya:~/export/fwho$ git config --add remote.origin.url http://mitsuha.aihara.co.jp/git/fwho.git
(注) 前述のように git-remote(1) で remote.origin.url を設定してもよい。

(補遺)
以上の例ではアカウント管理は htpasswd と httpd.conf で行うことになるので、詳しくは apache のドキュメントを参照。

git プロトコルによるリポジトリの公開

まずは、以下の前提条件の元で進めてみよう(基本的には、すべてのマシンに git がインストールされているものとする)。
  1. sakuya, ubagami - クライアント、プロジェクトを遂行するマシン
  2. mitsuha - サーバ、リポジトリを公開するマシン、git-daemon を起動する(書き込み許可は想定しない)
例題のプロジェクトとして、sakuya 上に以下のような作業ディレクトリがあるものとしよう。
taiji@sakuya:~$ ls -1 export/large_files
check_large_file.c
echo_sizeof_off_t.c
makefile
print_large_data.c
write_large_data.c
中間ファイルや生成されるファイルがある場合は、後に git add . する関係上、予め消しておくこと。

リポジトリの作成

先の fstrftime プロジェクトと全く同様であるが、おさらいのために改めて手順を記す。まず、作業ディレクトリに移動して、リポジトリの初期化を以下のように行う。
taiji@sakuya:~$ cd ~/export/large_files/
taiji@sakuya:~/export/large_files$ git init
次にリポジトリへの追加を次のように行う。
taiji@sakuya:~/export/large_files$ git add .
次にリポジトリへのコミットを次のように行う。
taiji@sakuya:~/export/large_files$ git commit -m 'Initial commit'
以上で large_files プロジェクトのリポジトリの作成は完了である。

(補遺) この段階で .git/description を編集し、プロジェクトの説明を書いておくとよい。

公開リポジトリの作成

次に mitsuha 上で公開リポジトリの準備を行う。以下のように素の git リポジトリを格納するディレクトリを作成しておく。
taiji@mitsuha:~$ sudo mkdir -p /var/git/large_files.git
taiji@mitsuha:~$ sudo chown -R taiji /var/git/large_files.git
taiji@mitsuha:~$ sudo chgrp -R staff /var/git/large_files.git
とりあえず自分の uid.gid にしたのは、後に ssh 経由でここに書き込むからである(後にここでの taiji アカウント以外から書き込みを許可するには、グループを作成して、グループの書き込みを許可すればよいだろう)。

次に sakuya 上で素の git リポジトリを以下のように作成する。これは mitsuha に移動すべき一時的なディレクトリである。
taiji@sakuya:~$ cd /tmp/
taiji@sakuya:/tmp$ git clone --bare ~/export/large_files large_files.git

そして、作成された sakuya 上の素の git リポジトリを mitsuha にコピーする。
taiji@sakuya:/tmp$ rsync --rsh=ssh -auv large_files.git/ mitsuha.aihara.co.jp:/var/git/large_files.git/
この作業が完了すれば、taiji@sakuya:/tmp/large_files.git は消去してもよい。

 さて、ここから git-daemon の起動であるが、以下のような起動方法を想定する。
taiji@mitsuha:~$ sudo env PATH=/opt/local/bin:/usr/bin:/usr/sbin:/bin \
/opt/local/libexec/git-core/git-daemon --user=nobody --group=nobody \
--base-path=/var/git --export-all --syslog --pid-file=/var/run/git-daemon.pid
オプション「--base-path=/var/git --export-all」とあるので、/var/git/ 配下にあるリポジトリはすべて公開されることに注意。詳しくは git-daemon(1) を参照のこと。そして、システム起動時に起動させるには、Solaris であれば /etc/init.d/ 等への起動スクリプトの登録、Mac OS X であれば、/System/Library/StartupItems/GitDaemon/{GitDaemon, StartupParameters.plist} の記述、もしくは、/System/Library/LaunchDaemons/org.kernel.git-daemon.plist の記述となるが、システム固有の説明となるのでここでは省略する。

公開リポジトリの運用

では、ubagami からリポジトリを取得してみよう。
taiji@ubagami:~$ cd ~/export/
taiji@ubagami:~/export$ git clone git://mitsuha.aihara.co.jp/large_files.git

taiji@ubagami:~/export$ ls -1 large_files/
check_large_file.c
echo_sizeof_off_t.c
makefile
print_large_data.c
write_large_data.c
また、sakuya でプロジェクトを更新してみよう。ここでは print_large_files.c, write_large_files.c を修正した。以下のように手元での差分を確認する。
taiji@sakuya:~/export/large_files$ git diff
diff --git a/print_large_data.c b/print_large_data.c
index 974fe9a..5399a8a 100644
--- a/print_large_data.c
+++ b/print_large_data.c
@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
for (a=1; a<argc; a++)
if (!strcmp(argv[a], "--"))
break;
- else if (!strcmp(argv[a], "-h")) {
+ else if (!strcmp(argv[a], "-h") || !strcmp(argv[a], "--help")) {
usage(stdout, argv[0]);
return 0;
}
diff --git a/write_large_data.c b/write_large_data.c
index 359a6fa..1af5e30 100644
--- a/write_large_data.c
+++ b/write_large_data.c
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
for (a=1; a<argc; a++)
if (!strcmp(argv[a], "--"))
break;
- else if (!strcmp(argv[a], "-h")) {
+ else if (!strcmp(argv[a], "-h") || !strcmp(argv[a], "--help")) {
usage(stdout, argv[0]);
return 0;
}
確認したら、以下のように手元のリポジトリにコミットする。
taiji@sakuya:~/export/large_files$ git commit -a -m 'add "--help" alias of "-h" option'
そして、以下のように mitsuha の公開リポジトリにプッシュする。但し、git プロトコル による書き込みは許可していないので、ssh プロトコルを使う。
taiji@sakuya:~/export/large_files$ git config --add remote.origin.url ssh://mitsuha.aihara.co.jp/var/git/large_files.git

taiji@sakuya:~/export/large_files$
git push
(注) 前述のように git-remote(1) で remote.origin.url を設定してもよい。


では、mitsuha の公開リポジトリ上の更新を ubagami から以下のように取得できるか確認しよう。
taiji@ubagami:~/export/large_files$ git pull

(補遺)
ちなみに、git-daemon (1) にオプション「--enable=receive-pack」を加えると、git-daemon の実行ユーザが書き込み権限があれば、匿名による git-push が可能になる。但しこれは、信頼できるネットワーク環境内での運用を想定したものであることに注意。

その他

git Web によるリポジトリの公開

git のソースの tarball の中には、gitweb という Perl で書かれた CGI ウェブインターフェースが同梱されており、gitweb/INSTALL を読めば分かるように、configure --prefix=/opt/local && make gitweb/gitweb.cgi などとすると gitweb.cgi が作成されるようになっている。

そして、生成された gitweb/gitweb.cgi を編集して「our $projectroot = "/var/git";」のように公開リポジトリが置いてあるパスを指定する。

最後に、CGI が許可された apache ウェブサーバが起動している mitsuha の /etc/httpd/httpd.conf で例えば以下のような設定を加えれば、
Alias /gitweb "/path/to/gitweb"
<Location /gitweb>
Options ExecCGI
DirectoryIndex gitweb.cgi
</Location>
http://mitsuha.aihara.co.jp/gitweb/ でリポジトリの閲覧ができるようになる。

tarball 作成上の注意

taiji@sakuya:~/export/logdo$ git archive -v --format=tar --prefix=logdo-20090902/ -- HEAD | gzip > ../logdo-20090902.tar.gz
などとすると、上位ディレクトリに pax(1) の global extended header 付きの tarball が作成されるが、対応していない tar では展開できないかもしれない。そこで以下のようにすればよい。
taiji@sakuya:~/export/logdo$ git archive -v --format=tar --prefix=logdo-20090902/ -- HEAD^{tree} | gzip > ../logdo-20090902.tar.gz

リモートリポジトリとコンフリクトへの対応

中央リポジトリを介して複数人と共同開発していると、中央リポジトリとリモートリポジトリに競合が生じる。基本的には git pull したときに競合する箇所が作業ディレクトリのファイルに書き込まれるので、その情報を元に適切にファイルを修正したのち、git commit、git push すればよい。もしくは自分の修正を断念して、git checkout -- file... すればよい。

また、手元の履歴をリニアに保ちたい場合には git-rebase(1) を参考のこと。

コミットメッセージを書き直したい

直前のコミットであれば簡単に修正することができる。
taiji@sakuya: ~/export/abmail$ git commit --amend
コミットメッセージだけでなく、コミット内容自体も修正できる。作業ディレクトリの状態を含めて直前のコミットを無かったことにしたい場合には、git reset --hard HEAD^ を使う。詳しくは、git-reset(1), git-commit(1) を参照のこと。

キリのよいところでタグを打つ

tarball をリリースした等、プロジェクトの区切りの良い時点でタグを打っておくと、後にそれを様々に参照でき便利である。
taiji@sakuya: ~/export/abmail$ git tag v1.2.1
過去の時点にタグを打つこともできる。それには、まずログをみて commit 名を調べた後、それに対してタグを打てば良い。
taiji@sakuya: ~/export/abmail$ git log
	:
commit 3a2002bc75c2c66ab1dcc25fce76f3e501f22b19
	:
    Initial commit for abmail-1.2.0
	:
taiji@sakuya: ~/export/abmail$ git tag v1.2.0 3a2002bc75c2c66ab1dcc25fce76f3e501f22b19
タグを git push するにはオプションが必要となることに注意しよう。
taiji@sakuya: ~/export/abmail$ git push --tags

ウェブコンテンツディレクトリと .git ディレクトリの注意

「.svn」 「CVS」ディレクトリを狙ってWebサイトの非公開ファイルをゲット』 にあるように、ウェブコンテンツを提供するディレクトリが git の作業ディレクトリを兼ねている場合、.git ディレクトリから例えばCGIスクリプトのソースが露呈してしまい、セキュリティリスクが増大する恐れがある。.git については個別に chmod -R o-r するか、httpd サーバの設定で不可視にしておく必要があるので注意しよう。以下に後者の apache の httpd.conf での例を記しておく。
	:
<DirectoryMatch "/\.git">
Order allow,deny
Deny from all
Satisfy All
</DirectoryMatch>
:
正規表現 "/\.git" のスラッシュがないと、素のリポジトリ 〜.git にもマッチしてしまうことに注意。

Written by Taiji Yamada