-
1. 使い始める
- 1.1 バージョン管理に関して
- 1.2 Git略史
- 1.3 Gitの基本
- 1.4 コマンドライン
- 1.5 Gitのインストール
- 1.6 最初のGitの構成
- 1.7 ヘルプを見る
- 1.8 まとめ
-
2. Git の基本
- 2.1 Git リポジトリの取得
- 2.2 変更内容のリポジトリへの記録
- 2.3 コミット履歴の閲覧
- 2.4 作業のやり直し
- 2.5 リモートでの作業
- 2.6 タグ
- 2.7 Git エイリアス
- 2.8 まとめ
-
3. Git のブランチ機能
- 3.1 ブランチとは
- 3.2 ブランチとマージの基本
- 3.3 ブランチの管理
- 3.4 ブランチでの作業の流れ
- 3.5 リモートブランチ
- 3.6 リベース
- 3.7 まとめ
-
4. Gitサーバー
- 4.1 プロトコル
- 4.2 サーバー用の Git の取得
- 4.3 SSH 公開鍵の作成
- 4.4 サーバーのセットアップ
- 4.5 Git デーモン
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 サードパーティによる Git ホスティング
- 4.10 まとめ
-
5. Git での分散作業
- 5.1 分散作業の流れ
- 5.2 プロジェクトへの貢献
- 5.3 プロジェクトの運営
- 5.4 まとめ
-
6. GitHub
- 6.1 アカウントの準備と設定
- 6.2 プロジェクトへの貢献
- 6.3 プロジェクトのメンテナンス
- 6.4 組織の管理
- 6.5 スクリプトによる GitHub の操作
- 6.6 まとめ
-
7. Git のさまざまなツール
- 7.1 リビジョンの選択
- 7.2 対話的なステージング
- 7.3 作業の隠しかたと消しかた
- 7.4 作業内容への署名
- 7.5 検索
- 7.6 歴史の書き換え
- 7.7 リセットコマンド詳説
- 7.8 高度なマージ手法
- 7.9 Rerere
- 7.10 Git によるデバッグ
- 7.11 サブモジュール
- 7.12 バンドルファイルの作成
- 7.13 Git オブジェクトの置き換え
- 7.14 認証情報の保存
- 7.15 まとめ
-
8. Git のカスタマイズ
- 8.1 Git の設定
- 8.2 Git の属性
- 8.3 Git フック
- 8.4 Git ポリシーの実施例
- 8.5 まとめ
-
9. Gitとその他のシステムの連携
- 9.1 Git をクライアントとして使用する
- 9.2 Git へ移行する
- 9.3 まとめ
-
10. Gitの内側
- 10.1 配管(Plumbing)と磁器(Porcelain)
- 10.2 Gitオブジェクト
- 10.3 Gitの参照
- 10.4 Packfile
- 10.5 Refspec
- 10.6 転送プロトコル
- 10.7 メンテナンスとデータリカバリ
- 10.8 環境変数
- 10.9 まとめ
-
A1. 付録 A: その他の環境でのGit
- A1.1 グラフィカルインタフェース
- A1.2 Visual StudioでGitを使う
- A1.3 EclipseでGitを使う
- A1.4 BashでGitを使う
- A1.5 ZshでGitを使う
- A1.6 PowershellでGitを使う
- A1.7 まとめ
-
A2. 付録 B: Gitをあなたのアプリケーションに組み込む
- A2.1 Gitのコマンドラインツールを使う方法
- A2.2 Libgit2を使う方法
- A2.3 JGit
-
A3. 付録 C: Gitのコマンド
- A3.1 セットアップと設定
- A3.2 プロジェクトの取得と作成
- A3.3 基本的なスナップショット
- A3.4 ブランチとマージ
- A3.5 プロジェクトの共有とアップデート
- A3.6 検査と比較
- A3.7 デバッグ
- A3.8 パッチの適用
- A3.9 メール
- A3.10 外部システム
- A3.11 システム管理
- A3.12 配管コマンド
8.1 Git のカスタマイズ - Git の設定
ここまで本書では、Git の基本動作やその使用法について扱ってきました。また、Git をより簡単に効率よく使うためのさまざまなツールについても紹介しました。 本章では、重要な設定項目やフックシステムを使用して、よりカスタマイズされた方法で Git を操作する方法について扱います。 これらを利用すれば、みなさん自身やその勤務先、所属グループのニーズにあわせた方法で Git を活用できるようになるでしょう。
Git の設定
[ch01-introduction] で手短にごらんいただいたように、git config
コマンドで Gitの設定が行えます。
最初にすることと言えば、名前とメールアドレスの設定でしょう。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
ここでは、同じようにして設定できるより興味深い項目をいくつか身につけ、Git をカスタマイズしてみましょう。
まず、簡単におさらいしましょう。Git では、いくつかの設定ファイルを使ってデフォルト以外の挙動を定義します。
最初に Git が見るのは /etc/gitconfig
で、ここにはシステム上の全ユーザーの全リポジトリ向けの設定値を記述します。
git config
にオプション --system
を指定すると、このファイルの読み書きを行います。
次に Git が見るのは ~/.gitconfig
(または ~/.config/git/config
)で、これは各ユーザー専用のファイルです。
Git でこのファイルの読み書きをするには、--global
オプションを指定します。
最後に Git が設定値を探すのは、現在使用中のリポジトリの設定ファイル (.git/config
) です。
この値は、そのリポジトリだけで有効なものです。
これらの “レベル” (システム、グローバル、ローカル)の間では、いずれも後から読んだ値がその前の値を上書きします。したがって、たとえば .git/config
に書いた値は /etc/gitconfig
での設定よりも優先されます。
注記
|
Git の設定ファイルはプレーンテキストなので、これらのファイルを手動で編集し、正しい構文で内容を追加することで、上記のような設定を行うことも可能ですが、通常は |
基本的なクライアントのオプション
Git の設定オプションは、おおきく二種類に分類できます。クライアント側のオプションとサーバー側のオプションです。 大半のオプションは、クライアント側のもの、つまり個人的な作業環境を設定するためのものとなります。 大量の、本当に大量の オプションが使用できますが、ここでは、もっとも一般的で、もっともよく使われているものだけを取り上げます。 その他のオプションの多くは特定の場合にのみ有用なものなので、ここでは扱いません。 Git で使えるすべてのオプションを知りたい場合は、次のコマンドを実行しましょう。
$ man git-config
このコマンドは、利用できるすべてのオプションを、簡単な説明とともに一覧表示します。 この内容は、 http://git-scm.com/docs/git-config.html にあるリファレンスでも見ることができます。
core.editor
デフォルトでは、コミットやタグのメッセージを編集するときには、ユーザーがデフォルトエディタとして設定したエディタ( $VISUAL
または $EDITOR
)が使われます。デフォルトエディタが設定されていない場合は vi エディタが使われます。
このデフォルト設定を別のものに変更するには core.editor
を設定します。
$ git config --global core.editor emacs
これで、シェルのデフォルトエディタに関係なく、Git でメッセージを編集する際には Emacs が起動されるようになりました。
commit.template
システム上のファイルへのパスをここに設定すると、Git はそのファイルをコミット時のデフォルトメッセージとして使います。
たとえば、次のようなテンプレートファイルを作って ~/.gitmessage.txt
においたとしましょう。
subject line
what happened
[ticket: X]
git commit
のときにエディタに表示されるデフォルトメッセージをこれにするには、commit.template
の設定を変更します。
$ git config --global commit.template ~/.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
署名入りの注釈付きタグ (作業内容への署名 で取り上げました) を作る場合は、GPG 署名用の鍵を登録しておくと便利です。 鍵の ID を設定するには、このようにします。
$ git config --global user.signingkey <gpg-key-id>
これで、git tag
コマンドでいちいち鍵を指定しなくてもタグに署名できるようになりました。
$ git tag -s <tag-name>
core.excludesfile
プロジェクトごとの .gitignore
ファイルでパターンを指定すると、git add
したときに Git がそのファイルを無視してステージしないようになります。これについては ファイルの無視 で説明しました。
ですが、作業中のすべてのリポジトリで、ある特定のファイルを無視したい場合もあります。
Mac OS X を使っているのなら、 .DS_Store
というファイルに見おぼえがあるでしょう。
使っているエディタが Emacs か Vim なら、 ~
で終わるファイルのことを知っていることと思います。
このような設定を行うには、グローバルな .gitignore
のようなファイルが必要です。
~/.gitignore_global
ファイルへ次の内容を書き込んで、
*~
.DS_Store
その上で git config --global core.excludesfile ~/.gitignore_global
を実行すれば、これらのファイルで手を煩わすことは二度となくなります。
help.autocorrect
Git でコマンドを打ち間違えると、こんなふうに表示されます。
$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.
Did you mean this?
checkout
Git は気を利かせて、何をしたかったのか推測はしてくれますが、実行まではしません。
help.autocorrect
を 1 にしておくと、 Git は実際にそのコマンドを実行しようとします。
$ git chekcout master
WARNING: You called a Git command named 'chekcout', which does not exist.
Continuing under the assumption that you meant 'checkout'
in 0.1 seconds automatically...
“0.1 seconds” という箇所に注目してください。 help.autocorrect
は整数値で、0.1秒単位での時間を表しています。
そのため、仮に 50 を設定したなら、自動修正したコマンドが実行される前に 5 秒の猶予が与えられます。
Git における色
Git では、ターミナルへの出力に色をつけることができます。ぱっと見て、すばやくお手軽に出力内容を把握できるようになるでしょう。 さまざまなオプションで、お好みに合わせて色を設定しましょう。
color.ui
Git は自動的に大半の出力に色づけをします。ですが、この挙動が気に入らないなら、そのためのマスタースイッチがあります。 ターミナルへの出力への色付けをすべてオフにするなら、以下のようにします。
$ git config --global color.ui false
デフォルトの設定は auto
で、直接ターミナルへ出力する場合には色付けを行いますが、パイプやファイルへリダイレクトした場合にはカラーコントロールコードを出力しません。
また always
を指定すると、ターミナルであってもパイプであっても色をつけます。
always
を使うことは、まずないでしょう。たいていの場合は、カラーコードを含む結果をリダイレクトしたければ、 Git コマンドに --color
フラグを渡せばカラーコードの使用を強制できます。
ふだんはデフォルトの設定で要望を満たせるでしょう。
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
(文字と背景の色を逆にする)のいずれかを指定できます。
外部のマージツールおよび diff ツール
Git には、内部的な diff の実装が組み込まれています。本書でこれまで見てきた内容は、それを使用しています。ですが、外部のツールを使うよう設定することもできます。 また、コンフリクトを手動で解決するのではなくグラフィカルなコンフリクト解消ツールを使うよう設定することもできます。 ここでは Perforce Visual Merge Tool (P4Merge) を使って diff の表示とマージの処理を行えるようにする例を示します。これはすばらしいグラフィカルツールで、しかも無料で使えるからです。
P4Merge はすべての主要プラットフォーム上で動作するので、実際に試してみたい人は試してみるとよいでしょう。
この例では、Mac や Linux 形式のパス名を例に使います。Windows の場合は、/usr/local/bin
のところを環境に合わせたパスに置き換えてください。
まず、P4Merge を からダウンロードします。
次に、コマンドを実行するための外部ラッパースクリプトを用意します。
この例では、Mac 用の実行パスを使います。他のシステムで使う場合は、p4merge
のバイナリがインストールされた場所に置き換えてください。
次のような内容のマージ用ラッパースクリプト extMerge
を用意してください。これは、 p4merge
にすべての引数を渡して呼び出します。
$ 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.<tool>.cmd
でそのコマンドを実行する方法を指定し、mergetool.<tool>.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.extMerge.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
すべて設定し終えたら、このような diff コマンドを実行すると、
$ git diff 32d1776b1^ 32d1776b1
結果をコマンドラインに出力するかわりに、Git から 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 にはさまざまなマージツール用の設定が事前に準備されており、特に設定しなくても利用できます。 サポートされているツールを確認するには、次のコマンドを実行します。
$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
emerge
gvimdiff
gvimdiff2
opendiff
p4merge
vimdiff
vimdiff2
The following tools are valid, but not currently available:
araxis
bc3
codecompare
deltawalker
diffmerge
diffuse
ecmerge
kdiff3
meld
tkdiff
tortoisemerge
xxdiff
Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.
KDiff3 を diff ツールとしてではなくマージのときにだけ使いたい場合は、kdiff3 コマンドにパスが通っている状態で次のコマンドを実行します。
$ git config --global merge.tool kdiff3
extMerge
や extDiff
を準備せずにこのコマンドを実行すると、マージの解決の際には KDiff3 を立ち上げて diff の際には通常の Git の diff ツールを使うようになります。
書式設定と空白文字
書式設定や空白文字の問題は微妙にうっとうしいもので、とくにさまざまなプラットフォームで開発している人たちと共同作業をするときに問題になりがちです。 使っているエディタが知らぬ間に空白文字を埋め込んでしまっていたり Windows で開発している人が行末にキャリッジリターンを付け加えてしまったりなどしてパッチが面倒な状態になってしまうことも多々あります。 Git では、こういった問題に対処するための設定項目も用意しています。
core.autocrlf
自分が Windows で開発している一方、チームの中に Windows 以外の環境で開発している人がいる場合(逆も同様)には、改行コードの問題に巻き込まれることがありがちです。 Windows ではキャリッジリターンとラインフィードでファイルの改行を表すのですが、Mac や Linux ではラインフィードだけで改行を表すという違いが原因です。 これはささいな違いではありますが、さまざまなプラットフォームにまたがる作業では非常に面倒なものです。Windows のエディタには、LFだけの改行をだまってCRLFに置き換えたり、ユーザがEnterキーを押下した際にCRとLFの両方を挿入したりするものが数多くあります。
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 のままにします。
Windows のみのプロジェクトで作業をしているのなら、この機能を無効にしてキャリッジリターンをそのままリポジトリに記録してもよいでしょう。その場合は、値 false
を設定します。
$ git config --global core.autocrlf false
core.whitespace
Git には、空白文字に関する問題を見つけて修正するための設定もあります。 空白文字に関する主要な六つの問題に対応するもので、そのうち三つはデフォルトで有効になっています。残りの三つはデフォルトでは有効になっていませんが、有効化することもできます。
デフォルトで有効になっている設定は、行末の空白文字を見つける blank-at-eol
、ファイル末尾の空白文字を見つける blank-at-eof
、行頭のタブ文字より前にある空白文字を見つける space-before-tab
です。
デフォルトでは無効だけれども有効にすることもできる三つの設定は、行頭がタブ文字でなく空白文字になっている行を見つける indent-with-non-tab
(空白文字の数は tabwidth
オプションで制御可能)、行内のインデント部分にあるタブ文字を見つける tab-in-indent
、行末のキャリッジリターンを許容する 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>
これらの設定は、git rebase
コマンドにも適用されます。
空白に関する問題を含むコミットをしたけれどまだそれを公開リポジトリにプッシュしていない場合は、 git rebase --whitespace=fix
を実行すれば、パッチを書き換えて空白問題を自動修正してくれます。
サーバーの設定
Git のサーバー側の設定オプションはそれほど多くありませんが、いくつか興味深いものがあるので紹介します。
receive.fsckObjects
デフォルトでは、Git はプッシュで受け取ったオブジェクトの SHA-1 チェックサムが一致していて有効なオブジェクトを指しているということをチェックさせることができます。
ですが、デフォルトではこのチェックは行わないようになっています。このチェックは比較的重たい処理であり、リポジトリのサイズが大きかったりプッシュする量が多かったりすると、毎回チェックさせるのには時間がかかるでしょう。
毎回のプッシュの際に 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
の制限を回避する方法として、いったんブランチを削除してから新しいコミットを参照するブランチをプッシュしなおすことができます。
これを無効にするには、 receive.denyDeletes
を true に設定します。
$ git config --system receive.denyDeletes true
これは、プッシュによるブランチやタグの削除を一切拒否し、誰も削除できないようにします。 リモートブランチを削除するには、サーバー上の ref ファイルを手で削除しなければなりません。ACL を使って、ユーザー単位でこれを制限することもできますが、その方法は Git ポリシーの実施例 で扱います。