Git の設定
第 1 章で手短にごらんいただいたように、git config
コマンドで Git の設定をすることができます。まず最初にすることと言えば、名前とメールアドレスの設定でしょう。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
ここでは、同じようにして設定できるより興味深い項目をいくつか身につけ、Git をカスタマイズしてみましょう。
Git の設定については最初の章でちらっと説明しましたが、ここでもう一度振り返っておきます。Git では、いくつかの設定ファイルを使ってデフォルト以外の挙動を定義します。まず最初に Git が見るのは /etc/gitconfig
で、ここにはシステム上の全ユーザーの全リポジトリ向けの設定値を記述します。git config
にオプション --system
を指定すると、このファイルの読み書きを行います。
次に Git が見るのは ~/.gitconfig
で、これは各ユーザー専用のファイルです。Git でこのファイルの読み書きをするには、--global
オプションを指定します。
最後に Git が設定値を探すのは、現在使用中のリポジトリの設定ファイル (.git/config
) です。この値は、そのリポジトリだけで有効なものです。後から読んだ値がその前の値を上書きします。したがって、たとえば .git/config
に書いた値は /etc/gitconfig
での設定よりも優先されます。これらのファイルを手動で編集して正しい構文で値を追加することもできますが、通常は git config
コマンドを使ったほうが簡単です。
基本的なクライアントのオプション
Git の設定オプションは、おおきく二種類に分類できます。クライアント側のオプションとサーバー側のオプションです。大半のオプションは、クライアント側のもの、つまり個人的な作業環境を設定するためのものとなります。大量のオプションがありますが、ここでは一般的に使われているものやワークフローに大きな影響を及ぼすものに絞っていくつかを紹介します。その他のオプションの多くは特定の場合にのみ有用なものなので、ここでは扱いません。Git で使えるすべてのオプションを知りたい場合は、次のコマンドを実行しましょう。
$ git config --help
また、git config
のマニュアルページには、利用できるすべてのオプションについて詳しい説明があります。
core.editor
コミットやタグのメッセージを編集するときに使うエディタは、ユーザーがデフォルトエディタとして設定したものとなります。デフォルトエディタが設定されていない場合は Vi エディタを使います。このデフォルト設定を別のものに変更するには core.editor
を設定します。
$ git config --global core.editor emacs
これで、シェルのデフォルトエディタを設定していない場合に Git が起動するエディタが Emacs に変わりました。
commit.template
システム上のファイルへのパスをここに設定すると、Git はそのファイルをコミット時のデフォルトメッセージとして使います。たとえば、次のようなテンプレートファイルを作って $HOME/.gitmessage.txt
においたとしましょう。
subject line
what happened
[ticket: X]
git commit
のときにエディタに表示されるデフォルトメッセージをこれにするには、commit.template
の設定を変更します。
$ git config --global commit.template $HOME/.gitmessage.txt
$ git commit
すると、コミットメッセージの雛形としてこのような内容がエディタに表示されます。
subject line
what happened
[ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C
コミットメッセージについて所定の決まりがあるのなら、その決まりに従ったテンプレートをシステム上に作って Git にそれを使わせるようにするとよいでしょう。そうすれば、その決まりに従ってもらいやすくなります。
core.pager
core.pager は、Git が log
や diff
などを出力するときに使うページャを設定します。more
などのお好みのページャを設定したり (デフォルトは less
です)、空文字列を設定してページャを使わないようにしたりすることができます。
$ git config --global core.pager ''
これを実行すると、すべてのコマンドの出力を、どんなに長くなったとしても全部 Git が出力するようになります。
user.signingkey
署名入りの注釈付きタグ (第 2 章で取り上げました) を作る場合は、GPG 署名用の鍵を登録しておくと便利です。鍵の ID を設定するには、このようにします。
$ git config --global user.signingkey <gpg-key-id>
これで、git tag
コマンドでいちいち鍵を指定しなくてもタグに署名できるようになりました。
$ git tag -s <tag-name>
core.excludesfile
プロジェクトごとの .gitignore
ファイルでパターンを指定すると、git add
したときに Git がそのファイルを無視してステージしないようになります。これについては第 2 章で説明しました。しかし、これらの内容をプロジェクトの外部で管理したい場合は、そのファイルがどこにあるのかを core.excludesfile
で設定します。ここに設定する内容はファイルのパスです。ファイルの中身は .gitignore
と同じ形式になります。
help.autocorrect
このオプションが使えるのは Git 1.6.1 以降だけです。Git 1.6 でコマンドを打ち間違えると、こんなふうに表示されます。
$ git com
git: 'com' is not a git-command. See 'git --help'.
Did you mean this?
commit
help.autocorrect
を 1 にしておくと、同じような場面でもし候補がひとつしかなければ自動的にそれを実行します。
Git における色
Git では、ターミナルへの出力に色をつけることができます。ぱっと見て、すばやくお手軽に出力内容を把握できるようになるでしょう。さまざまなオプションで、お好みに合わせて色を設定しましょう。
color.ui
あらかじめ指定しておけば、Git は自動的に大半の出力に色づけをします。何にどのような色をつけるかをこと細かに指定することもできますが、すべてをターミナルのデフォルト色設定にまかせるなら color.ui
を true にします。
$ git config --global color.ui true
これを設定すると、出力がターミナルに送られる場合に Git がその出力を色づけします。ほかに false という値を指定することもでき、これは出力に決して色をつけません。また always を指定すると、すべての場合に色をつけます。すべての場合とは、Git コマンドをファイルにリダイレクトしたり他のコマンドにパイプでつないだりする場合も含みます。この設定項目は Git バージョン 1.5.5 で追加されました。それより前のバージョンを使っている場合は、すべての色設定を個別に指定しなければなりません。
color.ui = always
を使うことは、まずないでしょう。たいていの場合は、カラーコードを含む結果をリダイレクトしたい場合は Git コマンドに --color
フラグを渡してカラーコードの使用を強制します。ふだんは color.ui = true
の設定で要望を満たせるでしょう。
color.*
どのコマンドをどのように色づけするかをより細やかに指定したい場合、あるいはバージョンが古くて先ほどの設定が使えない場合は、コマンド単位の色づけ設定を使用します。これらの項目には true
、false
あるいは always
を指定することができます。
color.branch
color.diff
color.interactive
color.status
さらに、これらの項目ではサブ設定が使え、出力の一部について特定の色を使うように指定することもできます。たとえば、diff の出力でのメタ情報を青の太字で出力させたい場合は次のようにします。
$ git config --global color.diff.meta “blue black bold”
色として指定できる値は normal、black、red、green、yellow、blue、magenta、cyan あるいは white のいずれかです。先ほどの例の bold のように属性を指定することもできます。bold、dim、ul、blink および reverse のいずれかを指定できます。
git config
のマニュアルページに、すべてのサブ設定がまとめられていますので参照ください。
外部のマージツールおよび Diff ツール
Git には diff の実装が組み込まれておりそれを使うことができますが、外部のツールを使うよう設定することもできます。また、コンフリクトを手動で解決するのではなくグラフィカルなコンフリクト解消ツールを使うよう設定することもできます。ここでは Perforce Visual Merge Tool (P4Merge) を使って diff の表示とマージの処理を行えるようにする例を示します。これはすばらしいグラフィカルツールで、しかもフリーだからです。
P4Merge はすべての主要プラットフォーム上で動作するので、実際に試してみたい人は試してみるとよいでしょう。この例では、Mac や Linux 形式のパス名を例に使います。Windows の場合は、/usr/local/bin
のところを環境に合わせたパスに置き換えてください。
まず、P4Merge をここからダウンロードします。
http://www.perforce.com/perforce/downloads/component.html
最初に、コマンドを実行するための外部ラッパースクリプトを用意します。この例では、Mac 用の実行パスを使います。他のシステムで使う場合は、p4merge
のバイナリがインストールされた場所に置き換えてください。次のようなマージ用ラッパースクリプト extMerge
を用意しました。これは、すべての引数を受け取ってバイナリをコールします。
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*
diff のラッパーは、7 つの引数が渡されていることを確認したうえでそのうちのふたつをマージスクリプトに渡します。デフォルトでは、Git は次のような引数を diff プログラムに渡します。
path old-file old-hex old-mode new-file new-hex new-mode
ここで必要な引数は old-file
と new-file
だけなので、ラッパースクリプトではこれらを渡すようにします。
$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"
また、これらのツールは実行可能にしておかなければなりません。
$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff
これで、自前のマージツールや diff ツールを使えるように設定する準備が整いました。設定項目はひとつだけではありません。まず merge.tool
でどんなツールを使うのかを Git に伝え、mergetool.*.cmd
でそのコマンドを実行する方法を指定し、mergetool.trustExitCode
では「そのコマンドの終了コードでマージが成功したかどうかを判断できるのか」を指定し、diff.external
では diff の際に実行するコマンドを指定します。つまり、このような 4 つのコマンドを実行することになります。
$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.trustExitCode false
$ git config --global diff.external extDiff
あるいは、~/.gitconfig
ファイルを編集してこのような行を追加します。
[merge]
tool = extMerge
[mergetool "extMerge"]
cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
trustExitCode = false
[diff]
external = extDiff
すべて設定し終えたら、
$ git diff 32d1776b1^ 32d1776b1
このような diff コマンドを実行すると、結果をコマンドラインに出力するかわりに P4Merge を立ち上げ、図 7-1 のようになります。

図 7-1. P4Merge
ふたつのブランチをマージしてコンフリクトが発生した場合は git mergetool
を実行します。すると P4Merge が立ち上がり、コンフリクトの解決を GUI ツールで行えるようになります。
このようなラッパーを設定しておくと、あとで diff ツールやマージツールを変更したくなったときにも簡単に変更することができます。たとえば extDiff
や extMerge
で KDiff3 を実行させるように変更するには extMerge
ファイルをこのように変更するだけでよいのです。
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
これで、Git での diff の閲覧やコンフリクトの解決の際に KDiff3 が立ち上がるようになりました。
Git にはさまざまなマージツール用の設定が事前に準備されており、特に設定しなくても利用することができます。事前に設定が準備されているツールは kdiff3、opendiff、tkdiff、meld、xxdiff、emerge、vimdiff そして gvimdiff です。KDiff3 を diff ツールとしてではなくマージのときにだけ使いたい場合は、kdiff3 コマンドにパスが通っている状態で次のコマンドを実行します。
$ git config --global merge.tool kdiff3
extMerge
や extDiff
を準備せずにこのコマンドを実行すると、マージの解決の際には KDiff3 を立ち上げて diff の際には通常の Git の diff ツールを使うようになります。
書式設定と空白文字
書式設定や空白文字の問題は微妙にうっとうしいもので、とくにさまざまなプラットフォームで開発している人たちと共同作業をするときに問題になりがちです。使っているエディタが知らぬ間に空白文字を埋め込んでしまっていたり Windows で開発している人が行末にキャリッジリターンを付け加えてしまったりなどしてパッチが面倒な状態になってしまうことも多々あります。Git では、こういった問題に対処するための設定項目も用意しています。
core.autocrlf
自分が Windows で開発していたり、チームの中に Windows で開発している人がいたりといった場合に、改行コードの問題に巻き込まれることがありがちです。Windows ではキャリッジリターンとラインフィードでファイルの改行を表すのですが、Mac や Linux ではラインフィードだけで改行を表すという違いが原因です。ささいな違いではありますが、さまざまなプラットフォームにまたがる作業では非常に面倒なものです。
Git はこの問題に対処するために、コミットする際には行末の CRLF を LF に自動変換し、ファイルシステム上にチェックアウトするときには逆の変換を行うようにすることができます。この機能を使うには core.autocrlf
を設定します。Windows で作業をするときにこれを true
に設定すると、コードをチェックアウトするときに行末の LF を CRLF に自動変換してくれます。
$ git config --global core.autocrlf true
Linux や Mac などの行末に LF を使うシステムで作業をしている場合は、Git にチェックアウト時の自動変換をされてしまうと困ります。しかし、行末が CRLF なファイルが紛れ込んでしまった場合には Git に自動修正してもらいたいものです。コミット時の CRLF から LF への変換はさせたいけれどもそれ以外の自動変換が不要な場合は、core.autocrlf
を input に設定します。
$ git config --global core.autocrlf input
この設定は、Windows にチェックアウトしたときの CRLF への変換は行いますが、Mac や Linux へのチェックアウト時は LF のままにします。またリポジトリにコミットする際には LF への変換を行います。
Windows のみのプロジェクトで作業をしているのなら、この機能を無効にしてキャリッジリターンをそのままリポジトリに記録してもよいでしょう。その場合は、値 false
を設定します。
$ git config --global core.autocrlf false
core.whitespace
Git には、空白文字に関する問題を見つけて修正するための設定もあります。空白文字に関する主要な四つの問題に対応するもので、そのうち二つはデフォルトで有効になっています。残りの二つはデフォルトでは有効になっていませんが、有効化することができます。
デフォルトで有効になっている設定は、行末の空白文字を見つける trailing-space
と行頭のタブ文字より前にある空白文字を見つける space-before-tab
です。
デフォルトでは無効だけれども有効にすることもできる設定は、行頭にある八文字以上の空白文字を見つける indent-with-non-tab
と行末のキャリッジリターンを許容する cr-at-eol
です。
これらのオン・オフを切り替えるには、core.whitespace
にカンマ区切りで項目を指定します。無効にしたい場合は、設定文字列でその項目を省略するか、あるいは項目名の前に -
をつけます。たとえば cr-at-eol
以外のすべてを設定したい場合は、このようにします。
$ git config --global core.whitespace \
trailing-space,space-before-tab,indent-with-non-tab
git diff
コマンドを実行したときに Git がこれらの問題を検出すると、その部分を色付けして表示します。修正してからコミットするようにしましょう。この設定は、git apply
でパッチを適用する際にも助けとなります。空白に関する問題を含むパッチを適用するときに警告を発してほしい場合には、次のようにします。
$ git apply --whitespace=warn <patch>
あるいは、問題を自動的に修正してからパッチを適用したい場合は、次のようにします。
$ git apply --whitespace=fix <patch>
これらの設定は、リベースのオプションにも適用されます。空白に関する問題を含むコミットをしたけれどまだそれを公開リポジトリにプッシュしていない場合は、rebase
に --whitespace=fix
オプションをつけて実行すれば、パッチを書き換えて空白問題を自動修正してくれます。
サーバーの設定
Git のサーバー側の設定オプションはそれほど多くありませんが、いくつか興味深いものがあるので紹介します。
receive.fsckObjects
デフォルトでは、Git はプッシュで受け取ったオブジェクトの一貫性をチェックしません。各オブジェクトの SHA-1 チェックサムが一致していて有効なオブジェクトを指しているということを Git にチェックさせることもできますが、デフォルトでは毎回のプッシュ時のチェックは行わないようになっています。このチェックは比較的重たい処理であり、リポジトリのサイズが大きかったりプッシュする量が多かったりすると、毎回チェックさせるのには時間がかかるでしょう。毎回のプッシュの際に Git にオブジェクトの一貫性をチェックさせたい場合は、receive.fsckObjects
を true にして強制的にチェックさせるようにします。
$ git config --system receive.fsckObjects true
これで、Git がリポジトリの整合性を確認してからでないとプッシュが認められないようになります。壊れたデータをまちがって受け入れてしまうことがなくなりました。
receive.denyNonFastForwards
すでにプッシュしたコミットをリベースしてもう一度プッシュした場合、あるいはリモートブランチが現在指しているコミットを含まないコミットをプッシュしようとした場合は、プッシュが拒否されます。これは悪くない方針でしょう。しかしリベースの場合は、自分が何をしているのかをきちんと把握していれば、プッシュの際に -f
フラグを指定して強制的にリモートブランチを更新することができます。
このような強制更新機能を無効にするには、receive.denyNonFastForwards
を設定します。
$ git config --system receive.denyNonFastForwards true
もうひとつの方法として、サーバー側の receive フックを使うこともできます。こちらの方法については後ほど簡単に説明します。receive フックを使えば、特定のユーザーだけ強制更新を無効にするなどより細やかな制御ができるようになります。
receive.denyDeletes
denyNonFastForwards
の制限を回避する方法として、いったんブランチを削除してから新しいコミットを参照するブランチをプッシュしなおすことができます。その対策として、新しいバージョン (バージョン 1.6.1 以降) の Git では receive.denyDeletes
を true に設定することができます。
$ git config --system receive.denyDeletes true
これは、プッシュによるブランチやタグの削除を一切拒否し、誰も削除できないようにします。リモートブランチを削除するには、サーバー上の ref ファイルを手で削除しなければなりません。ACL を使って、ユーザー単位でこれを制限することもできますが、その方法は本章の最後で扱います。