😇

Gitで復旧作業をしてみたよー

に公開

はじめに

開発中に「あ、やべ😭 このファイルは含めるべきではなかった...」と気づくことありませんか?

例えば:

  • 設定ファイルやスキーマファイルを誤って含めてしまった
  • テスト用のコードを本番ブランチにプッシュしてしまった
  • 不要なデバッグコードを含めてしまった

そんな時に、他のファイルはそのままで、特定のファイルだけを元に戻す方法を解説します。

前提条件

  • Git の基本操作(add、commit、push)ができる
  • 作業ブランチで開発している
  • 他の開発者がまだそのブランチを使用していない

方法1: 特定ファイルを前のコミットに戻す(推奨)

Step 1: 変更されたファイルを確認

まず、最新のコミットで変更されたファイルを確認します:

git show --name-only HEAD

実行例:

$ git show --name-only HEAD
commit a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0 (HEAD -> feature/api-update)
Author: Developer <developer@example.com>
Date:   Mon Jan 15 14:30:00 2024 +0900

    API機能追加とバグ修正

src/controllers/user_controller.py
src/models/user_model.py
config/database.yml
tests/test_user.py

この例では、config/database.yml が誤って含まれているとします。

Step 2: 特定ファイルを1つ前のコミットに戻す

git checkout HEAD~1 -- path/to/your/file

実際の例:

git checkout HEAD~1 -- config/database.yml

Step 3: 変更を確認

git status

出力例:

On branch feature/api-update
Your branch is up to date with 'origin/feature/api-update'.
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   config/database.yml

Step 4: コミット&プッシュ

# コミット
git commit -m "Revert config/database.yml to previous state"

# プッシュ
git push origin feature/api-update

方法2: 複数のファイルを一度に戻す

複数のファイルを元に戻したい場合:

# 複数ファイルを指定
git checkout HEAD~1 -- config/database.yml src/debug.py

# または、特定のディレクトリ全体
git checkout HEAD~1 -- config/

方法3: 特定のコミットの状態に戻す

1つ前ではなく、特定のコミットの状態に戻したい場合:

# コミット履歴を確認
git log --oneline

# 特定のコミットの状態に戻す
git checkout <commit-hash> -- path/to/your/file

# 例
git checkout abc123d -- config/database.yml

ファイルパスを探す便利なコマンド

最新のコミットで変更されたファイル

git show --name-only HEAD

複数のコミットで変更されたファイル

# 最新の3つのコミット
git log --name-only -3

# 簡潔表示
git log --oneline --name-only -5

ファイル名で検索

# ファイル名の一部で検索
find . -name "*config*" -type f

# 特定の拡張子で検索
find . -name "*.yml" | grep -i config

特定のファイルのコミット履歴

git log --oneline -- path/to/your/file

実際の使用例

ケース1: 設定ファイルを誤ってコミットした場合

# 1. 変更されたファイルを確認
$ git show --name-only HEAD
src/api/handlers.py
src/api/models.py
config/secrets.yml  # これを元に戻したい

# 2. 設定ファイルを元に戻す
$ git checkout HEAD~1 -- config/secrets.yml

# 3. 変更をコミット
$ git add config/secrets.yml
$ git commit -m "Revert secrets.yml to previous state"
$ git push origin feature/api-enhancement

ケース2: テストファイルを複数戻したい場合

# テストディレクトリ全体を元に戻す
$ git checkout HEAD~1 -- tests/

# または、特定のテストファイルのみ
$ git checkout HEAD~1 -- tests/test_debug.py tests/test_temp.py

$ git add tests/
$ git commit -m "Revert test files to previous state"
$ git push origin feature/cleanup

注意点とベストプラクティス

⚠️ 注意点

  1. 他の開発者が使用している場合

    • 共有ブランチで強制プッシュ(--force)は避ける
    • チームメンバーに事前に連絡する
  2. 重要なファイルのバックアップ

    • 大きな変更前は念のためバックアップを取る
  3. マージ前の確認

    • プルリクエスト作成前に変更内容を再確認する

✅ ベストプラクティス

  1. .gitignore の活用

    # 設定ファイル
    config/secrets.yml
    config/database.yml
    
    # 一時ファイル
    *.tmp
    *.log
    
    # IDE設定
    .vscode/
    .idea/
    
  2. コミット前の確認習慣

    # コミット前に変更内容を確認
    git diff --cached
    
    # または
    git status
    
  3. 小さなコミット単位

    • 関連する変更をまとめてコミット
    • 不要なファイルを混入させない

まとめ

特定のファイルをコミット&プッシュから元に戻す方法を紹介しました。

推奨手順:

  1. git show --name-only HEAD で変更ファイルを確認
  2. git checkout HEAD~1 -- path/to/file で特定ファイルを元に戻す
  3. git addgit commitgit push で変更を適用

この方法なら、他のファイルに影響を与えることなく、安全に特定のファイルだけを元に戻すことができます。

開発効率向上のために、ぜひ活用してみてください!

関連記事

Discussion