ブランチを切る (git branch, git switch)
以下のようなシチュエーションを考えてみましょう。
code: シチュエーション
A君「〇〇を推定するプログラムを記述しました。」
BOSS「この手法も使えるんじゃない?比較してみてよ。」
A君「やってみます。」
BOSS「でも今のプログラムを残しておいてね。すぐ切り替えられるように。」
A君「...」
さあ困りました。しかし、ブランチという機能を使うと実現できます。
ブランチとは
変更履歴の記録を分岐させる機能のことをブランチ (branch) と呼びます。下図のように木の枝のように分岐する姿からブランチと呼ばれています。
https://gyazo.com/6f1df830cf9bbe6dd18036cae273d06b
ブランチを新規作成することを一般に「ブランチを切る」といいます。またブランチの名前のことをブランチ名といいます。
ブランチはコミットを基準にして分岐します。分岐させる前にコミットすることを覚えておきましょう。
デフォルトブランチ
リポジトリを作成したとき、最初に作られる (自動生成) ブランチが master ブランチです。2020年現在、世界の様々な情勢により初期ブランチ名が main になるという動きもあります (GitHub で作成されるリポジトリは master ではなく main です) 。最初に作られるブランチのことをデフォルトブランチと呼びます。
ブランチを切る
それでは実際にブランチを切ってみましょう。
0. ファイルを用意する
code: シェルスクリプトを作成する.sh
$ echo "Hello, Git." > sample.txt
一度実行してみます。以下のように表示されれば成功です。
code: シェルスクリプトを実行してみる.sh
$ cat sample.txt
Hello, Git.
作成したファイルをコミットしましょう。以下のコマンドを実行します。
code: ファイルをコミットする.sh
$ git add sample.txt
$ git commit
$ git log
1. 現在のブランチを確認する
現在どのブランチにいるかを以下のコマンドで確認します。
code: ブランチを確認する.sh
$ git branch
すると以下のような表示になります。
code: ブランチを確認した結果.sh
$ git branch
* master
現在はデフォルトブランチの master のみが表示されています。
2. ブランチを切る
ブランチを切るためには以下のコマンドを実行します。
code: ブランチを切る.sh
$ git branch ${ブランチ名}
今回は sample ブランチを作成します。
code: sampleブランチを作る.sh
$ git branch sample
ブランチが作成されたか確認しましょう。
code: ブランチを確認する.sh
$ git branch
* master
sample
master のように表示されている「*」は現在いるブランチです。
3. ブランチを移動する
sample ブランチに移動してみます。移動するには以下のコマンドを実行します。
code: ブランチを移動する.sh
$ git checkout ${ブランチ名}
# または
$ git switch ${ブランチ名}
git checkout は従来の操作方法、 git switch は新しい操作方法です。 git checkout の役割が多くなりすぎたために、 git switch と git restore に分割されました。Git 公式は git switch を推奨していますが、2020年10月現在、まだ正式機能としてリリースされていないので変更の可能性があります。そのため本記事では両方の操作方法を記述します。
今回は sample に移動して master に戻ってみます。
code: master -> sample -> master.sh
$ git checkout sample
# または
$ git switch sample
$ git branch
master
* sample <- sample に移動してる!
$ git checkout master
# または
$ git switch master
$ git branch
* master <- master に戻っている!
sample
4. ブランチを削除する
不要なブランチを削除します。以下のコマンドです。
code: ブランチを削除する.sh
$ git branch -d ${ブランチ名}
一度 sample を削除してみましょう。自身のブランチは消せないので、必ず master に移動しましょう。
code: sample ブランチを削除する.sh
$ git branch -d sample
$ git branch
* master
5. ブランチを新規作成しつつ移動する
実際の開発では、いちいちブランチを作って移動するのが面倒に感じることがあります。ブランチを新規作成しつつ移動するコマンドがあるので試してみましょう。
code: ブランチを新規作成しつつ移動する.sh
$ git checkout -b ${ブランチ名}
# または
$ git switch -c ${ブランチ名}
ここで、checkout と switch でオプションが異なることに注意が必要です。
実際にコマンドを実行してみましょう。 develop ブランチに移動します。
code: develop を作りつつ移動.sh
$ git checkout -b develop
# または
$ git switch -c develop
$ git branch
* develop
master
ブランチを使う効果を体験する
ブランチを切って移動することができました。続いてはブランチを使う効果を体験してみましょう。
1. 状況を確認する
現在のブランチが develop であることを確認しましょう。また、ディレクトリの状況も確認しましょう。
code: 各種確認.sh
$ git branch
* develop
master
$ ls
sample.txt
$ cat sample.txt
Hello, Git.
現在のディレクトリには「Hello, Git.」と記述された sample.txt が存在することが確認できました。これは master ブランチのときと同じものです。
2. ファイルを追加する&ファイルを編集する
続いてファイルを追加・編集します。これは効果をわかりやすくするためです。Vimで sample.txt を開き、「Hello, Git.」を「Hello, branch.」に書き換えてください。また、branch.txt を新規作成します。
code: ファイルの追加・編集.sh
$ vim sample.txt
$ echo "Created on develop branch." > branch.txt
$ cat sample.txt
Hello, branch.
$ cat branch.txt
Created on develop branch.
$ git status
On branch develop
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: sample.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
branch.txt
no changes added to commit (use "git add" and/or "git commit -a")
作業後は cat と git status で変更を確認しています。
3. コミットする
ファイルの編集が完了したのでコミットします。
code: コミットする.sh
$ git add sample.txt branch.txt
$ git commit -m "ファイルの追加と編集"
4. ブランチを切り替える
develop ブランチの状況と master ブランチの状況を比較します。
code: develop ブランチの状況.sh
$ git branch
* develop
master
$ ls
branch.txt sample.txt
$ cat sample.txt
Hello, branch.
編集した内容が確認できます。続いて master に移動して確認してみます。
code: master ブランチの状況.sh
$ git checkout master
# または
$ git switch master
$ git branch
develop
* master
$ ls
sample.txt
$ cat sample.txt
Hello, Git.
すると、develop で追加ファイルや編集された内容がブランチを切る前の状態になっています。これは編集したコミットが develop ブランチに記録されているからです。こうしてブランチを分けることで、複数の状態を任意に切り替えることができます。つまり同一のファイル名で複数の内容をもつことができるのです。
Ex. コミットしないとどうなる?
今回はコミットをして変更を確定したことで意図する挙動をしました。では編集後にコミットせずにブランチを変更するとどうなるのでしょうか?答えは切り替えたブランチにその変更が引き継がれます。以下に動作結果を示します。興味がある人は自分で実行してみてください。
code: コミットせずにブランチを切り替えたとき.sh
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: sample.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
branch.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git switch master
M sample.txt
Switched to branch 'master'
$ git branch
develop
* master
$ ls
branch.txt sample.txt
$ cat sample.txt
Hello, branch.
ブランチを使うもう一つの効果
ブランチは複数の状態を任意に切り替えることがメリットでした。しかしながらもう1つメリットがあります。それはリポジトリを共有したとき、作業の衝突を避けられるということです。
ブランチのコミットは同じリポジトリであれば同じ並びである必要があります。ある人のブランチAでは「AAA-BBB-CCC」のコミットの並び順、もうひとりのブランチAでは「AAA-BBB-DDD」のコミットの並び順であったとします。Git ホスティングサービスで共有した場合、作業が衝突 (コンフリクト) してしまいます。
これを回避するにはブランチ名を変更することが一番の近道です。ブランチ名が一意になるように切ることで作業の衝突を避けることができます。
【TIPS】一般的なブランチの分け方 - Git-flow
ブランチを分けることによってブランチの名前に「意味」を持たせることができます。
下図は一般的なブランチの分岐例です (このようなブランチの分け方を Git-flow と呼びます) 。
https://gyazo.com/e13a302aad9c02309ea5ee5d2d4e0de9
master または main ブランチはリリースしたバージョンのコミットを管理します。つまり、開発途中ではなく製品版のプログラムしかここでは管理しません。いつ master ブランチにアクセスしても 100% 動作するプログラムになります。masterブランチの最新コミットはプロジェクトの最新バージョンということになります。master ブランチで重大なバグが発生したときは master から hotfix ブランチを切り、修正します。
develop ブランチは開発中のプログラムを管理します。基本的にはどのコミットでも動作するプログラムになります。具体的な機能を追加する feature ブランチは develop ブランチから切ります。リリースするための機能がすべて develop ブランチにマージされるとそのコミットから release ブランチが切られます。
feature ブランチは新しい機能を開発するためのブランチです。このブランチは1つだけ存在するわけではなく、機能ごとに存在します。具体的には feature/add_login (ログイン機能を作るブランチ) のようなブランチが作成されます。機能の実装が完了すると develop ブランチにマージされます。
release ブランチはリリース前の準備段階にあるプログラムを管理します。このブランチはバグの修正しかしません。プロジェクトによってはここから bug ブランチを切る運用をすることもあります。このブランチもバージョンごとにブランチが存在します。具体的には release/version_1_0 (version 1.0 リリース用のブランチ) のようなブランチが作成されます。release ブランチが更新されると、そのコミットを develop ブランチにマージして反映します。バグの修正が完了すると master ブランチにマージされます。これが新しいバージョンのリリースとなります。
hotfix ブランチは master ブランチで重大なバグが発生した時に切られるブランチです。このブランチもバグごとにブランチが切られます。具体的には hotfix/fix_login_view (ログイン画面の修正) のようなブランチが作成されます。修正が完了すると master ブランチと develop ブランチにマージされます。