-
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 リセットの解明
- 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. その他の環境での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. アプリケーションへのGitの埋め込み
- A2.1 コマンドラインGit
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
付録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 内部コマンド
3.1 Gitブランチ - ブランチ入門
ほぼすべてのバージョン管理システム(VCS)は、何らかの形のブランチサポートを持っています。ブランチとは、開発のメインラインから分岐し、メインラインを混乱させることなく作業を続けることを意味します。多くのVCSツールでは、これはややコストのかかるプロセスであり、多くの場合、ソースコードディレクトリの新しいコピーを作成する必要があるため、大規模なプロジェクトでは時間がかかります。
Gitのブランチモデルを「キラー機能」と呼ぶ人もいますが、それは確かにGitをVCSコミュニティの中で際立たせています。なぜこれほどまでに特別な機能なのでしょうか?Gitのブランチ作成方法は非常に軽量であるため、ブランチ操作はほぼ瞬時に行われ、ブランチ間の切り替えも同様に高速です。他の多くのVCSとは異なり、Gitは1日に複数回でも、頻繁にブランチを作成してマージするワークフローを推奨しています。この機能を理解し習得することで、強力で独自のツールが手に入り、開発方法を完全に変えることができます。
ブランチ入門
Gitのブランチ作成方法を本当に理解するには、一歩下がってGitがどのようにデータを保存しているかを調べることが必要です。
Gitとは何か?で説明したように、Gitは変更セットや差分としてデータを保存するのではなく、一連のスナップショットとしてデータを保存します。
コミットを作成すると、Gitはステージングしたコンテンツのスナップショットへのポインタを含むコミットオブジェクトを保存します。このオブジェクトには、作成者の名前とメールアドレス、入力したメッセージ、そしてこのコミットの直前にあるコミット(親コミット)へのポインタも含まれています。最初のコミットには親コミットが0個、通常のコミットには1個、2つ以上のブランチのマージによって生成されるコミットには複数個の親コミットがあります。
これを視覚化するために、3つのファイルを含むディレクトリがあり、それらをすべてステージングしてコミットすると仮定しましょう。ファイルをステージングすると、それぞれについてチェックサム(Gitとは何か?で説明したSHA-1ハッシュ)が計算され、そのファイルのバージョンがGitリポジトリに保存され(Gitではblobと呼ばれます)、そのチェックサムがステージングエリアに追加されます。
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
git commit
を実行してコミットを作成すると、Gitは各サブディレクトリ(この場合はルートプロジェクトディレクトリのみ)のチェックサムを計算し、Gitリポジトリにツリーオブジェクトとして保存します。次にGitは、メタデータとルートプロジェクトツリーへのポインタを持つコミットオブジェクトを作成します。これにより、必要に応じてそのスナップショットを再作成できます。
Gitリポジトリには、5つのオブジェクトが保存されます。3つのblob(それぞれ3つのファイルのいずれかのコンテンツを表す)、ディレクトリのコンテンツをリストし、どのファイル名がどのblobとして保存されているかを指定する1つのtree、そしてそのルートツリーとすべてのコミットメタデータへのポインタを持つ1つのcommitです。

変更を加えて再度コミットすると、次のコミットはその直前にあったコミットへのポインタを保存します。

Gitにおけるブランチは、単にこれらのコミットのいずれかへの軽量で移動可能なポインタです。Gitのデフォルトのブランチ名はmaster
です。コミットを始めると、最後に作成したコミットを指すmaster
ブランチが与えられます。コミットするたびに、master
ブランチポインタは自動的に前方に移動します。
注記
|
Gitの "master" ブランチは特別なブランチではありません。他のブランチと全く同じです。ほとんどのリポジトリにmasterブランチが存在する唯一の理由は、 |

新しいブランチの作成
新しいブランチを作成すると何が起こるのでしょうか?それは、移動するための新しいポインタを作成することです。例えば、testing
という新しいブランチを作成したいとします。これはgit branch
コマンドで行います。
$ git branch testing
これにより、現在いるのと同じコミットへの新しいポインタが作成されます。

Gitは現在どのブランチにいるかをどのように認識するのでしょうか?それはHEAD
と呼ばれる特別なポインタを保持しています。これは、SubversionやCVSなど、あなたが慣れている他のVCSのHEAD
の概念とは大きく異なることに注意してください。Gitでは、これは現在いるローカルブランチへのポインタです。この場合、あなたはまだmaster
ブランチ上にいます。git branch
コマンドは新しいブランチを作成しただけで、そのブランチに切り替えたわけではありません。

これは、ブランチポインタがどこを指しているかを示す単純なgit log
コマンドを実行することで簡単に確認できます。このオプションは--decorate
と呼ばれます。
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
f30ab
コミットのすぐ隣にmaster
とtesting
ブランチがあることがわかります。
ブランチの切り替え
既存のブランチに切り替えるには、git checkout
コマンドを実行します。新しいtesting
ブランチに切り替えてみましょう。
$ git checkout testing
これにより、HEAD
がtesting
ブランチを指すように移動します。

その意味は何でしょうか?では、もう一つのコミットを行いましょう。
$ vim test.rb
$ git commit -a -m 'Make a change'

これは興味深いことです。なぜなら、これでtesting
ブランチは先に進みましたが、master
ブランチはまだ、ブランチを切り替えるためにgit checkout
を実行したときのコミットを指しているからです。master
ブランチに戻りましょう。
$ git checkout master
注記
|
git log は常にすべてのブランチをすべて表示するわけではありません今すぐ ブランチが消えたわけではありません。Gitは単に、あなたがそのブランチに関心を持っていることを知らず、あなたが関心を持っていると思っているものを表示しようとしているだけです。言い換えれば、デフォルトでは、 目的のブランチのコミット履歴を表示するには、明示的に指定する必要があります: |

このコマンドは2つのことを行いました。HEADポインタをmaster
ブランチを指すように戻し、作業ディレクトリのファイルをmaster
が指すスナップショットに戻しました。これはまた、この時点以降に行う変更は、プロジェクトの古いバージョンとは異なるようになることを意味します。本質的に、testing
ブランチで行った作業を巻き戻して、別の方向に進めることができます。
注記
|
ブランチを切り替えると、作業ディレクトリのファイルが変更されます
Gitでブランチを切り替えると、作業ディレクトリのファイルが変更されることに注意することが重要です。古いブランチに切り替えると、作業ディレクトリはそのブランチで最後にコミットしたときのように戻されます。Gitがきれいに実行できない場合、切り替えは許可されません。 |
いくつかの変更を加えて、再度コミットしてみましょう。
$ vim test.rb
$ git commit -a -m 'Make other changes'
これで、プロジェクトの履歴は分岐しました(分岐履歴を参照)。ブランチを作成して切り替え、そこで作業を行い、メインブランチに戻って別の作業を行いました。これらの変更は、それぞれ別のブランチに隔離されています。ブランチ間を自由に切り替えることができ、準備ができたらマージできます。そして、それらすべてを単純なbranch
、checkout
、commit
コマンドで行いました。

git log --oneline --decorate --graph --all
コマンドでも簡単に確認できます。このコマンドを実行すると、コミットの履歴が出力され、ブランチポインタの位置と履歴の分岐場所が表示されます。
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Make other changes
| * 87ab2 (testing) Make a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commit of my project
Gitのブランチは実際には、それが指すコミットの40文字のSHA-1チェックサムを含む単純なファイルであるため、ブランチの作成と削除は安価です。新しいブランチの作成は、ファイルに41バイト(40文字と改行)を書くのと同じくらい迅速かつ簡単です。
これは、プロジェクトのすべてのファイルを第2のディレクトリにコピーすることを伴う、ほとんどの古いVCSツールがブランチを行う方法とは対照的です。プロジェクトのサイズによっては、数秒から数分かかる場合がありますが、Gitでは常に瞬間的です。また、コミット時に親を記録しているため、マージのための適切なマージベースの検索は自動的に行われ、一般的に非常に簡単に行えます。これらの機能は、開発者が頻繁にブランチを作成して使用することを促します。
その理由を見てみましょう。
注記
|
新しいブランチの作成と同時に切り替え
新しいブランチを作成し、同時にその新しいブランチに切り替えたいことは一般的です。これは、 |
注記
|
Gitバージョン2.23以降では、
|