-
1. Gitの始め方
- 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 Replace
- 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 パックファイル
- 10.5 リフスペック
- 10.6 転送プロトコル
- 10.7 メンテナンスとデータ復旧
- 10.8 環境変数
- 10.9 まとめ
-
A1. 付録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 まとめ
-
A2. 付録B: アプリケーションへのGitの組み込み
- A2.1 コマンドラインGit
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
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 Plumbingコマンド
8.3 Gitのカスタマイズ - Gitフック
Gitフック
他の多くのバージョン管理システムと同様に、Gitには特定の重要なアクションが発生したときにカスタムスクリプトを実行する方法があります。これらのフックには、クライアントサイドとサーバーサイドの2つのグループがあります。クライアントサイドのフックはコミットやマージなどの操作によってトリガーされ、サーバーサイドのフックはプッシュされたコミットの受信などのネットワーク操作で実行されます。これらのフックは、さまざまな目的で使用できます。
フックのインストール
フックはすべてGitディレクトリのhooks
サブディレクトリに保存されています。ほとんどのプロジェクトでは、それは.git/hooks
です。新しいリポジトリをgit init
で初期化すると、Gitはhooksディレクトリにたくさんのサンプルスクリプトを格納します。これらのスクリプトの多くはそれ自体で役立ちますが、それぞれのスクリプトの入力値も文書化されています。すべてのサンプルはシェルスクリプトとして書かれており、一部にはPerlも含まれていますが、適切な名前が付けられた実行可能なスクリプトであれば、RubyやPythonなど、使い慣れた言語で書かれていても問題なく動作します。付属のフックスクリプトを使用したい場合は、名前を変更する必要があります。それらのファイル名はすべて.sample
で終わっています。
フックスクリプトを有効にするには、.git
ディレクトリのhooks
サブディレクトリに、適切に命名され(拡張子なし)、実行可能であるファイルを配置します。それ以降、そのスクリプトが呼び出されるようになります。ここでは、主要なフックファイル名のほとんどを扱います。
クライアントサイドフック
クライアントサイドフックには多くの種類があります。このセクションでは、それらをコミットワークフローフック、メールワークフロースクリプト、およびその他のものに分類して説明します。
注
|
クライアントサイドフックはリポジトリをクローンしてもコピーされないことに注意することが重要です。これらのスクリプトでポリシーを強制しようとする場合は、おそらくサーバーサイドでそれを行うことになるでしょう。Gitによる強制ポリシーの例の例を参照してください。 |
コミットワークフローフック
最初の4つのフックはコミットプロセスに関連しています。
pre-commit
フックは、コミットメッセージを入力する前に最初に実行されます。このフックは、コミットしようとしているスナップショットを検査し、何か忘れ物がないか、テストが実行されているかを確認したり、コード内で検査する必要があるものを調べたりするために使用されます。このフックがゼロ以外のステータスで終了すると、コミットは中止されますが、git commit --no-verify
でバイパスすることもできます。コードスタイル(lint
などの実行)、末尾の空白(デフォルトのフックがこれを行います)、新しいメソッドの適切なドキュメントの確認などを行うことができます。
prepare-commit-msg
フックは、コミットメッセージエディタが起動される前で、デフォルトメッセージが作成された後に実行されます。これにより、コミット作成者がデフォルトメッセージを見る前に編集することができます。このフックはいくつかのパラメータを受け取ります:これまでのコミットメッセージを保持するファイルのパス、コミットのタイプ、そして修正コミットである場合はコミットのSHA-1です。このフックは通常、通常のコミットにはあまり有用ではありません。むしろ、テンプレート化されたコミットメッセージ、マージコミット、スカッシュされたコミット、修正コミットなど、デフォルトメッセージが自動生成されるコミットに有効です。コミットテンプレートと組み合わせて、プログラム的に情報を挿入するために使用することもできます。
commit-msg
フックは1つのパラメータを受け取ります。これは、開発者によって書かれたコミットメッセージを含む一時ファイルのパスです。このスクリプトがゼロ以外のステータスで終了すると、Gitはコミットプロセスを中止するため、コミットが実行される前にプロジェクトの状態やコミットメッセージを検証するために使用できます。この章の最後のセクションでは、このフックを使用して、コミットメッセージが必要なパターンに準拠しているかを確認する方法を実演します。
コミットプロセス全体が完了した後、post-commit
フックが実行されます。このフックはパラメータを取りませんが、git log -1 HEAD
を実行することで最後のコミットを簡単に取得できます。通常、このスクリプトは通知やそれに類する目的で使用されます。
メールワークフローフック
メールベースのワークフローには、3つのクライアントサイドフックを設定できます。これらはすべてgit am
コマンドによって呼び出されるため、ワークフローでこのコマンドを使用しない場合は、次のセクションに安全にスキップできます。git format-patch
で作成されたパッチをメールで受け取る場合は、これらのいくつかが役に立つかもしれません。
最初に実行されるフックはapplypatch-msg
です。これは単一の引数、すなわち提案されたコミットメッセージを含む一時ファイルの名前を受け取ります。このスクリプトがゼロ以外のステータスで終了すると、Gitはパッチ適用を中止します。これを使用して、コミットメッセージが適切にフォーマットされていることを確認したり、スクリプトでメッセージをその場で編集して正規化したりすることができます。
git am
を介してパッチを適用するときに次に実行されるフックはpre-applypatch
です。少し紛らわしいですが、これはパッチが適用された後、コミットが行われる前に実行されるため、コミットを行う前にスナップショットを検査するために使用できます。このスクリプトでテストを実行したり、作業ツリーを検査したりすることができます。何かが不足している場合やテストがパスしない場合、ゼロ以外のステータスで終了すると、パッチをコミットせずにgit am
スクリプトが中止されます。
git am
操作中に最後に実行されるフックはpost-applypatch
で、コミットが行われた後に実行されます。これを使用して、取り込んだパッチのグループまたは作者に完了を通知できます。このスクリプトでパッチ適用プロセスを停止することはできません。
その他のクライアントフック
pre-rebase
フックは、リベースを行う前に実行され、ゼロ以外のステータスで終了することでプロセスを停止できます。このフックを使用して、すでにプッシュされたコミットのリベースを禁止することができます。Gitがインストールするpre-rebase
の例はこれを行いますが、あなたのワークフローに合わない仮定をしている場合があります。
post-rewrite
フックは、git commit --amend
やgit rebase
など、コミットを置き換えるコマンドによって実行されます(ただしgit filter-branch
では実行されません)。単一の引数として書き換えをトリガーしたコマンドを受け取り、stdin
を通じて書き換えのリストを受け取ります。このフックは、post-checkout
やpost-merge
フックと多くの点で同じ用途があります。
git checkout
が成功した後、post-checkout
フックが実行されます。これを使用して、プロジェクト環境に合わせて作業ディレクトリを適切にセットアップできます。これは、バージョン管理したくない大きなバイナリファイルを移動したり、ドキュメントを自動生成したりするようなことを意味するかもしれません。
post-merge
フックは、merge
コマンドが成功した後に実行されます。これを使用して、パーミッションデータなど、Gitが追跡できない作業ツリー内のデータを復元できます。このフックはまた、作業ツリーが変更されたときにコピーしたいGit管理外のファイルの存在を検証することもできます。
pre-push
フックはgit push
の実行中に、リモート参照が更新された後、オブジェクトが転送される前に実行されます。リモートの名前と場所をパラメータとして受け取り、更新される参照のリストをstdin
を通じて受け取ります。プッシュが行われる前に、一連の参照更新を検証するためにこれを使用できます(ゼロ以外の終了コードはプッシュを中止します)。
Gitは、通常の操作の一環として、git gc --auto
を呼び出すことで、時々ガベージコレクションを行います。pre-auto-gc
フックは、ガベージコレクションが行われる直前に呼び出され、これが実行されていることを通知したり、都合が悪い場合はコレクションを中止したりするために使用できます。
サーバーサイドフック
クライアントサイドフックに加えて、システム管理者としていくつかの重要なサーバーサイドフックを使用して、プロジェクトにほとんどあらゆる種類のポリシーを強制することができます。これらのスクリプトは、サーバーへのプッシュの前後に実行されます。プリフックはいつでもゼロ以外のステータスで終了することでプッシュを拒否し、クライアントにエラーメッセージを返すことができます。これにより、任意の複雑さのプッシュポリシーを設定できます。
pre-receive
クライアントからのプッシュを処理する際に最初に実行されるスクリプトはpre-receive
です。これは標準入力からプッシュされている参照のリストを受け取ります。もしゼロ以外のステータスで終了した場合、それらの参照はどれも受け入れられません。このフックを使用して、更新される参照が非ファストフォワードでないことを確認したり、プッシュで変更されるすべての参照やファイルへのアクセス制御を行ったりすることができます。
update
update
スクリプトはpre-receive
スクリプトと非常によく似ていますが、プッシュ者が更新しようとしている各ブランチに対して一度ずつ実行される点が異なります。プッシュ者が複数のブランチにプッシュしようとしている場合、pre-receive
は一度だけ実行されますが、update
はプッシュ先のブランチごとに一度ずつ実行されます。このスクリプトは標準入力から読み取る代わりに、3つの引数を受け取ります:参照(ブランチ)の名前、プッシュ前にその参照が指していたSHA-1、およびユーザーがプッシュしようとしているSHA-1です。もしupdate
スクリプトがゼロ以外のステータスで終了した場合、その参照だけが拒否され、他の参照は引き続き更新できます。
post-receive
post-receive
フックは、プロセス全体が完了した後に実行され、他のサービスを更新したり、ユーザーに通知したりするために使用できます。これはpre-receive
フックと同じ標準入力データを受け取ります。例としては、リストへのメール送信、継続的インテグレーションサーバーへの通知、チケット追跡システムの更新などがあります。コミットメッセージを解析して、開く、変更する、閉じる必要があるチケットがあるかどうかを確認することもできます。このスクリプトはプッシュプロセスを停止することはできませんが、完了するまでクライアントは切断されないため、時間がかかる可能性のあることを試す場合は注意が必要です。
ヒント
|
他の人が読む必要があるスクリプトやフックを作成する場合は、コマンドラインフラグの長いバージョンを使用することを推奨します。半年後にはきっと私たちに感謝するでしょう。 |