-
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 スマート HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 サードパーティホスティングオプション
- 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 reset の解明
- 7.8 高度なマージ
- 7.9 rerere
- 7.10 Git を使ったデバッグ
- 7.11 サブモジュール
- 7.12 バンドリング
- 7.13 置換
- 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 内部コマンドと外部コマンド
- 10.2 Git オブジェクト
- 10.3 Git リファレンス
- 10.4 パックファイル
- 10.5 refspec
- 10.6 転送プロトコル
- 10.7 メンテナンスとデータ復旧
- 10.8 環境変数
- 10.9 まとめ
-
付録A. 付録 A: 他の環境での Git
- A1.1 グラフィカルインターフェース
- A1.2 Visual Studio での Git
- A1.3 Visual Studio Code での Git
- A1.4 IntelliJ/PyCharm/WebStorm/PhpStorm/RubyMine での Git
- A1.5 Sublime Text での Git
- A1.6 Bash での Git
- A1.7 Zsh での Git
- A1.8 PowerShell での Git
- A1.9 まとめ
-
付録B. 付録 B: アプリケーションへの Git の埋め込み
- A2.1 コマンドライン Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
付録C. 付録 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 を自分、会社、またはグループのニーズに正確に合わせるように簡単に設定できます。
Git の設定
「はじめに」で簡単に説明したように、`git config` コマンドを使用して Git の設定を指定できます。最初に行った操作の 1 つは、名前とメールアドレスを設定することでした。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
ここでは、この方法で設定できる、より興味深いオプションをいくつか学習して、Git の使用方法をカスタマイズします。
まず、簡単な復習です。Git は、一連の設定ファイルを使用して、必要となるデフォルト以外の動作を決定します。Git が最初にこれらの値を探す場所は、システム全体の `[path]/etc/gitconfig` ファイルです。このファイルには、システム上のすべてのユーザーとそのすべてのリポジトリに適用される設定が含まれています。`git config` に `--system` オプションを渡すと、このファイルの読み取りと書き込みが行われます。
次に Git が参照するのは `~/.gitconfig` (または `~/.config/git/config`) ファイルで、これは各ユーザーに固有です。`--global` オプションを渡すと、Git はこのファイルの読み取りと書き込みを行います。
最後に、Git は現在使用しているリポジトリの Git ディレクトリ(`.git/config`)にある設定ファイル内の設定値を探します。これらの値はその単一のリポジトリに固有であり、`git config` に `--local` オプションを渡すことを表します。どのレベルで作業するかを指定しない場合、これがデフォルトになります。
これらの各「レベル」(システム、グローバル、ローカル)は前のレベルの値を上書きするため、たとえば `.git/config` の値は `[path]/etc/gitconfig` の値よりも優先されます。
注記
|
Git の設定ファイルはプレーンテキストなので、ファイルを直接編集して正しい構文を挿入することで、これらの値を設定することもできます。ただし、一般的には `git config` コマンドを実行する方が簡単です。 |
基本的なクライアント設定
Git で認識される設定オプションは、クライアント側とサーバー側の 2 つのカテゴリに分類されます。オプションの大部分はクライアント側のもので、個人の作業環境を設定します。非常に多くの設定オプションがサポートされていますが、その多くは特定のエッジケースでのみ役立ちます。ここでは、最も一般的で便利なオプションのみを説明します。お使いのバージョンの Git で認識されるすべてのオプションのリストを確認するには、以下を実行します。
$ man git-config
このコマンドは、かなり詳細にすべての利用可能なオプションをリストします。このリファレンス資料は、https://git.dokyumento.jp/docs/git-config でも確認できます。
注記
|
高度なユースケースでは、上記ドキュメントで「条件付きインクルード」を参照することをお勧めします。 |
core.editor
デフォルトでは、Git はシェル環境変数 `VISUAL` または `EDITOR` のいずれかで設定されているデフォルトのテキストエディターを使用するか、そうでない場合は `vi` エディターにフォールバックして、コミットメッセージとタグメッセージを作成および編集します。このデフォルトを別のものに変更するには、`core.editor` 設定を使用できます。
$ git config --global core.editor emacs
デフォルトのシェルエディタの設定に関わらず、Gitはメッセージの編集にEmacsを起動します。
commit.template
この設定にシステム上のファイルのパスを設定すると、コミット時のデフォルトの初期メッセージとしてそのファイルが使用されます。カスタムコミットテンプレートを作成することの利点は、コミットメッセージの作成時に適切な形式とスタイルを自分自身(または他人)に思い出させることができる点です。
例えば、~/.gitmessage.txt
にあるようなテンプレートファイルがあるとします。
Subject line (try to keep under 50 characters)
Multi-line description of commit,
feel free to be detailed.
[Ticket: X]
このコミットテンプレートは、件名を短く保つこと(git log --oneline
の出力を簡潔にするため)、さらに詳細をその下に追加すること、そして存在する場合は課題またはバグトラッカーチケット番号を参照することをコミッターに思い出させます。
git commit
を実行したときにエディタに表示されるデフォルトのメッセージとしてこれを使用するようにGitに指示するには、commit.template
設定値を設定します。
$ git config --global commit.template ~/.gitmessage.txt
$ git commit
その後、コミット時にプレースホルダーのコミットメッセージとして、エディタには次のような内容が表示されます。
Subject line (try to keep under 50 characters)
Multi-line description of commit,
feel free to be detailed.
[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
この設定は、log
やdiff
などのGit出力ページャーを決定します。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がそれらを未追跡ファイルとして認識したり、git add
を実行したときにステージングしようとしたりすることを防ぐことができます。
しかし、作業するすべてのリポジトリで特定のファイルを無視したい場合があります。macOSを使用しているコンピューターの場合、.DS_Store
ファイルに精通しているかもしれません。お気に入りのエディタがEmacsまたはVimの場合、~
または.swp
で終わるファイル名について知っているでしょう。
この設定により、一種のグローバルな.gitignore
ファイルを作成できます。次のような内容の~/.gitignore_global
ファイルを作成した場合
*~
.*.swp
.DS_Store
…そしてgit config --global core.excludesfile ~/.gitignore_global
を実行すると、Gitはそれらのファイルについて二度と煩わしくなりません。
help.autocorrect
コマンドを誤って入力すると、次のようなメッセージが表示されます。
$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.
The most similar command is
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秒」という部分に注意してください。help.autocorrect
は実際には10分の1秒を表す整数です。したがって、これを50に設定すると、Gitは自動修正されたコマンドを実行する前に、5秒間の猶予を与えます。
Gitの色
Gitはカラーターミナル出力を完全にサポートしており、コマンド出力の視覚的な解析を迅速かつ容易に支援します。いくつかのオプションを使用すると、好みに合わせてカラーリングを設定できます。
color.ui
Gitはほとんどの出力を自動的にカラー化しますが、この動作が気に入らない場合はマスタースイッチがあります。Gitのカラーターミナル出力をすべてオフにするには、これを実行します。
$ git config --global color.ui false
デフォルト設定はauto
で、ターミナルに直接出力される場合は出力をカラー化しますが、出力がパイプまたはファイルにリダイレクトされる場合はカラー制御コードを省略します。
ターミナルとパイプの違いを無視するようにalways
に設定することもできます。これはめったに必要ありません。ほとんどの場合、リダイレクトされた出力にカラーコードが必要な場合は、代わりに--color
フラグをGitコマンドに渡して、カラーコードの使用を強制することができます。デフォルト設定はほとんどの場合、必要な設定です。
color.*
どのコマンドをどのようにカラー化するかについてより具体的に指定したい場合、Gitは動詞固有のカラー設定を提供します。これらはそれぞれ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
、dim
、ul
(下線)、blink
、reverse
(前景と背景の入れ替え)から選択できます。
外部マージとdiffツール
Gitにはdiffの内部実装がありますが(本書で紹介しているもの)、代わりに外部ツールを設定できます。また、手動で競合を解決する代わりに、グラフィカルなマージ競合解決ツールを設定することもできます。優れたグラフィカルツールであり、無料で利用できるPerforce Visual Merge Tool(P4Merge)をdiffとマージ解決に使用するための設定方法を示します。
試したい場合は、P4Mergeはすべての主要なプラットフォームで動作するため、実行できるはずです。例ではmacOSとLinuxシステムで動作するパス名を使用します。Windowsの場合は、/usr/local/bin
を実行可能ファイルのパスに変更する必要があります。
まず、PerforceからP4Mergeをダウンロードします。次に、コマンドを実行するための外部ラッパースクリプトを設定します。実行ファイルのmacOSパスを使用します。他のシステムでは、p4merge
バイナリがインストールされている場所になります。提供されたすべての引数でバイナリを呼び出すextMerge
というマージラッパースクリプトを設定します。
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*
diffラッパーは、7つの引数が提供されていることを確認し、そのうちの2つをマージスクリプトに渡します。デフォルトでは、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ツールを使用するように構成ファイルを設定できます。これには、使用する戦略をGitに指示するmerge.tool
、コマンドの実行方法を指定するmergetool.<tool>.cmd
、そのプログラムの終了コードが成功したマージ解決を示すかどうかをGitに指示するmergetool.<tool>.trustExitCode
、diffの実行コマンドをGitに指示するdiff.external
など、多数のカスタム設定が必要です。そのため、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
コマンドラインに出力されるdiffを取得する代わりに、GitはP4Mergeを起動し、次のような表示になります。

2つのブランチをマージしようとしてマージの競合が発生した場合は、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は、cmd構成を設定しなくても、他のマージ解決ツールをいくつか使用するためにプリセットされています。サポートされているツールのリストを確認するには、これを実行してみてください。
$ 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.
diffにKDiff3を使用するのではなく、マージ解決のみに使用したい場合、およびkdiff3コマンドがパスにある場合は、次を実行できます。
$ git config --global merge.tool kdiff3
extMerge
とextDiff
ファイルを設定する代わりにこれを実行すると、Gitはマージ解決にKDiff3を使用し、通常のGit diffツールをdiffに使用します。
フォーマットと空白
フォーマットと空白の問題は、特にクロスプラットフォームでのコラボレーション時に、多くの開発者が遭遇する、最もイライラする微妙な問題の1つです。パッチやその他のコラボレーション作業で微妙な空白の変更が導入されることは非常に簡単です。これは、エディタがそれらを黙って導入し、ファイルがWindowsシステムに触れた場合、改行が置き換えられる可能性があるためです。Gitには、これらの問題に対処するためのいくつかの構成オプションがあります。
core.autocrlf
Windowsでプログラミングしていて、そうでない人と協力している場合(またはその逆)、いつか改行の問題に遭遇する可能性があります。これは、Windowsがファイルの改行にキャリッジリターン文字とラインフィード文字の両方を使用するのに対し、macOSとLinuxシステムはラインフィード文字のみを使用するためです。これは、クロスプラットフォーム作業の微妙だが非常に厄介な事実です。Windowsの多くのエディタは、既存のLFスタイルの改行をCRLFに置き換えたり、ユーザーがEnterキーを押したときに改行文字を挿入したりします。
Gitは、ファイルをインデックスに追加するときにCRLF改行をLFに変換し、コードをファイルシステムにチェックアウトするときにその逆を行うことで、これに対処できます。core.autocrlf
設定を使用して、この機能を有効にすることができます。Windowsマシンを使用している場合は、true
に設定します。これにより、コードをチェックアウトするときにLF改行がCRLFに変換されます。
$ git config --global core.autocrlf true
LF改行を使用するLinuxまたはmacOSシステムを使用している場合は、ファイルをチェックアウトするときにGitが自動的に変換する必要はありません。ただし、CRLF改行のファイルが誤って導入された場合は、Gitが修正できるようにしたい場合があります。コミット時にCRLFをLFに変換するが、その逆は行わないようにGitに指示するには、core.autocrlf
をinput
に設定します。
$ git config --global core.autocrlf input
この設定により、WindowsチェックアウトではCRLF改行が、macOSとLinuxシステムおよびリポジトリではLF改行が残るはずです。
Windows専用のプロジェクトを作成しているWindowsプログラマーの場合は、この機能をオフにして、リポジトリにキャリッジリターンを記録できます。そのためには、構成値をfalse
に設定します。
$ git config --global core.autocrlf false
core.whitespace
Gitは、いくつかの空白の問題を検出して修正するようにプリセットされています。6つの主要な空白の問題を検出できます。そのうち3つはデフォルトで有効になっており、無効にすることができます。また、3つはデフォルトで無効になっていますが、有効にすることができます。
デフォルトでオンになっている3つは、行末のスペースを探すblank-at-eol
、ファイル末尾の空白行に気付くblank-at-eof
、行頭でタブの前にスペースを探すspace-before-tab
です。
デフォルトでは無効になっていますが、有効にできる3つは、タブの代わりにスペースで始まる行を探すindent-with-non-tab
(tabwidth
オプションで制御されます)、行のインデント部分のタブを監視するtab-in-indent
、行末のキャリッジリターンがOKであることをGitに指示するcr-at-eol
です。
有効にするものをGitに指示するには、core.whitespace
をオンまたはオフにしたい値に設定し、コンマで区切ります。オプションを無効にするには、名前の前に-
を付けるか、設定文字列から完全に削除してデフォルト値を使用します。たとえば、space-before-tab
以外のすべてを設定する場合は、次のように実行できます(trailing-space
はblank-at-eol
とblank-at-eof
の両方をカバーする省略形です)。
$ git config --global core.whitespace \
trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
または、カスタマイズ部分のみを指定することもできます。
$ git config --global core.whitespace \
-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
git diff
コマンドを実行すると、Gitはこれらの問題を検出し、色付けしてコミット前に修正できるようにします。また、これらの値を使用して、git apply
でパッチを適用する際にも役立ちます。パッチを適用する際、指定した空白に関する問題があるパッチを適用する場合に警告するようにGitに指示できます。
$ git apply --whitespace=warn <patch>
または、パッチを適用する前にGitが問題を自動的に修正しようとさせることもできます。
$ git apply --whitespace=fix <patch>
これらのオプションはgit rebase
コマンドにも適用されます。空白に関する問題をコミットしたが、まだアップストリームにプッシュしていない場合は、git rebase --whitespace=fix
を実行して、パッチを書き換える際にGitが空白の問題を自動的に修正させます。
サーバー設定
Gitのサーバー側では、利用可能な設定オプションはそれほど多くありませんが、いくつか注目すべき興味深いものがあります。
receive.fsckObjects
Gitは、プッシュ中に受信したすべてのオブジェクトがそのSHA-1チェックサムと一致し、有効なオブジェクトを指していることを確認できます。ただし、これはデフォルトでは行われません。これはかなりコストのかかる操作であり、特に大規模なリポジトリやプッシュでは操作速度を低下させる可能性があります。すべてのプッシュでGitにオブジェクトの一貫性をチェックさせたい場合は、receive.fsckObjects
をtrueに設定して強制的に実行できます。
$ git config --system receive.fsckObjects true
これで、各プッシュが受け入れられる前にGitはリポジトリの整合性をチェックし、故障した(または悪意のある)クライアントが破損したデータを持ち込まないようにします。
receive.denyNonFastForwards
既にプッシュしたコミットをリベースしてから再度プッシュしようとすると、またはリモートブランチが現在指しているコミットを含まないリモートブランチにコミットをプッシュしようとすると、拒否されます。これは一般的に良いポリシーですが、リベースの場合、自分のやっていることが分かっているため、プッシュコマンドに-f
フラグを使用してリモートブランチを強制的に更新できると判断する場合があります。
Gitに強制プッシュを拒否させるには、receive.denyNonFastForwards
を設定します。
$ git config --system receive.denyNonFastForwards true
これを行うもう一つの方法は、サーバー側の受信フックを使用することです(後ほど説明します)。この方法では、特定のユーザーのサブセットに対して非高速転送を拒否するなど、より複雑な処理を行うことができます。
receive.denyDeletes
denyNonFastForwards
ポリシーの回避策の1つは、ユーザーがブランチを削除してから、新しい参照で再度プッシュすることです。これを回避するには、receive.denyDeletes
をtrueに設定します。
$ git config --system receive.denyDeletes true
これにより、ブランチやタグの削除が拒否されます。どのユーザーも削除できません。リモートブランチを削除するには、サーバーからrefファイルを手動で削除する必要があります。ACLを使用して、ユーザーごとにこれを行うより興味深い方法もあります。詳しくはGitによるポリシー強制の例を参照してください。