web-dev-qa-db-ja.com

壊れた/部分的に削除されたgitリポジトリを回復する方法

誤ってrm -r .gitディレクトリ。 Luckly rmは書き込み保護されたファイルに到達すると停止しましたが、.gitでいくつかのものが失われました。

まだ持っているファイル:

FETCH_HEAD
ORIG_HEAD
config
gitk.cache
logs/
objects/

私が失ったファイル:

HEAD
description
hooks/
index
info/
packed-refs
refs/

私が知ることができることから、私が失った唯一の再クローンができないことは、私のステージングエリアと私の参照の変更です。私はステージングの変更を失う準備ができていますが、本当にHEADと私のブランチを回復する必要があります。これを行う方法はありますか?たとえば、子のないコミットを見つけてチェックすることによってそれらが何であるかを確認し、それらのブランチを作成していますか?現在のところ、gitは私のリポジトリをリポジトリとして認識しません。

7
Shum

すべてのコミットとそれらが参照するファイルは、objectsディレクトリにオブジェクトとして保存されます。 Gitはそれらを読み取り専用として作成するので、すべて存在するはずです。

復旧するには、新しい空のリポジトリを作成し、壊れたリポジトリのobjectsディレクトリの内容を新しいものにコピーすることをお勧めします。これで、gitが少なくともリポジトリであることを認識し、すべてのオブジェクトが含まれるようになるはずです。コピーで作業することは、物事を修正しようとしているときに、さらに大きな損傷を引き起こさないようにするのにも役立ちます。

一時リポジトリを作成してオブジェクトをコピーするシェルコマンド:

git init /tmp/recovery
cd /tmp/recovery
cp -r /path/to/broken/repo/.git/objects .git

それが完了したら、git fsckを使用して、何からも参照されていないオブジェクトのリストを取得できます。これにはすべてのブランチヘッドが含まれますが、git commit --amendまたはリベースによって廃止されたコミットも含まれます。

あなたはまだもっと大きな助けになる可能性が高いログディレクトリを持っているので。ブランチごとにlogs/refs/heads/<branch>ファイルが必要です。最終行の2列目には、削除が行われたときにそのブランチの先頭にあったコミットのIDが含まれます。 HEADがどこにあったかと同じ情報を含むlogs/HEADもあるはずですが、分離HEADで作業していなかった場合は、ブランチを回復することをお勧めしますそして通常通りブランチをチェックアウトします。

復元するブランチごとに、次のコマンドを実行できます。

git branch <name> <commit_id>

ブランチを復元したら、設定ファイルをコピーできます。最新のコミット時の状態にかなり近いはずです。

11
qqx