破損したGitリポジトリの修復:完全トラブルシューティングガイド

バックアップ、git fsck、インデックス修復、reflog復元、安全な再クローンを使用して、Gitリポジトリの破損を診断・修復します。

破損したGitリポジトリの修復:完全トラブルシューティングガイド

Gitリポジトリは一般的に堅牢ですが、ハードウェア障害、突然のシステムクラッシュ、ディスクエラー、あるいは重要なGit操作(オブジェクトのパックや履歴の書き換えなど)中の停電などの外部要因により、データ破損が発生する可能性があります。破損したリポジトリは、混乱を招くエラー、コミット不能、またはオブジェクト欠落の報告として現れることがあります。

このガイドでは、破損の種類を診断し、適切な修復技術を適用し、失われたデータを安全に復元するための体系的なステップバイステップのアプローチを提供します。リポジトリの破損は永久的なデータ損失につながる可能性があるため、侵襲的な修復を試みる前に、常に安全なバックアップを作成するというベストプラクティスに従ってください。


1. 安全第一:破損したリポジトリのバックアップ

特に.gitディレクトリ内のファイルシステム操作を伴う修復コマンドを開始する前に、完全なバックアップを作成する必要があります。これにより、修復プロセスでさらなる問題が発生した場合でも、現在の破損状態に戻すことができます。

# リポジトリディレクトリの外に移動
cd ..

# ディレクトリ全体の圧縮バックアップを作成
tar -czvf myrepo_corrupted_backup.tar.gz myrepo

# または、リポジトリディレクトリ全体をコピー
cp -R myrepo myrepo_backup_$(date +%Y%m%d)

2. git fsckによる破損の診断

Gitリポジトリの整合性をチェックするための主要なツールはgit fsck(ファイルシステムチェック)です。このコマンドはオブジェクトデータベースと参照をスキャンし、不整合、欠落オブジェクト、または壊れたリンクを探します。

包括的なチェックのために次のコマンドを実行します:

# 詳細出力で整合性チェックを実行
git fsck --full --unreachable --strict

git fsck出力の解釈

エラーメッセージ 意味 重大度 主な修正方法
error: object XXXXX is missing 必要なblob、ツリー、またはコミットオブジェクトが完全に欠落しています。 リモート/バックアップからの復元。
dangling commit XXXXX コミットは存在しますが、ブランチ、タグ、またはreflogから参照されていません。 低/中 git reflogによる復元。
dangling blob XXXXX データは存在しますが、コミットやツリーにリンクされていません。 通常は無視するか、pruneできます。
error: HEAD points to an unborn branch .git/HEADファイルが破損しているか、存在しないブランチを指しています。 .git/HEADの手動修正またはgit reset

3. Gitインデックス(.git/index)の修復

インデックスファイルは、Gitが作業ディレクトリと最後のコミットの間の変更を追跡するために使用するステージングエリアキャッシュです。インデックスの破損は、システムクラッシュやマージ失敗後によく発生する問題の1つです。

Git操作がインデックスが無効、不整合、または読み取り不能であるというエラーで失敗する場合、インデックスを再構築する必要があります。

方法1:Gitにインデックスを強制的に再読み取りさせる

インデックス修復を試みる最も安全な方法は、ハードリセットを実行することです。これにより、Gitは最新のコミットに基づいてインデックスと作業ディレクトリを強制的に調整します。

git reset --hard HEAD

方法2:インデックスを手動で削除して再作成する

git resetが失敗した場合、破損したインデックスファイルを削除できます。Gitは、git statusgit addなどのコマンドが必要とする次回に自動的に再作成します。

警告: インデックスを削除すると、ステージングエリアがクリアされます。git addを使用してステージングした変更はすべて失われます。

# 破損したインデックスファイルを削除
rm .git/index

# GitにHEADからインデックスを強制的に再構築させる
git reset

# 機能を確認するためにステータスをチェック
git status

4. 壊れたオブジェクトと欠落オブジェクトへの対処

壊れたGitオブジェクト(blob、ツリー、コミット)を含む破損は、特にオブジェクトが本当に欠落している場合、修正が最も難しいことがよくあります。ただし、破損が不適切にパッケージ化されたオブジェクトや復元可能なダングリングオブジェクトによる場合もあります。

4.1. リポジトリの再パッケージ化

Gitはオブジェクトをルーズファイルとして保存するか、パックファイルに統合して保存します。再パック操作を実行すると、軽微な整合性の問題が解決され、パフォーマンスが向上する場合があります。

# すべてのルーズオブジェクトを再パックし、整合性を検証し、古いパックファイルを削除
git repack -a -d

# 改善を確認するためにfsckを再実行
git fsck --full

4.2. Reflogを介したダングリングコミットの復元

ダングリングコミットは、有効ではあるが既知の参照(ブランチ、タグ)から到達不可能なコミットオブジェクトです。これは、強制リセットや履歴の書き換え後によく発生します。reflogはローカルのHEADと参照の履歴を追跡し、多くの場合、復元の鍵を握っています。

  1. Reflogを表示:

    git reflog
    

    損失の原因となったアクションの前のSHA-1ハッシュを探します(例:HEAD@{5}: reset: moving to origin/main)。

  2. コミットを再参照:

    正しいSHA-1(例:a1b2c3d4)を特定したら、それを指す新しいブランチを作成するか、現在のブランチをリセットできます。

    # 例:新しい復元ブランチを作成
    git branch recovered-work a1b2c3d4
    
    # または、現在のブランチをダングリングコミットにリセット
    # (注意して使用)
    git reset --hard a1b2c3d4
    

4.3. 本当に欠落しているオブジェクトへの対処

git fsckerror: object XXXXX is missingを報告した場合、特定のコミット履歴に必要なデータがローカルオブジェクトデータベース(.git/objects)に存在しないことを意味します。

  • リモートが存在する場合: 唯一の信頼できる解決策は、リモートリポジトリから欠落オブジェクトをフェッチすることです。

    git fetch origin
    
    # その後、影響を受けるブランチのリンクを修復するかリセットを試みます
    
  • リモートが存在しない場合(ローカル破損): リポジトリが完全にローカルでオブジェクトが欠落している場合、そのオブジェクトが参照するデータは、外部バックアップがない限り永久に失われます。

5. 破損した参照(Refs)の修正

参照(refs)は、.git/refs/ディレクトリ内のファイル(例:ブランチ、タグ、リモート追跡ブランチ)で、それらが指すコミットのSHA-1ハッシュを含んでいます。これらのファイルが破損している場合(例:ゼロバイトまたは無効なハッシュを含む)、Gitはブランチの状態を判断できません。

5.1. 特定と手動修復

  1. 破損した参照を特定: エラーメッセージは通常、どの参照が壊れているかを指定します(例:error: bad ref for branch 'feature/X')。

  2. refsディレクトリに移動:

    cd .git/refs/heads/
    # または .git/refs/remotes/origin/
    
  3. ファイルを検査: テキストエディタまたはcatを使用してファイルを表示します。正確に40文字の16進数(SHA-1ハッシュ)が含まれている必要があります。

  4. 修復:

    • ハッシュが既知の場合(例:git reflogから)、正しい40文字のSHA-1をファイルに手動で貼り付けます。
    • 参照が明らかに壊れている場合(例:ゼロバイト、ガベージデータ)、ファイルを削除します。その後、必要に応じてブランチ/参照を再作成する必要があります(例:git checkout -b <branch-name> <known-good-commit>)。

最終手段:破損したReflogファイルの削除

特定のreflogファイルが破損して通常のGitコマンドを妨げる場合、バックアップを取った後にそれを移動します。reflogを削除するとローカルの復元履歴が削除されるため、これはgit fsck、refs検査、リモート復元がすべて失敗した後にのみ行ってください。

mv .git/logs .git/logs.corrupt.backup

6. 最終的な復元オプション:既知の正常なソースからのクローン

リポジトリの破損が広範囲に及ぶ場合、または必要なオブジェクトが欠落している場合、最も安全で信頼性の高い復元方法は、現在のローカルリポジトリを放棄し、信頼できるソース(通常はGitHub、GitLab、Bitbucketなどのリモートサーバー)から再クローンすることです。

# 1. 破損したリポジトリの作業変更をバックアップ
# (例:コミットされていないファイルを一時的な場所にコピー)

# 2. 破損したリポジトリディレクトリの名前を変更するか削除
mv myrepo myrepo_bad

# 3. 新しいコピーをクローン
git clone <remote_url> myrepo

# 4. バックアップした作業変更を新しいリポジトリに適用

この方法により、保証されたクリーンで検証済みのリポジトリ履歴のコピーから開始でき、永続的な破損のリスクを最小限に抑えられます。

重要なポイント

破損したGitリポジトリを修正するには、インデックス、オブジェクト、または参照に的を絞った修復を適用する前に、git fsckを使用した注意深い診断が必要です。開始する前に.gitディレクトリをバックアップして、常に安全性を優先してください。git reflogなどのローカル復元方法は履歴の復元に強力ですが、リモートリポジトリからのクローンは、深刻な破損に対して最も信頼性の高い解決策です。

重要なポイント:

  1. 最初にバックアップ。(常に)。
  2. git fsck --fullで診断。
  3. インデックスの問題は通常git reset --hardで修正されます。
  4. 欠落オブジェクトは通常、リモートからのフェッチが必要です。