ファイル名を指定し、--sourceに戻したい版のコミットを渡す
1つのファイルだけを、以前のコミットの時点の内容に戻すコマンドです。git log --oneline -- config.txtで、そのファイルを変えたコミットの一覧を出し、戻したい版のコミットID(左端の7桁ほどの英数字)を選びます。git restore --source=そのID -- config.txtを実行すると、作業フォルダーのconfig.txtだけがその版の内容に置き換わります。下のabc1234は例の値です。自分のgit logに出たIDに置き換えてください。
今いるブランチの位置(HEAD)、ほかのファイル、これまでのコミットは変わりません。戻した内容は、まだコミットしていない変更として残ります。git status --shortは M config.txt(右の列のMは、ステージしていない変更)と表示します。確かめてからgit addとgit commitで新しいコミットにします(後の節)。
ファイル名の前の--は、そこから後ろがファイル名だという区切りです。-で始まるファイル名や、後の節のgit logで今はないファイル(削除済み)を指定するときも、取り違えずに指定できます。git restoreとgit logのファイル名は、今いるフォルダーからの相対パスです(git showのコロンの後ろとは書き方が違います。後の節)。git restoreはGit 2.23以降のコマンドです。
git log --oneline -- config.txt
git restore --source=abc1234 -- config.txt
git status --short戻す前に、そのファイルにコミットしていない変更がないか確かめる
git restore --sourceは、作業フォルダーにあるそのファイルの内容を、確認なしで上書きします。コミットしていない編集があっても、エラーも警告も出ずに消えます。消えた編集はコミットされていないため、関連記事「git reset --hardで消したコミットを戻す:git reflogで元の位置を探す手順」のreflogでも探せません。
git status --short -- config.txtで何も表示されなければ、コミットしていない変更はありません。 M config.txt(ステージしていない変更)、M config.txt(ステージした変更)、MM config.txt(両方)のように何か表示されたら、git diff HEAD -- config.txtで、ステージした分も含めて中身を見ます。HEADを付けないgit diff -- config.txtは、ステージした変更を表示しません。残したい編集なら、先にコミットするか、関連記事「作業途中の変更をgit stashで退避する:未追跡ファイルは-u、ステージは--indexで戻す」の方法で退避してから戻します。
練習環境では、git addでステージした後に作業フォルダーだけを戻した場合、ステージの内容は残りました。git restore -- config.txt(--sourceなし)で、ステージした内容を作業フォルダーへ戻せます。ステージしていない編集は、この方法でも戻りません。また、作業フォルダーを戻した後でgit addすると、ステージしていた内容は戻した版に置き換わって消えます。
git status --short -- config.txt
git diff HEAD -- config.txt練習用フォルダーを作り、そこへ移動する
以下はGitが使えるBash(WSLやGit Bashなど)用です。PowerShellへそのまま貼る例ではありません。実務のリポジトリではなく、まだ存在しないgit-restore-source-practiceというフォルダーで試します。次の2行は1行ずつ実行し、mkdirとcdの両方が成功したことを確かめてから次へ進みます。エラーが出たらそこで止めてください。既に同名フォルダーがある場合は、別の新しい名前を選びます。
mkdir git-restore-source-practice
cd git-restore-source-practiceconfig.txtを2回変えたコミットを用意する
リポジトリを作り、config.txt・README.md・docs/a.txtを入れたAdd configをコミットします。名前とメールアドレスは、この練習用リポジトリ内だけに設定する例示値です。git init -bはGit 2.28以降で使えます。
git tag v1は、最初のコミットにv1という名前を付けるコマンドです。コミットIDは環境ごとに変わるため、練習ではIDの代わりにv1を戻し先に使います。実務では、git logで見つけたコミットIDを指定します。
続けて、config.txtのcolorをblueからredへ変えたChange color to redと、config.txtにsize=largeを足しREADME.mdとdocs/b.txtも変えたAdd size and docs bをコミットします。最後のgit log --onelineは、Add size and docs b、Change color to red、Add configの3件を新しい順に表示します。
git init -b main
git config user.name 'Practice'
git config user.email 'practice@example.invalid'
printf 'title=Shop\ncolor=blue\n' > config.txt
printf '# app\n' > README.md
mkdir docs
printf 'a\n' > docs/a.txt
git add -- config.txt README.md docs
git commit -m 'Add config'
git tag v1
printf 'title=Shop\ncolor=red\n' > config.txt
git add -- config.txt
git commit -m 'Change color to red'
printf 'title=Shop\ncolor=red\nsize=large\n' > config.txt
printf '# app v2\n' > README.md
printf 'b\n' > docs/b.txt
git add -- config.txt README.md docs
git commit -m 'Add size and docs b'
git log --oneline戻す版を、git showとgit diffで先に見る
git log --oneline -- config.txtは、config.txtを変えたコミットだけを表示します。練習では3件とも表示されます。README.mdだけを変えたコミットがあれば、この一覧には出ません。
git show v1:config.txtは、v1の時点のconfig.txtの中身を、ファイルを書き換えずに表示します。title=Shopとcolor=blueの2行です。コロンの後ろはリポジトリの一番上のフォルダーからのパスです。docsの中でgit show v1:a.txtと書くとfatal: path 'docs/a.txt' exists, but not 'a.txt'と表示され、v1:docs/a.txtかv1:./a.txtと書けば表示できました。
git diff v1 -- config.txtは、v1の版と今の作業フォルダーの版の違いです。-の行(-color=blue)がv1の内容、+の行(+color=red、+size=large)が今の内容です。戻すと、+の行が消えて-の行に置き換わります。
git log --oneline -- config.txt
git show v1:config.txt
git diff v1 -- config.txtconfig.txtだけをv1の版に戻す
git restore --source=v1 -- config.txtは、何も表示せずに終わります。git status --shortは M config.txtで、config.txtの中身はtitle=Shopとcolor=blueの2行に戻ります。
同じコミットで変えたREADME.mdは# app v2のまま、docs/b.txtも残っています。git log --oneline -1はAdd size and docs bのままで、HEADは動いていません。git statusの1行目もOn branch mainのままです。
git restore --source=v1 -- config.txt
git status --short
cat config.txt
cat README.md
git log --oneline -1コミットする前なら、git restoreで今の版へ戻せる
戻した結果が違っていた場合は、git restore -- config.txt(--sourceなし)で取りやめられます。--sourceを付けないと、ステージの内容から戻します。git restore --sourceは作業フォルダーだけを書き換え、ステージはAdd size and docs bの版のままなので、元のcolor=redとsize=largeの3行に戻ります。git status --shortは何も表示しません。
練習では、確かめた後でもう一度v1の版に戻し、次の節でコミットします。
git restore -- config.txt
git status --short
cat config.txt
git restore --source=v1 -- config.txt戻した内容を、新しいコミットにする
git diff -- config.txtで、-color=red、-size=large、+color=blueの3行を確かめてから、git addとgit commitでコミットします。git log --oneline -2は、Change color back to blueとAdd size and docs bの2件です。
これまでのコミットは消えず、戻したことが新しいコミットとして履歴に残ります。そのため、既にpush済みのブランチでも強制pushは要りません。送信先に他の人のコミットが先に入っている場合は、いつもどおり取り込んでからpushします(練習には送信先がないためpushは実行していません)。
git diff -- config.txt
git add -- config.txt
git commit -m 'Change color back to blue'
git log --oneline -2git checkout コミット -- ファイル名は、ステージまで書き換える
古い書き方のgit checkout コミット -- ファイル名でも、ファイルを指定した版に戻せます。違いはステージで、git checkoutは作業フォルダーとステージの両方を書き換えます。練習でgit checkout HEAD~1 -- config.txt(1つ前のAdd size and docs bの版)を実行すると、git status --shortは左の列のMで M config.txtと表示されました。git restoreは右の列のMで、ステージには入りません。
git checkoutで戻した後に取りやめるには、git restore --source=HEAD --staged --worktree -- config.txtで、作業フォルダーとステージの両方を今のコミットの版へ戻します。git restoreでもステージまで入れたい場合は、--staged --worktreeを付けます。
git checkout HEAD~1 -- config.txt
git status --short
git restore --source=HEAD --staged --worktree -- config.txt
git status --short表は横にスクロールできます →
| 方法 | ステージ(git status --short) | 戻した版にないファイル |
|---|---|---|
| git restore --source=ID -- パス | 変わらない( M、右の列) | 消す |
| git restore --source=ID --staged --worktree -- パス | 書き換える(M 、左の列) | 消す |
| git checkout ID -- パス | 書き換える(M 、左の列) | 残す |
フォルダーを指定すると、その版になかったファイルは消える
ファイル名の代わりにフォルダー名を指定すると、フォルダーの中の追跡中のファイルをまとめて戻します。git restoreは、戻した版になかったファイルを削除して、その版と同じ状態にします。練習でgit restore --source=v1 -- docsを実行すると、v1の後に足したdocs/b.txtが消え、git status --shortは D docs/b.txtでした。ファイルを1つだけ指定した場合も同じで、git restore --source=v1 -- docs/b.txtのように戻した版にないファイルを指定すると、エラーにならずに削除されます。
git checkout v1 -- docsでは、docs/b.txtは消えずに残り、git status --shortは何も表示しませんでした(docs/a.txtはv1と同じ内容のため)。Git公式のgit-checkoutの説明では、ファイルを削除しないのがgit checkoutの既定(overlay mode)です。
どちらも、追跡していないファイルは対象外です。git restore --source=ID -- .のように.を指定すると、今いるフォルダー以下(一番上のフォルダーで実行すればリポジトリ全体)が対象になります。その版の後に足したファイルが全部削除され、コミットしていない編集もすべて上書きされるので、指定するのは戻したいファイルかフォルダーだけにします。練習では、消えたdocs/b.txtをgit restore -- docsで元に戻しています。
git restore --source=v1 -- docs
git status --short
ls docs
git restore -- docs
git checkout v1 -- docs
git status --short
ls docs削除したファイルは、削除したコミットの1つ前の版から戻す
コミットで削除したファイルを取り戻すときも、git restore --sourceを使います。git log --oneline -- README.mdには、削除したRemove READMEのコミットも表示されます。--diff-filter=Dを付けると、そのファイルを削除したコミットだけに絞れます。
削除したコミットそのものを--sourceに指定すると、そのファイルはもう追跡されておらず、その版にもないため、error: pathspec 'README.md' did not match any file(s) known to gitと表示されて何も戻りません。削除したコミットのIDの後ろに~1を付けて(例:abc1234~1)、1つ前の版を指定します。練習では削除したコミットが最新なので、HEAD~1です。
戻したREADME.mdは、git status --shortで?? README.md(追跡していないファイル)と表示されます。ステージには入っていないため、git addしてからコミットします。
git rm -- README.md
git commit -m 'Remove README'
git log --oneline --diff-filter=D -- README.md
git restore --source=HEAD -- README.md
git restore --source=HEAD~1 -- README.md
git status --short
git add -- README.md
git commit -m 'Restore README'関連する操作と、確認した環境
ステージに入れたファイルを外すだけなら、関連記事「git addを取り消す:編集内容を残してステージから外す手順」のgit restore --stagedが対象です。1つのファイルではなくコミット全体の変更を打ち消すなら「push済みのコミットを打ち消す:git revertで履歴を残したまま元に戻す手順」を参照してください。
2026年11月3日、WSLのLinux・Git 2.53.0・非rootユーザーで掲載例を実行しました。git log -- ファイル名の絞り込み、git showのパスの書き方、git restore --sourceで作業フォルダーだけが変わりHEADとほかのファイルが変わらないこと、コミットしていない変更が警告なしに上書きされること、ステージした内容が残ること、--sourceなしでの取りやめ、git checkoutとのステージの違い、フォルダー指定で消えるファイル、削除したファイルの戻し方とエラーの表示を照合しています。Git公式の説明は2026年11月3日時点の版(git-restore・git-checkoutは2.55.0、git-log・git-show・gitrevisionsは2.56.0で更新)を参照しました。Git for Windows(Git Bash)・コマンドプロンプト・PowerShellでは実行していません。