2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

まだ git checkout 使ってるの? — git switch と git restore に移行すべき理由

2
Posted at

結論だけ知りたい人へ — これだけ覚えれば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 switchgit 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

チーム全体で移行する場合は、以下のアプローチが効果的です。

  1. READMEやCONTRIBUTINGに方針を明記する
## Git コマンド規約
- ブランチ操作: `git switch` を使用してください
- ファイル復元: `git restore` を使用してください
- `git checkout` は後方互換のため使用可能ですが、新コマンドを推奨します
  1. コードレビューで緩やかに促す — 強制ではなく「こっちのほうが安全ですよ」というスタンスで

  2. ペアプログラミングやモブプログラミングの際に自然に使う — 見て覚えるのが最も効果的です


よくある質問(FAQ)

git checkout は廃止(deprecated)されるのですか?

いいえ、廃止の予定はありません。 Git公式ドキュメントでも checkout は引き続きサポートされています。Git は後方互換性を非常に重視するプロジェクトなので、既存のスクリプトやCI/CDパイプラインが壊れるような変更は行いません。

ただし、Git 2.23のリリースノートでは switchrestore を「checkout の機能を分離した実験的コマンド」として導入しており、2026年現在では experimental(実験的)のラベルも外れ、安定版コマンドとして定着 しています。新しく学ぶなら switch / restore から始めるのがベストです。

switchrestore だけで 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 switchgit restore は、この問題を 「1コマンド1責任」 の原則で解決しています。

今日からやることリスト

  • git --version でバージョンが 2.23 以上か確認する
  • git switchgit restore を普段の作業で使い始める
  • エイリアス(sw, rs, sc)を設定して移行をスムーズにする
  • チームのCONTRIBUTINGガイドに新コマンドの推奨を追記する

コマンドの意図が明確であることは、チーム開発における最大の安全装置です。 今日から git switchgit restore を使ってみてください。


参考リンク


Zennでも記事を書いていますので、よければぜひ覗いてみてください。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?