どのような時にgit fsckが必要になるのか?
コマンドの入力中に突然停電が発生したり、ハードドライブの不調でGitがerror: inflate: data stream errorやcorrupt loose objectといったエラーを出したりしていませんか?このような時、多くの人は手っ取り早くgit cloneし直そうと考えがちです。
しかし、重要な変更をまだサーバーにプッシュしていなかったらどうなるでしょうか?そこで登場するのがgit fsck(File System Check)です。このツールは、Gitデータベースの整合性をチェックする監査役のような役割を果たします。破損したオブジェクトを検出し、<a href="https://itfromzero.com/ja/git-ja/git-log-%e5%bf%9c%e7%94%a8%ef%bc%9a%e8%91%97%e8%80%85%e3%83%bb%e6%99%82%e9%96%93%e3%83%bb%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%a7%e3%82%b3%e3%83%9f%e3%83%83%e3%83%88%e3%82%92%e7%b5%9e%e3%82%8a.html">git log</a>に表示されなくなった「孤立した」コミットを見つけ出すのに役立ちます。
私は以前、同僚がこのコマンドのおかげで2日分の作業内容をすべて復元するのを目の当たりにしました。製品デモの直前にサーバーのハードドライブでセクタエラーが発生し、いくつかの重要なオブジェクトが破損してしまったのです。git fsckのおかげで、エラー箇所を特定し、間一髪で事態を収束させることができました。
Git의 整合性に関する3つの核心的な概念
GitはデータをObjects(blob、tree、commit、tag)として保存し、SHA-1ハッシュ値で識別します。コマンドを効果的に使うために、以下の3つの状態を区別する必要があります。
- Unreachable Objects: データベース内には存在するが、どのブランチやタグからも参照されていないオブジェクト。
- Dangling Objects:
git commit --amendやrebaseの結果として生じます。古いコミットはすぐには消えず、一時的に「宙に浮いたコミット」となります。 - Corrupt Objects: ハードウェアのエラーなどにより、
.git/objectsディレクトリ内のファイル内容が変化し、ハッシュ値に不整合が生じている状態。
実践:エラーの走査と修正
1. リポジトリの全体チェック
まずは、リポジトリの状態を確認するための最も基本的なコマンドから始めましょう:
git fsck
結果が何も表示されなければ、おめでとうございます。リポジトリは完全にクリーンな状態です。もしdangling commitのリストが表示されても、あまり心配する必要はありません。これは通常、コミットの修正やブランチの切り替えによる日常的な痕跡に過ぎません。
より厳密にチェックするには、次のように入力します:
git fsck --full --strict
--strictフラグを使用すると、Gitはフォーマットの細部まで厳密に検査します。このコマンドは、チームメンバー間でのデータ同期に問題があるのではないかと疑われる場合に非常に有用です。
2. 失われたコミットの検索と復元
マージ前のブランチを誤って削除してしまったとしましょう。この場合、git logからは完全にその痕跡が消えてしまいます。しかし、パニックになる必要はありません。そのコミットはまだdangling objectsの中に存在しています。
以下のコマンドを使用して、アクセス不能なコミットを抽出します:
git fsck --unreachable | grep commit
ハッシュ値のリストを取得したら、git show <commit-hash>を使って内容を確認します。復元したいコミットを特定できたら、そのハッシュ値を指す新しいブランチを作成するだけです:
git branch recovery-branch <commit-hash>
Tips: リストが長すぎる場合は、git fsck --lost-foundを使用してください。Gitは孤立したオブジェクトを自動的に.git/lost-found/ディレクトリに分類してくれるため、通常のファイルマネージャーで中身を簡単に確認できるようになります。
3. Corrupt Object(重大なエラー)への対処
sha1 mismatchというメッセージが表示された場合、それは物理的な破損の兆候です。以下の応急処置を試してみてください:
- reflogの確認:
git reflogを実行して、エラーが発生する直前の最新の復元ポイントを探します。 - 破損したオブジェクトの置換: 破損したblobが特定できている場合は、
.git/objects内の該当ファイルを削除します。その後、チームの他のメンバーのPCからそのファイルを再度git checkoutしてみてください。 - リモートの活用: 最も安全な方法は、リポジトリを新しいディレクトリにクローンし直すことです。その後、新しい
.gitディレクトリを古いフォルダに上書きコピーします(実行前に必ず古いフォルダのバックアップを取ってください)。
実践的なアドバイス:予防は治療に勝る
8人のチームで活動していた際、私は常に「早めにプッシュ、こまめにプッシュ」というルールを求めていました。git fsckは非常に強力ですが、救えるのは一度でもgit addやgit commitを行ったものだけです。ハードドライブに問題が発生した際、untracked状態のファイルは永遠に失われてしまいます。
また、定期的にgit gc(Garbage Collection)を実行しましょう。このコマンドはリポジトリを圧縮して軽量化するだけでなく、バックグラウンドでgit fsckを実行して不要なオブジェクトをクリーンアップします。ただし、git gcによるクリーンアップ後(通常14日後)は、dangling commitはメモリ解放のために永久に削除されることに注意してください。
結論
毎日使うコマンドではありませんが、git fsckはプロのエンジニアなら知っておくべきサバイバルスキルです。Gitがどのようにオブジェクトを管理しているかを理解することで、データ紛失という事態にも自信を持って対処できるようになります。次にGitで不可解なエラーに遭遇したときは、リポジトリを削除する前に、まずは落ち着いてfsckを試してみてください。ソースコードを安全に守りましょう!
