git branch コマンド:作成、削除、チェックアウト、リスト、名前の変更、オプション
この投稿では、ブランチを正しく理解する方法と、git branch
コマンドを使ったブランチの作成、削除、変更、検証、名前の変更、その他のオプションについて説明します。
1. git branch を理解する
ブランチは、Git における共同作業の重要な機能です。 従来のファイルシステムでは、同じファイルを同時に修正したい場合は、コピーを作って別々に修正し、手作業でマージして元に戻すしかありませんでした。 ブランチを使えば、Gitは同じファイルに対して異なる操作を同時に行うことができます。
この便利な機能の原理は、実はとてもシンプルです。 前回の git add や git commit で、ひとつのコミットに関する情報を格納するコミットオブジェクトは、その親コミットの ID を持っていると述べました。 コミットの履歴は、最終的に各コミットの親コミットの ID でリンクされます。
ブランチは、このコミット履歴の直近のコミットを指す名前タグにすぎません。
main
ブランチで作業している場合、mainというブランチ名には現在のコミット履歴の最後のコミットIDが入ります。
これは、次の画像のようになります。
コミット B はコミット A の ID である 2b89
を知っているので、この 2 つのコミットを履歴でつなげることができます。
そして、main
という名前のブランチはコミット B の ID 991b
を知っており、そのヒストリの最後のコミットなので、現在のブランチを main
と呼ぶことにします。
現在のブランチで新しいコミットを行うと、main
タグの最後のコミットIDが新しいコミットIDに変更されます。
これは、次のようになります。
こうすることで、ブランチ機能の実装に使用する情報は最後のコミット ID だけとなります。 そして、次のセクションで説明するブランチの変更も、ブランチリストの iD に基づいて適切なコミットにジャンプするだけです。
新しいブランチを作成し、そのブランチに新しいコミットを行うとすると、次のようになります。
main
ブランチに topicA
という名前の新しいブランチを作成すると、main
と topicA
の両方が v274
を指すようになります。
topicA
ブランチに新しいコミットを作成すると、topicA
ブランチはコミット D の ID 1g8c
を指すようになります。
この状況では、main
ブランチに切り替えるとコミット C を指すようになり、topicA
ブランチに戻すとコミット D を指すようになります。ブランチは最後のコミット ID を表すネームタグであることを覚えておくことが重要です。
2. ローカルブランチとリモートブランチの一覧の取得
現在のローカルリポジトリのすべてのブランチを確認するコマンドは次のとおりです。
$ git branch
この場合、*
のついたブランチが現在の作業ブランチとなります。実行結果は次のようになります。
git branch
のリストアップコマンドには -r
オプションと -a
オプションをつけることができます。これらを使用すると、リモートブランチのみを表示したり、ローカルブランチとリモートブランチの両方を表示したりすることができます。
これらのオプションは以下のように使います。
3. 新しいブランチの作成
現在のブランチと同じコミットを指す新しいブランチを作成するには、若干の違いはありますが 3 つのコマンドがあります。
まず、以下のコマンドはもっとも基本的なブランチ作成コマンドです。
$ git branch <new-branch-name>
つ目のコマンドは、ブランチを作成し、すぐにそのブランチに移動するものだ。作成してから移動するステップは省略できる。
$ git checkout -b <new-branch-name>
最後のコマンドはcheckout
より新しく、同じ結果をもたらす。これが推奨される方法である。
$ git switch -c <new-branch-name>
以下に実行結果を示します。
説明したように新しいブランチを作成した後、そのブランチに変更が加えられました。
4. リモートブランチをローカル環境にコピーする
リモートリポジトリで作成したブランチをローカル環境にコピーするには、 checkout
コマンドまたは switch
コマンドで -t
オプションを使用します。新しいブランチ名を指定しなければ、リモートブランチと同じ名前でコピーされます。
$ git checkout -t <remote-name>/<branch-name>
または
$ git switch -c <new-branch-name> -t <remote-name>/<branch-name>
以下が実行結果です。
ローカル環境に feature-a
ブランチが作成され、リモートリポジトリの feature-a
ブランチを追跡しています。
5. 変更ブランチへの移動
作業中のブランチを変更するには、2つのコマンドがあります。checkout は伝統的なコマンドで、ブランチだけでなくコミットやタグ、その他の条件も参照できます。switch は比較的新しいコマンドで、ブランチを操作するためだけに作られました。Git を安全に使うためには、機能を制限した switch コマンドを使うことをおすすめします。
両方のコマンドの使い方は次のとおりです。
$ git checkout <branch-name>
または
$ git switch <branch-name>
これが実行結果です。
6. ブランチの削除と削除解除の方法
Git ブランチを削除するには二通りの方法があります。ひとつはマージ済みのブランチを削除する方法、もうひとつはマージしていないブランチを削除する方法です。
6.1. ブランチの削除
マージ済みのブランチを削除するコマンドは以下のとおりです。現在作業中のブランチは削除できないので、別のブランチに移動して入力してください。
$ git branch -d <branch-name-merged>
この場合、マージコミットは削除するブランチの最後のコミット ID を親コミット ID とします。そのため、このブランチに属していたすべてのコミットが、このリポジトリのコミット履歴に残ります。
以下は、マージしていないブランチを削除するコマンドです。
$ git branch -D <branch-name-not-merged>
この場合、削除するブランチに属していたコミットへのポインタが消えてしまいます。 これはダングリングコミット (dangling commit) あるいは orphaned commit (孤立コミット) と呼ばれるもので、Git のガベージコレクタがアクセス不能なコミットの後始末を行います。
まずは、マージしたブランチを削除した結果を見てみましょう。
上の git log グラフは、feature-c
ブランチを develop
ブランチにマージしたことを示しています。
その後で feature-c
ブランチを削除してもう一度ロググラフを表示すると、feature-c
ブランチは消えていますが、そのブランチへのコミットはまだ履歴に残っています。
これは、マージコミット 0dd7b0b
が develop
ブランチのコミット 80d10f1
と feature-c
ブランチのコミット 8480ae1
の両方の ID を持っているためです。
以下は、マージされていないブランチを削除した結果です。
上のロググラフを見ると、develop
ブランチの中に新しい feature-d
ブランチを作成し、新しいコミットを行ったことがわかります。その後、feature-d
ブランチをマージせずに削除すると、ロググラフから消えました。
6.2. ブランチの削除解除
最後に、誤って削除してしまったブランチを元に戻す方法を見てみましょう。お気づきかもしれませんが、delete branch コマンドは成功のメッセージとブランチが指していた最後のコミット ID を出力します。
たとえば、3a31806
というメッセージには Deleted branch feature-d (was 3a31806)
と表示されます。上のスクリーンショットでこれを見ることができます。
ブランチの削除を取り消すには、このようにコミット ID を指定します。コマンドは以下のようになります。
<base-commit-id>
の部分にコミット ID を入れてください。
$ git branch <branch-name> <base-commit-id>
上で削除した 2 つのブランチを、次のコマンドで元に戻してみましょう。
コミット履歴はこのようになります。
feature-c
と feature-d
のブランチが以前の場所から復活したことがわかります。
6.3. リモートブランチの削除
すべての Git ホスティングサービスは、GUI によるリモートブランチの削除をサポートしています。
コマンドは次のようになります。
$ git push <remote-name> --delete <branch-name>
を実行した結果です。
削除したリモートブランチを追跡するブランチがローカル環境にある場合は、一緒に削除されません。セクション6](#61-branch-delete)1 で説明したコマンドを使って削除してください。
7. 結論
git branch` コマンドは複数のプロジェクトを同時に作業するための基本であり、今回取り上げたのはそのための概念です。この記事が、ブランチを正しく理解して使いこなすための助けになったことを願っています。
