結論だけ知りたい人へ — これだけ覚えればOK
「聞いたことはあるけど、忙しくて詳しい理由までは不要」という方はここだけで十分です。
| やりたいこと | ❌ 今まで | ✅ これから |
|---|---|---|
| ブランチを切り替える | git checkout main |
git switch main |
| 新しいブランチを作って切り替える | git checkout -b feature |
git switch -c feature |
以下、「なぜそうなったのか」を知りたい方は読み進めてください。
「ブランチ切り替えたつもりが、ファイルが消えた」
エンジニア歴8年の間に、この手の事故を何度か見てきました。
あるプロジェクトで、メンバーが git checkout main.py と打ってしまったことがあります。本人はブランチを切り替えるつもりでしたが、 main.py というファイルが HEAD の状態に巻き戻されました 。数時間分の作業が一瞬で消え、git reflog で復旧するまで30分以上かかりました。
この事故の根本原因は、 git checkout が多機能すぎる ことにあります。
なぜ git checkout は危ないのか? — 1つのコマンドに3つの役割
git checkout は、以下の3つのまったく異なる操作を1つのコマンドで担っています。
| 役割 | コマンド例 | 操作内容 |
|---|---|---|
| ブランチ切り替え | git checkout main |
作業ブランチを main に変更 |
| ファイル復元 | git checkout -- index.html |
ファイルを直前のコミット状態に戻す |
| 新ブランチ作成 | git checkout -b feature |
新しいブランチを作って切り替え |
問題は、 Gitがコンテキストから「どの操作か」を推測する 点です。git checkout feature と打ったとき、feature がブランチ名なのかファイル名なのかによって、まったく違う動作をします。
checkout が曖昧になる具体例
# ブランチ名とファイル名が同じ場合
git checkout feature
# → ブランチ切り替え? ファイル復元? Git が推測する
# 明示的にファイル復元するには -- が必要
git checkout -- feature
この曖昧さは、Git公式でも「ARGUMENT DISAMBIGUATION」として文書化されているほどの既知の問題です。2019年、ついにGitコアチームが解決に動きました。
Git 2.23 で何が変わったのか? — switch と restore の誕生
2019年8月にリリースされたGit 2.23で、git checkout の機能が 2つの専用コマンド に分離されました。
git checkout(多機能)
├── ブランチ操作 → git switch(新コマンド)
└── ファイル復元 → git restore(新コマンド)
git switch — ブランチ操作に特化
git switch はブランチの切り替えと作成だけを担当します。ファイル復元の機能は持っていないため、 誤ってファイルを上書きするリスクがありません 。
# ブランチ切り替え
git switch main
# 新ブランチを作成して切り替え
git switch -c feature/login
# リモートの追跡ブランチに切り替え
git switch --track origin/develop
# 直前のブランチに戻る
git switch -
git restore — ファイル復元に特化
git restore はワーキングツリーやステージングエリアのファイル復元だけを担当します。ブランチ操作の機能は持っていないため、 意図せずブランチが切り替わることがありません 。
# ワーキングツリーのファイルを復元(変更を破棄)
git restore index.html
# ステージングを取り消す(git reset HEAD の代替)
git restore --staged index.html
# ステージングとワーキングツリーの両方を復元
git restore --staged --worktree index.html
# 特定のコミットからファイルを復元
git restore --source HEAD~2 index.html
ポイント: git restore --staged は、従来 git reset HEAD <file> で行っていた「ステージングの取り消し」をより直感的に表現しています。
詳細対応表 — オプション付きの完全版
冒頭のチートシートではカバーしきれなかった、リモートブランチやデタッチHEADも含む完全版です。
| やりたいこと | 旧: git checkout
|
新: git switch / git restore
|
|---|---|---|
| ブランチ切り替え | git checkout main |
git switch main |
| 新ブランチ作成+切り替え | git checkout -b feature |
git switch -c feature |
| リモートブランチの追跡 | git checkout --track origin/dev |
git switch --track origin/dev |
| 直前のブランチに戻る | git checkout - |
git switch - |
| ファイルの変更を破棄 | git checkout -- file.txt |
git restore file.txt |
| ステージングの取り消し | git reset HEAD file.txt |
git restore --staged file.txt |
| 特定コミットのファイルを取得 | git checkout abc123 -- file.txt |
git restore --source abc123 file.txt |
| デタッチHEAD(特定コミットに移動) | git checkout abc123 |
git switch --detach abc123 |
「checkout で事故った」あるある5選
実際の開発現場でよくある checkout 起因の事故パターンを紹介します。 switch / restore ならこれらの事故を構造的に防げます。
1. ブランチ名とファイル名の衝突
# 「test」というブランチに切り替えたかった
git checkout test
# → しかし「test」というファイルが存在し、ファイルが復元されてしまった
git switch test なら、ブランチが存在しなければ エラーになるだけ で、ファイルには一切触れません。
2. デタッチHEADに気づかずコミットが迷子に
git checkout v1.0.0
# → タグに移動してデタッチHEAD状態に
# → この状態でコミットすると、ブランチに属さない「迷子のコミット」になる
# → git switch v1.0.0 ならエラーで止まるので安全
3. -- を忘れてファイル復元
# ファイルを復元したかった
git checkout important-file.js
# → 「important-file.js」というブランチがあれば、そちらに切り替わる
git restore important-file.js なら、 ファイル復元しかしない ので安全です。
4. checkout -b のタイプミス
# -b を忘れた
git checkout feature/new-api
# → 存在しないブランチに切り替えようとしてエラー(まだマシ)
# → 同名ファイルがあれば、ファイル復元されてしまう(最悪)
5. 複数ファイルの復元で意図しないファイルまで巻き戻す
git checkout -- .
# → カレントディレクトリ以下の全変更を破棄
# → 「このファイルだけ戻したかった」のに全部消える
git restore index.html
# → 指定したファイルだけ復元。明示的で安全
実際の移行手順 — 今日からできる3ステップ
ステップ1: Git のバージョンを確認する
git switch と git restore は Git 2.23 以降で使用できます。まずバージョンを確認しましょう。
git --version
# git version 2.43.0 のように表示される
# 2.23 以上なら OK
2.23未満の場合は、Gitを更新してください。
# macOS (Homebrew)
brew install git
# Ubuntu / Debian
sudo apt update && sudo apt install git
# Windows (公式インストーラー)
# https://git-scm.com/download/win からダウンロード
ステップ2: エイリアスで移行をスムーズにする
いきなり習慣を変えるのは難しいので、エイリアスを設定して段階的に移行するのがおすすめです。
# よく使うコマンドを短縮
git config --global alias.sw 'switch'
git config --global alias.rs 'restore'
git config --global alias.sc 'switch -c'
ステップ3: チームで導入するためのTips
チーム全体で移行する場合は、以下のアプローチが効果的です。
- READMEやCONTRIBUTINGに方針を明記する
## Git コマンド規約
- ブランチ操作: `git switch` を使用してください
- ファイル復元: `git restore` を使用してください
- `git checkout` は後方互換のため使用可能ですが、新コマンドを推奨します
-
コードレビューで緩やかに促す — 強制ではなく「こっちのほうが安全ですよ」というスタンスで
-
ペアプログラミングやモブプログラミングの際に自然に使う — 見て覚えるのが最も効果的です
よくある質問(FAQ)
git checkout は廃止(deprecated)されるのですか?
いいえ、廃止の予定はありません。 Git公式ドキュメントでも checkout は引き続きサポートされています。Git は後方互換性を非常に重視するプロジェクトなので、既存のスクリプトやCI/CDパイプラインが壊れるような変更は行いません。
ただし、Git 2.23のリリースノートでは switch と restore を「checkout の機能を分離した実験的コマンド」として導入しており、2026年現在では experimental(実験的)のラベルも外れ、安定版コマンドとして定着 しています。新しく学ぶなら switch / restore から始めるのがベストです。
switch と restore だけで checkout の全機能をカバーできますか?
日常の開発作業においては ほぼ100%カバーできます 。唯一、git checkout 固有の機能として --orphan(親コミットのない新ブランチ作成)がありますが、git switch --orphan でも同等の操作が可能です。
シェルスクリプトや CI の checkout は書き換えるべきですか?
急いで書き換える必要はありません。 checkout は今後も動作し続けます。ただし、新しく書くスクリプトでは switch / restore を使うことで、コマンドの意図が明確になり、メンテナンス性が向上します。
git switch で detached HEAD にならないようにできますか?
はい、 git switch はデフォルトでデタッチHEADを拒否します 。git switch abc123(コミットハッシュ指定)はエラーになり、意図的に --detach オプションを付ける必要があります。これは checkout にはなかった安全機能です。
まとめ — 「意図が明確なコマンド」を選ぼう
git checkout は長年Gitの中心的なコマンドでしたが、「多機能すぎる」という設計上の問題を抱えていました。Git 2.23で導入された git switch と git restore は、この問題を 「1コマンド1責任」 の原則で解決しています。
今日からやることリスト
-
git --versionでバージョンが 2.23 以上か確認する -
git switchとgit restoreを普段の作業で使い始める -
エイリアス(
sw,rs,sc)を設定して移行をスムーズにする - チームのCONTRIBUTINGガイドに新コマンドの推奨を追記する
コマンドの意図が明確であることは、チーム開発における最大の安全装置です。 今日から git switch と git restore を使ってみてください。
参考リンク
Zennでも記事を書いていますので、よければぜひ覗いてみてください。