目次
概要
「あっ、このファイルdevelopブランチにコミットしちゃダメだった!」 そんな経験はないだろうか。今回は、特定のファイルだけを過去の状態に戻す安全な方法を解説する。
基本の3ステップ
ステップ1: ファイルのコミット履歴を確認する
まず、どのコミットの状態に戻したいかを確認する。変更内容も一緒に確認できる -p (--patch) オプションや、一行で表示する --oneline を付けるのがオススメだ。
# 変更内容の差分も見たい場合(推奨)
git log -p -- <ファイルパス>
# 一行で簡潔に見たい場合
git log --oneline -- <ファイルパス>
# より詳しく見たい場合(作成者・日時付き)
git log --stat -- <ファイルパス>
実行例:
git log --oneline -- src/main.js
# 出力例:
# a1b2c3d (HEAD) Fix: バグ修正
# d4e5f6g Add: 新機能追加(←この状態に戻したい!)
# h7i8j9k Initial commit
ステップ2: 特定のコミット時点のファイルを取り出す
ステップ1で確認した戻したい時点のコミットハッシュ(コミット番号)を指定して、ファイルの状態を現在の作業ディレクトリに復元する。
git checkout <コミットハッシュ> -- <ファイルパス>
具体例:
# d4e5f6gというコミット時点のsrc/main.jsに戻す
git checkout d4e5f6g -- src/main.js
このコマンドを実行すると、指定したファイルがステージング済み(git addされた状態)で復元される。
ステップ3: 変更を新しいコミットとして記録する
これが非常に重要な最後のステップである。ファイルの状態を戻したという事実を、プロジェクトの正式な履歴として記録する。
# なぜ戻したのかが分かるようにメッセージを記述する
git commit -m "Revert: main.jsをコミットd4e5f6gの状態に戻す"
# リモートリポジトリに反映
git push origin develop
ポイント:
- 履歴を消すのではなく、「戻した」という新しい履歴を作る
- チーム開発で安全(他のメンバーに影響を与えない)
- いつでも元に戻せる
実務で役立つ応用テクニック
1. 直前のコミットに戻すだけなら相対指定が便利
コミットハッシュを調べるのが面倒な場合、相対的な指定が使える。
# 1つ前のコミット時点のファイル状態に戻す
git checkout HEAD~1 -- <ファイルパス>
# 2つ前なら
git checkout HEAD~2 -- <ファイルパス>
# その後、同様にコミットする
git commit -m "Revert: <ファイル名>を直前の状態に戻す"
HEAD記法の意味:
HEAD: 現在のコミットHEAD~1またはHEAD^: 1つ前のコミットHEAD~2: 2つ前のコミット
2. まだコミットしていない変更を戻す
作業中のファイルを最新のコミット状態に戻したい場合は以下のようにする。
# ワーキングディレクトリの変更を破棄
git checkout -- <ファイルパス>
# または(Git 2.23以降の新しい書き方)
git restore <ファイルパス>
注意: この操作は元に戻せない。必要なら事前にバックアップを取ろう。
3. ステージングだけを取り消す
git addしてしまったけど、コミットはまだしていない場合は以下のようにする。
# ステージングを解除(ファイルの変更内容は保持される)
git reset HEAD -- <ファイルパス>
# または(Git 2.23以降)
git restore --staged <ファイルパス>
4. 複数のファイルを一度に戻す
# パターンマッチで複数ファイルを指定
git checkout d4e5f6g -- src/*.js
# ディレクトリごと戻す
git checkout d4e5f6g -- src/components/
# 複数のファイルを個別指定
git checkout d4e5f6g -- file1.js file2.js file3.js
5. 特定のブランチからファイルを取得
別のブランチの状態を持ってくることもできる。
# mainブランチの状態を現在のブランチに持ってくる
git checkout main -- <ファイルパス>
# featureブランチから複数ファイルを取得
git checkout feature/new-ui -- src/components/*.tsx
よくある質問
Q1: git revertとの違いは?
git revert:
- コミット全体を打ち消す新しいコミットを作成
- すべてのファイル変更が対象
git checkout <commit> -- <file>:
- 特定のファイルだけを過去の状態に戻せる
- より細かい制御が可能
ファイル単位で戻したい場合はgit checkoutが適している。
Q2: 間違えてcheckoutしてしまった
まだコミットしていなければ、もう一度checkoutすれば良い。
# 最新の状態に戻す
git checkout HEAD -- <ファイルパス>
コミット前ならgit diff --cachedでステージング内容を確認できる。
# ステージングされている変更を確認
git diff --cached
# 間違っていたらステージングを解除
git restore --staged <ファイルパス>
Q3: リモートにpush済みのコミットを戻せる?
可能だ。ただし、新しい「戻すコミット」を作ることで対応する(履歴は残る)。これがチーム開発で推奨される安全な方法である。
Q4: ファイルを削除したコミットから復活させるには?
削除される前のコミットを指定すれば良い。
# 削除されたファイルを検索
git log --all --full-history -- <ファイルパス>
# 削除前のコミットから復元
git checkout <削除前のハッシュ> -- <ファイルパス>
便利な確認コマンド
現在の状態を確認
# ワーキングディレクトリとステージングの状態
git status
# ステージングされている変更の詳細
git diff --cached
# ワーキングディレクトリの変更の詳細
git diff
履歴をグラフィカルに表示
# ブランチの分岐も含めて見やすく表示
git log --oneline --graph --all --decorate
# 特定のファイルに絞って詳細表示
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' -- <ファイルパス>
特定のコミットでの変更内容を確認
# コミットで何が変わったかを確認
git show <コミットハッシュ>
# 特定のファイルだけを確認
git show <コミットハッシュ>:<ファイルパス>
コマンド早見表
やりたいこと | コマンド |
|---|---|
ファイルの履歴を確認 |
|
特定コミット時点に戻す |
|
1つ前のコミットに戻す |
|
別ブランチから取得 |
|
作業中の変更を破棄 |
|
ステージングを解除 |
|
複数ファイルを戻す |
|
削除済みファイルを復活 |
|
ステージング内容を確認 |
|
コミットの詳細を確認 |
|
まとめ
git logでコミット履歴を確認git checkout <hash> -- <file>でファイルを復元git commitで変更を記録
この3ステップを押さえておけば、間違えてコミットしてしまった場合でも安全に対処できる。履歴を消すのではなく「戻した記録を残す」ことで、チーム開発でも安心して使える。
覚えておきたいポイント:
- ファイル単位で戻せるため、影響範囲を最小限にできる
- 履歴は残るので、後から「やっぱり戻す前の状態が良かった」となっても問題ない
git checkoutはGit 2.23以降ではgit restoreに置き換わりつつあるが、どちらも使える- 困ったら
git statusとgit logで現在の状態を確認する習慣をつけよう