30.

git で特定ファイル/ディレクトリだけを過去状態に戻す方法(checkout / restore / sparse-checkout)

編集
この記事の要点
  • git restore path/to/file = 作業ツリーをインデックスに戻す(Git 2.23+ 推奨)
  • git restore --source=HEAD path/ = 指定コミットの内容で復元
  • 旧来: git checkout HEAD -- path/to/file(同じ動作)
  • 別ブランチからファイルだけ持ってくる: git checkout feature-x -- src/Login.php
  • 一部のディレクトリだけクローンしたいなら sparse-checkout(モノレポ向け)
  • 誤って checkout . でローカル変更を消したら git refloggit fsck で救出

結論: 最短コマンド

やりたいことコマンド
ローカル変更を捨てて HEAD に戻す(1 ファイル)git restore src/Login.php
ローカル変更を捨てて HEAD に戻す(ディレクトリ全体)git restore src/
3 コミット前の状態に 1 ファイルだけ戻すgit restore --source=HEAD~3 src/Login.php
削除したファイルを HEAD から復元git restore src/Deleted.php
別ブランチからファイルだけ持ってくるgit checkout feature -- src/Foo.php
add 済を取り消す(unstage)git restore --staged src/Login.php

restore vs checkout の使い分け

Git 2.23(2019年)で、ややこしかった checkout を分割するために git switch(ブランチ切替)と git restore(ファイル復元)が新設されました。新規プロジェクトは restore を使うのが推奨です。

# 旧 (Git 2.23 未満時代も含めて広く動く)
git checkout HEAD -- src/Login.php

# 新 (Git 2.23+ 推奨、意味が明確)
git restore src/Login.php                    # 作業ツリーを index に戻す
git restore --source=HEAD src/Login.php      # HEAD の内容に戻す
git restore --staged src/Login.php           # add を取り消す
git restore --source=HEAD~3 src/Login.php    # 3 つ前のコミット内容に戻す
git restore --source=feature src/Login.php   # 別ブランチの内容に置換

シナリオ別レシピ

1) ローカル編集をうっかり破棄

# ファイル単位
git restore src/Login.php

# ディレクトリ単位
git restore src/

# 全変更を捨てる(注意)
git restore :/                # リポジトリルートから全部
git restore .                 # カレントディレクトリ以下

2) 削除したファイルを戻す

# 誤って rm したファイル
rm src/Important.php

# まだコミットしてないなら HEAD から戻せる
git restore src/Important.php

# 既にコミット済の削除を取り消したい
git restore --source=HEAD~1 src/Important.php

# 「いつ削除されたか」を遡る
git log --diff-filter=D --summary -- src/Important.php
# → 削除したコミットがわかる
git restore --source=<その1つ前のコミット> src/Important.php

3) 別ブランチからファイルだけ持ってくる

# feature-x ブランチの src/Login.php だけが欲しい
git checkout feature-x -- src/Login.php
# または
git restore --source=feature-x src/Login.php

# 持ってきたら自動で add 状態になっている(checkout の場合)
git status
git commit -m "feature-x の Login.php を取り込み"

4) add を取り消す(unstage)

# 旧
git reset HEAD src/Login.php

# 新 (Git 2.23+)
git restore --staged src/Login.php

# 全部 unstage
git restore --staged :/

sparse-checkout: 一部ディレクトリだけ clone

モノレポなど巨大リポジトリで「frontend ディレクトリだけ作業したい」というニーズに対応する機能。

# Git 2.25+ の cone モード(推奨)
git clone --filter=blob:none --no-checkout https://github.com/foo/monorepo.git
cd monorepo

# sparse-checkout を有効化
git sparse-checkout init --cone

# 必要なディレクトリを指定
git sparse-checkout set frontend docs/api

# 取得(指定ディレクトリ以外はファイル本体を取らない)
git checkout main

# 確認
git sparse-checkout list

# 後で範囲拡大
git sparse-checkout add backend

# 解除(全部チェックアウト)
git sparse-checkout disable

誤って ファイルを消してしまったら

# パターン1: git restore を実行直後に「やっぱり戻したかった」
# → 残念ながら restore は作業ツリーの未追跡変更を消すと復元できない

# パターン2: コミット済なら必ず救える
git reflog
# 過去の全 HEAD 移動が見える → ハッシュを使って復元
git restore --source=abc1234 path/to/file

# パターン3: 全部失った(dangling commit 探し)
git fsck --lost-found
# → .git/lost-found/commit/ にハッシュが並ぶ
git show 
git restore --source= path/to/file

FAQ

Q: git checkout .git restore . の違い
A: 動作はほぼ同じ(カレント以下のローカル変更を捨てる)。restore のほうが意味が明確で、checkout のような副作用(ブランチ切替)が起きない。

Q: --source を省略すると?
A: index(add した内容)を見ます。つまり「add していない変更だけ」を捨てます。--staged を付けると HEAD を見て unstage。

Q: 巨大バイナリの履歴も含めて clone を軽くしたい
A: git clone --filter=blob:none(partial clone)+ sparse-checkout の組み合わせが定番。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 用語一覧
  2. エラー一覧
  3. git本体のインストール(Linux)
  4. Linuxサーバーへのgit導入とクライアントのセットアップ
  5. リモートリポジトリをローカルリポジトリとしてクローンする方法
  6. リモートとローカルのリポジトリを同期(pull)する方法
  7. 設定の確認
  8. gitユーザー名とemailの設定
  9. リモートリポジトリの作成
  10. ローカルリポジトリの作成
  11. 新規ファイル/ディレクトリをインデックスに登録
  12. インデックスの登録状態を確認
  13. ローカルリポジトリの変更をコミット
  14. コミット履歴の確認
  15. クライアントからリモートリポジトリの接続設定、確認、削除
  16. リポジトリへのプッシュ
  17. リモートリポジトリからクライアントへのSSHクローン
  18. リモートとローカルの差分表示
  19. バージョンの確認
  20. プロキシの設定
  21. ローカルをリモートリポジトリの状態に戻す
  22. ブランチの作成, 一覧表示, 切り替え
  23. ブランチのマージと削除
  24. リベース
  25. .gitignoreの書き方
  26. .gitignoreの設定が反映されない場合
  27. 特定のファイルをgitの管理から外す方法
  28. 参照(ORIG_HEAD, HEAD, FETCH_HEAD)
  29. git rm [-r --cached] の取り消し
  30. 一部のディレクトリ/ファイルのみをリポジトリから復元する方法
  31. ローカルとリモートリポジトリの有無を同期
  32. pushの取消し方法
  33. マージツールの起動方法
  34. Gitで「MERGING」の状態a