最初に次のコマンドを試します(必要に応じて再実行します)。
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
それでも問題が解決しない場合は、次のことを試してください。
破損したオブジェクトをすべて削除します。
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt
$ rm -v .git/objects/06/91c5...51e5
空のオブジェクトをすべて削除します。
error: object file .git/objects/06/91c5...51e5 is empty
$ find .git/objects/ -size 0 -exec rm -vf "{}" \;
「リンク切れ」メッセージを確認するには:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
これにより、破損したBLOBがどのファイルからのものであるかがわかります。
ファイルを回復するために、あなたは本当に幸運かもしれません、そしてそれはあなたがすでに作業ツリーでチェックアウトしたバージョンかもしれません:
git hash-object -w my-magic-file
もう一度、それが不足しているSHA1(4b945 ..)を出力する場合、これですべて完了です!
壊れたのが古いバージョンだとすると、それを行う最も簡単な方法は次のようにすることです。
git log --raw --all --full-history -- subdirectory/my-magic-file
これで、そのファイルのログ全体が表示されます(所有していたツリーが最上位のツリーではない可能性があるので、自分でどのサブディレクトリにあるかを確認する必要があることに注意してください)。次に、ハッシュオブジェクトを持つオブジェクトが再び見つかりません。
コミット、ツリー、ブロブが欠落しているすべての参照のリストを取得するには:
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
通常のブランチ-dまたはタグ-dコマンドを使用してこれらの参照の一部を削除できない場合があります。gitが破損に気付いた場合、これらの参照は停止するためです。したがって、代わりに配管コマンドgit update-ref -d $ refを使用してください。ローカルブランチの場合、このコマンドは古いブランチ構成を.git / configに残す可能性があることに注意してください。手動で削除できます([branch "$ ref"]セクションを探してください)。
すべての参照がクリーンになった後も、参照ログに壊れたコミットがある可能性があります。git reflog expire --expire = now --allを使用して、すべてのreflogをクリアできます。すべてのreflogを失いたくない場合は、個々のrefで壊れたreflogを検索できます。
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(git rev-listに追加された-gオプションに注意してください。)次に、それぞれに対してgit reflog expire --expire = now $ refを使用します。壊れた参照と参照ログがすべてなくなったら、git fsck --fullを実行して、リポジトリがクリーンであることを確認します。ぶら下がりオブジェクトは問題ありません。
以下は、賢い使い方をしないとgitリポジトリのデータが失われる可能性のあるコマンドの高度な使用法を示しています。誤ってgitにさらに損傷を与える前にバックアップを作成してください。自分のしていることがわかっている場合は、自分の責任で試してください。
フェッチ後に現在のブランチを上流のブランチの上にプルするには:
$ git pull --rebase
新しいブランチをチェックアウトして古いブランチを削除することもできます:
$ git checkout -b new_master origin/master
破損したオブジェクトをgitで見つけて削除するには、次のコマンドを試してください。
while [ true ]; do f=`git fsck --full 2>&1|awk '{print $3}'|sed -r 's/(^..)(.*)/objects\/\1\/\2/'`; if [ ! -f "$f" ]; then break; fi; echo delete $f; rm -f "$f"; done
OSXの場合は、のsed -E
代わりに使用しますsed -r
。
他のアイデアは、すべてのオブジェクトをパックファイルからアンパックして、.git / objects内のすべてのオブジェクトを再生成することです。そのため、リポジトリ内で次のコマンドを実行してみてください。
$ cp -fr .git/objects/pack .git/objects/pack.bak
$ for i in .git/objects/pack.bak/*.pack; do git unpack-objects -r < $i; done
$ rm -frv .git/objects/pack.bak
上記の方法で問題が解決しない場合は、rsyncを試すか、gitオブジェクトを別のリポジトリからコピーしてみてください。
$ rsync -varu git_server:/path/to/git/.git local_git_repo/
$ rsync -varu /local/path/to/other-working/git/.git local_git_repo/
$ cp -frv ../other_repo/.git/objects .git/objects
次のようにチェックアウトしようとしたときに壊れたブランチを修正するには:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
それを削除して、上流からもう一度チェックアウトしてみてください:
$ git branch -D master
$ git checkout -b master github/master
gitがデタッチされた状態になった場合は、チェックアウトmaster
してデタッチされたブランチにマージします。
別のアイデアは、既存のマスターを再帰的にリベースすることです:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
以下も参照してください。
.git
もちろんフォルダーを除く)からすべてのファイルを新しくクローンしたリポジトリにコピーします...その後git status
、新しいリポジトリで実行しました... gitはファイルへの影響を受けるすべての変更を正しく検出し、作業を再開できます。