-
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 配管コマンド
3.1 Git のブランチ機能 - ブランチとは
ほぼすべてと言っていいほどの VCS が、何らかの形式でブランチ機能に対応しています。 ブランチとは、開発の本流から分岐し、本流の開発を邪魔することなく作業を続ける機能のことです。 多くの VCS ツールでは、これは多少コストのかかる処理になっています。 ソースコードディレクトリを新たに作る必要があるなど、巨大なプロジェクトでは非常に時間がかかってしまうことがよくあります。
Git のブランチモデルは、Git の機能の中でもっともすばらしいものだという人もいるほどです。 そしてこの機能こそが Git を他の VCS とは一線を画すものとしています。 何がそんなにすばらしいのでしょう? Git のブランチ機能は圧倒的に軽量です。ブランチの作成はほぼ一瞬で完了しますし、ブランチの切り替えも高速に行えます。 その他大勢の VCS とは異なり、Git では頻繁にブランチ作成とマージを繰り返すワークフローを推奨しています。 一日に複数のブランチを切ることさえ珍しくありません。 この機能を理解して身につけることで、あなたはパワフルで他に類を見ないツールを手に入れることになります。 これは、あなたの開発手法を文字通り一変させてくれるでしょう。
ブランチとは
Git のブランチの仕組みについてきちんと理解するには、少し後戻りして Git がデータを格納する方法を知っておく必要があります。
[ch01-introduction] で説明したように、Git はチェンジセットや差分としてデータを保持しているのではありません。そうではなく、スナップショットとして保持しています。
Git にコミットすると、Git はコミットオブジェクトを作成して格納します。このオブジェクトには、あなたがステージしたスナップショットへのポインタや作者・メッセージのメタデータ、そしてそのコミットの直接の親となるコミットへのポインタが含まれています。最初のコミットの場合は親はいません。通常のコミットの場合は親がひとつ存在します。複数のブランチからマージした場合は、親も複数となります。
これを視覚化して考えるために、ここに 3 つのファイルを含むディレクトリがあると仮定しましょう。3 つのファイルをすべてステージしてコミットしたところです。ステージしたファイルについてチェックサム ([ch01-introduction] で説明した SHA-1 ハッシュ) を計算し、そのバージョンのファイルを Git ディレクトリに格納し (Git はファイルを blob として扱います)、そしてそのチェックサムをステージングエリアに追加します。
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'
git commit
を実行してコミットを作るときに、Git は各サブディレクトリ (今回の場合はルートディレクトリひとつだけ) のチェックサムを計算して、そのツリーオブジェクトを Git リポジトリに格納します。
それから、コミットオブジェクトを作ります。このオブジェクトは、コミットのメタデータとルートツリーへのポインタを保持しており、必要に応じてスナップショットを再作成できるようになります。
この時点で、Git リポジトリには 5 つのオブジェクトが含まれています。3 つのファイルそれぞれの中身をあらわす blob オブジェクト、ディレクトリの中身の一覧とどのファイルがどの blob に対応するかをあらわすツリーオブジェクト、そしてそのルートツリーおよびすべてのメタデータへのポインタを含むコミットオブジェクトです。
なんらかの変更を終えて再びコミットすると、次のコミットには直近のコミットへのポインタが格納されます。
Git におけるブランチとは、単にこれら三つのコミットを指す軽量なポインタに過ぎません。Git のデフォルトのブランチ名は master
です。最初にコミットした時点で、直近のコミットを指す master
ブランチが作られます。その後コミットを繰り返すたびに、このポインタは自動的に進んでいきます。
注記
|
Git の “master” ブランチは、特別なブランチというわけではありません。
その他のブランチと、何ら変わるところのないものです。
ほぼすべてのリポジトリが “master” ブランチを持っているたったひとつの理由は、
|
新しいブランチの作成
新しいブランチを作成したら、いったいどうなるのでしょうか?
単に新たな移動先を指す新しいポインタが作られるだけです。
では、新しい testing ブランチを作ってみましょう。
次の git branch
コマンドを実行します。
$ git branch testing
これで、新しいポインタが作られます。 現時点ではふたつのポインタは同じ位置を指しています。
Git は、あなたが今どのブランチで作業しているのかをどうやって知るのでしょうか?
それを保持する特別なポインタが HEAD
と呼ばれるものです。
これは、Subversion や CVS といった他の VCS における HEAD
の概念とはかなり違うものであることに注意しましょう。
Git では、HEAD はあなたが作業しているローカルブランチへのポインタとなります。
今回の場合は、あなたはまだ 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 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project
“master” と “testing” の両ブランチが、コミット f30ab
の横に表示されていることがわかります。
ブランチの切り替え
ブランチを切り替えるには git checkout
コマンドを実行します。
それでは、新しい testing
ブランチに移動してみましょう。
$ git checkout testing
これで、HEAD
は testing
ブランチを指すようになります。
それがどうしたって? では、ここで別のコミットをしてみましょう。
$ vim test.rb
$ git commit -a -m 'made a change'
興味深いことに、testing
ブランチはひとつ進みましたが master
ブランチは変わっていません。
git checkout
でブランチを切り替えたときの状態のままです。それでは master
ブランチに戻ってみましょう。
$ git checkout master
このコマンドは二つの作業をしています。
まず HEAD ポインタが指す先を master
ブランチに戻し、そして作業ディレクトリ内のファイルを master
が指すスナップショットの状態に戻します。
つまり、この時点以降に行った変更は、これまでのプロジェクトから分岐した状態になるということです。
これは、testing
ブランチで一時的に行った作業を巻き戻したことになります。
ここから改めて別の方向に進めるということになります。
注記
|
ブランチを切り替えると、作業ディレクトリのファイルが変更される
気をつけておくべき重要なこととして、Git でブランチを切り替えると、作業ディレクトリのファイルが変更されることを知っておきましょう。 古いブランチに切り替えると、作業ディレクトリ内のファイルは、最後にそのブランチ上でコミットした時点の状態まで戻ってしまいます。 Git がこの処理をうまくできない場合は、ブランチの切り替えができません。 |
それでは、ふたたび変更を加えてコミットしてみましょう。
$ vim test.rb
$ git commit -a -m 'made other changes'
これで、プロジェクトの歴史が二つに分かれました (分裂した歴史 を参照ください)。
新たなブランチを作成してそちらに切り替え、何らかの作業を行い、メインブランチに戻って別の作業をした状態です。
どちらの変更も、ブランチごとに分離しています。ブランチを切り替えつつそれぞれの作業を進め、必要に応じてマージすることができます。
これらをすべて、シンプルに branch
コマンドと checkout
コマンドそして commit
コマンドで行えるのです。
この状況を git log
コマンドで確認することもできます。
git log --oneline --decorate --graph --all
を実行すると、コミットの歴史を表示するだけではなく、
ブランチポインタがどのコミットを指しているのかや、歴史がどこで分裂したのかも表示します。
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
Git におけるブランチとは、実際のところ特定のコミットを指す 40 文字の SHA-1 チェックサムだけを記録したシンプルなファイルです。 したがって、ブランチを作成したり破棄したりするのは非常にコストの低い作業となります。 新たなブランチの作成は、単に 41 バイト (40 文字と改行文字) のデータをファイルに書き込むのと同じくらい高速に行えます。
これが他の大半の VCS ツールのブランチと対照的なところです。 他のツールでは、プロジェクトのすべてのファイルを新たなディレクトリにコピーしたりすることになります。 プロジェクトの規模にもよりますが、これには数秒から数分の時間がかかることでしょう。 Git ならこの処理はほぼ瞬時に行えます。 また、コミットの時点で親オブジェクトを記録しているので、マージの際にもどこを基準にすればよいのかを自動的に判断してくれます。 そのためマージを行うのも非常に簡単です。 これらの機能のおかげで、開発者が気軽にブランチを作成して使えるようになっています。
では、なぜブランチを切るべきなのかについて見ていきましょう。