CH 22 / 75第4部 ブランチとマージ

ブランチを作る・切り替える・消す

このページで分かること

  • git switch と git switch -c でブランチを切り替え・作成できる
  • 切り替えるとワークツリーの中身が入れ替わることが分かる
  • 記録していない変更が切り替え時にどう扱われるかが分かる
  • git branch -m で名前を変え、-d と -D の違いを理解して消せる
このページの目次11 items

21で、ブランチはコミットに貼った付箋だと分かりました。このページでは、ブランチを作り、git switch で切り替え、名前を変え、消すまでの一通りの操作を練習します。切り替えるとワークツリーの中身が入れ替わる様子も確かめます。

作って、切り替える#

クッキーのレシピを、main とは別のブランチで書いてみます。まずブランチを作り、そこへ移ります。

text3 lines
cd ~/git-practice
git branch cookie
git switch cookie
text1 lines
Switched to branch 'cookie'

git switch ブランチ名 は、HEAD をそのブランチに付け替えるコマンドです。第3部の18の言葉でいうと、.git/HEAD の中身が ref: refs/heads/cookie に書き換わります。

text1 lines
git branch
text2 lines
* cookie
  main

* が cookie に移りました。この状態でコミットすると、21で見たとおり cookie だけが進みます。

text3 lines
echo "バター 100g" > recipes/cookie.txt
git add recipes/cookie.txt
git commit -m "クッキーのレシピを追加"
text3 lines
[cookie 4b541f5] クッキーのレシピを追加
 1 file changed, 1 insertion(+)
 create mode 100644 recipes/cookie.txt

コミットの1行目の [cookie 4b541f5] は、「cookie ブランチに 4b541f5 を記録した」という意味です。

作るのと切り替えるのを一度に#

git branch と git switch を続けて打つ代わりに、-c(create)を付けると1回で済みます。

text1 lines
git switch -c ブランチ名

実際の作業では、こちらを使うことがほとんどです。

切り替えると、ワークツリーの中身が入れ替わる#

main に戻って、recipes フォルダの中を見比べます。

text3 lines
ls recipes
git switch main
ls recipes
text4 lines
cake.txt
cookie.txt
Switched to branch 'main'
cake.txt

main に戻ると、cookie.txt がワークツリーから消えました。消えたのではなく、main が指すコミットには cookie.txt が含まれていないので、ワークツリーがその状態に入れ替わったのです。git switch cookie で戻れば、また現れます。

main と cookie が別々のコミットを指し、git switch main ではワークツリーが cake.txt・shopping.txt・todo.txt に、git switch cookie では cookie.txt も加わった状態に入れ替わる図
git switch は、ワークツリーの中身をそのブランチのコミットの状態に入れ替える
text1 lines
git log --oneline --decorate --graph --all -n 3
text3 lines
* 4b541f5 (cookie) クッキーのレシピを追加
* 4e16e23 (HEAD -> main) やることに掃除を追加
* 370768c (tag: v1.0) ケーキのレシピを追加

cookie は main の1つ先にいます。main はまだクッキーのことを知りません。cookie の変更を main に取り込む方法は、次の23で扱います。

記録していない変更は、どうなるか#

切り替えで入れ替わるのは「コミットされた中身」です。まだコミットしていない変更は、どのブランチのものでもありません。

text2 lines
echo "りんごを買う" >> shopping.txt
git switch cookie
text2 lines
Switched to branch 'cookie'
M	shopping.txt
text1 lines
git status -s
text1 lines
 M shopping.txt

M shopping.txt の行は「変更されたファイルを持ったまま移った」という知らせです。ワークツリーとステージ(第2部の08)は1つしかないので、記録していない変更は切り替えてもそのまま付いてきます。

ただし、付いていくと切り替え先の中身を上書きしてしまう場合は、Git が切り替えを止めます。

text4 lines
git switch main
git restore shopping.txt
echo "下書き" > recipes/cookie.txt
git switch cookie
text4 lines
error: The following untracked working tree files would be overwritten by checkout:
	recipes/cookie.txt
Please move or remove them before you switch branches.
Aborting

main で作った下書きの recipes/cookie.txt が、cookie ブランチに記録されている同名のファイルとぶつかるので、切り替えが中止されました。変更を守るための安全装置です。

練習で作った下書きは消しておきます。

text1 lines
rm recipes/cookie.txt

直前のブランチに戻る#

git switch - は、直前にいたブランチに戻ります。2つのブランチを行き来するときに便利です。

text2 lines
git switch -c tmp-test
git switch -
text2 lines
Switched to a new branch 'tmp-test'
Switched to branch 'main'

名前を変える・消す#

名前を変える:git branch -m#

text2 lines
git branch -m cookie recipe-cookie
git branch -v
text2 lines
* main          4e16e23 やることに掃除を追加
  recipe-cookie 4b541f5 クッキーのレシピを追加

-m(move)で、ブランチの名前を変えられます。付箋に書いた名前を書き直すだけなので、コミットには何の影響もありません。今いるブランチの名前を変えるときは、git branch -m 新しい名前 と1つだけ書きます。

消す:-d と -D#

text1 lines
git branch -d tmp-test
text1 lines
Deleted branch tmp-test (was 4e16e23).

-d(delete)で消せます。tmp-test は main と同じコミットを指していたので、消しても失うものはありません。では、main にまだ取り込んでいない recipe-cookie を消そうとするとどうなるでしょうか。

text1 lines
git branch -d recipe-cookie
text3 lines
error: the branch 'recipe-cookie' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D recipe-cookie'
hint: Disable this message with "git config set advice.forceDeleteBranch false"

「まだ取り込まれていない(not fully merged)」と断られました。このブランチを消すと、クッキーのコミットをたどる名前がなくなるからです。それでも消したい場合は、大文字の -D を使います。

オプション動き
-d取り込み済みのブランチだけ消す。未取り込みなら断る
-D取り込んでいなくても消す

recipe-cookie は次の23で main に取り込むので、消さずに残しておきます。

よくある疑問#

Q. git checkout でもブランチを切り替えられると聞きました。
A. できます。git checkout ブランチ名 は git switch と同じ動き、git checkout -b 名前 は git switch -c 名前 と同じです。ただ checkout はファイルを元に戻す操作(今の git restore)も兼ねていて紛らわしいため、Git 2.23 で役割を分けた switch と restore が加わりました。このガイドでは switch を使います。古い記事で checkout を見かけたら、読み替えてください。

Q. ブランチ名に使える文字は?
A. 英小文字・数字・ハイフンで付けるのが無難です。空白や ~ ^ : ? などは使えません。feature/login のように / で区切る名前は使えて、よく使われます(28で扱います)。

まとめ#

  • git switch 名前 で切り替え、git switch -c 名前 で作って切り替える。git switch - で直前のブランチへ戻る
  • 切り替えると、ワークツリーの中身がそのブランチのコミットの状態に入れ替わる
  • 記録していない変更は切り替えても付いてくる。上書きになる場合は Git が止める
  • git branch -m で名前を変える
  • -d は取り込み済みのブランチだけ消し、-D は強制的に消す

次のページ#

23. マージの仕組み(Fast-forward と3-way) ── recipe-cookie で書いたクッキーのレシピを main に取り込み、マージの2つの形を見分けます。