Git:「壊れた緩いオブジェクト」


329

リモートからプルすると、圧縮に関する次のエラーが表示されます。手動圧縮を実行すると、同じ結果になります。

$ git gc
error: Could not read 3813783126d41a3200b35b6681357c213352ab31
fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
error: failed to run repack

誰か知っていますか、それについて何をすべきですか?

猫ファイルから私はこれを得ます:

$ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
error: unable to find 3813783126d41a3200b35b6681357c213352ab31
fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file

そしてgit fsckから私はこれを取得します(それが実際に関連しているかどうかはわかりません):

$ git fsck
error: inflate: data stream error (invalid distance too far back)
error: corrupt loose object '45ba4ceb93bc812ef20a6630bb27e9e0b33a012a'
fatal: loose object 45ba4ceb93bc812ef20a6630bb27e9e0b33a012a (stored in .git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted

誰かがこれを解読するのを手伝ってくれる?


後者のオブジェクト(45ba4ceb93bc812ef20a6630bb27e9e0b33a012a)を見てみましたか?
Gintautas Miliauskas、2010年

4
ありがとう...しかし、オブジェクトをどのように「見る」のでしょうか。gitにはまだ新しい:)
asgerhallas

2
「git show」を実行すると、残念ながら「git fsck」以外の機能はありません。
asgerhallas 2010年

4
Linus Torvaldsは、このエラーと、ファイルがある場合に手動でblobを再構築する方法について、次の役立つドキュメントを書きました。 破損したBLOBオブジェクトを回復する方法破損したリポジトリを固定するためにブロブオブジェクトを再構築するためにいくつかのトリックを
ウーヴェ・クライネ・ケーニッヒを

2
承認された回答にコメントを追加したり、編集したりできますか?私はまったく同じ状況にあり、受け入れられた回答には「Just Work TM」に十分な詳細が含まれていないようですが、代わりに自分で詳細に飛び込むよう強制されます。
ripper234 2012

回答:


57

破損したツリーオブジェクトがあるようです。他の人からそのオブジェクトを取得する必要があります。うまくいけば、彼らは破損していないバージョンを持っているでしょう。

他の誰かから有効なバージョンが見つからない場合は、そこにあるファイルを推測することで実際に再構築できます。オブジェクトの日付と時刻がそれと一致するかどうかを確認したい場合があります。それらは関連するブロブである可能性があります。これらのオブジェクトからツリーオブジェクトの構造を推測できます。

を見てみましょう git internalsに関するScott ChaconのGit Screencastを。これにより、内部でgitがどのように機能するか、また、本当に行き詰まって他の人からそのオブジェクトを取得できない場合に、この探偵の作業をどのように行うかがわかります。


2
パックファイルに格納される場合があります。これは、gitがデルタを格納することによってオブジェクトのストレージを圧縮する方法です。緩いオブジェクトとは、まだパッケージに含まれていないオブジェクトです。Googleのパックファイル、Gitのインデックスファイルを使用すると、必要なだけ深く掘り下げることができます。
Adam Dymitruk、2010年

2
ChaconのGitスクリーンキャストへの回答にリンクを提供できますか?
Ehtesh Choudhury、2012

1
git cat-file -t <SHA1>タイプを教えてくれます。破損していない場合はgit cat-file <type> <SHA1>、コンテンツを確認できます(私はに使用しましたblob。他のタイプのコンテンツも表示されると思います。)
Carl G

1
また、Linusからのこの投稿では、を回復するプロセスについて説明していますblob。しかし、これらの指示に従っていると、正常に実行できたにもかかわらずgit status応答fatal: unable to read <SHA1>しましたgit hash-object -w <file>(おそらく、彼の指示に従って、そのオブジェクトファイルを移動したためです。それを返すと、同じcorrupt loose objectエラーが発生しました。)
Carl G

2
そして今英語で繰り返してください
Mehdi

359

私は同じ問題を抱えていました(理由はわかりません)。

この修正では、破損していないリポジトリのリモートコピーにアクセスする必要があり、ローカルで作業しているコピーをそのまま維持します。

しかし、いくつかの欠点があります。

  • プッシュされなかったコミットの記録は失われ、再コミットする必要があります。
  • あなたはすべての隠し場所を失います。

修正

リポジトリの上の親ディレクトリから次のコマンドを実行します( 'foo'をプロジェクトフォルダーの名前に置き換えます)。

  1. 破損したディレクトリのバックアップを作成します。
    cp -R foo foo-backup
  2. リモートリポジトリの新しいクローンを新しいディレクトリに作成します。
    git clone git@www.mydomain.de:foo foo-newclone
  3. 破損した.gitサブディレクトリを削除します。
    rm -rf foo/.git
  4. 新しくクローンした.gitサブディレクトリをfooに移動します。
    mv foo-newclone/.git foo
  5. 一時的な新しいクローンの残りを削除します。
    rm -rf foo-newclone

Windowsでは、以下を使用する必要があります。

  • copy の代わりに cp -R
  • rmdir /S の代わりに rm -rf
  • move の代わりに mv

これでfooには元の.gitサブディレクトリが戻りましたが、ローカルの変更はすべてそのまま残っています。git statuscommitpullpush、など、彼らが必要として再び働きます。


11
この方法でうまくいきました。ただし、プッシュされていないコミットはすべて失われたと思います。レポデータは変更されていません。
2013

30
はい、プッシュされていないコミット情報は失われます。ただし、一般的なシナリオ(現在以外のプッシュされていない変更がある複数のローカルブランチがない場合)では、最新のファイル変更(インクル削除)はすべてディスク上にあるため、以前のプッシュされていないコミットを簡単に繰り返すことができます。私は常にコミットのシーケンスの後でプッシュするので、私はこのトラブルに遭遇しませんでした。
キュービックレタス

7
シンプルでわかりやすい。これはIMOであり、gitに関するすべてを理解しておらず、リポジトリをいじりたくない場合に最も効率的なソリューションです。
Oliboy50 2014年

4
それらは.gitサブディレクトリの下に格納されているため、すべてのスタッシュが削除されると思います。
アンソニーエリオット

4
プロジェクトにサブモジュールがある場合、.gitフォルダーを取得する前にそれらを初期化する必要があります。
AdrieanKhisbe 14

242

あなたの最善の策は、おそらくリモートリポジトリ(Githubなど)から単純に再クローンすることです。残念ながら、プッシュされていないコミットと隠された変更は失われますが、作業コピーはそのまま残ります。

まず、ローカルファイルのバックアップコピーを作成します。次に、作業ツリーのルートからこれを実行します。

rm -fr .git
git init
git remote add origin [your-git-remote-url]
git fetch
git reset --mixed origin/master
git branch --set-upstream-to=origin/master master  

次に、必要に応じて変更されたファイルをコミットします。


12
私見これは受け入れられる答えであるべきです。リポジトリを削除して再クローニングするよりもはるかに簡単です!:)あなたはステージングされたコミットを失いますが...
Nick

6
明らかに、破損が発生したときにマスター以外のブランチにいた場合はmaster、ブランチ名に置き換えます。
ティモシーゾーン

ほとんどがそのまま機能していましたが、working破損して別のブランチにいたため、これらの手順でマスター以外のブランチのローカルコピーが提供されませんでした(そして、はい、上記のマスターを置き換えようとしましたworkingが、機能しませんでした)。で上記の手順を実行してmasterから、私の変更を隠しておき、checkout -b working origin/workingそこに隠し場所をポップしました。うまくいったようです-ありがとうございます!
幻想的な

1
私のリポジトリには破損していないサブモジュールがありました。このプロセスにより、リポジトリとそのサブモジュールは、などのコマンドが生成された状態になりgit statusましたfatal: Not a git repository: submodules/my-sub/../../.git/modules/my-sub。ファイルシステムからサブモジュールを削除してプロセスを再起動すると、正常性が回復しました。おそらく最初にサブモジュールにプッシュされていないチェンジセットがないことを確認することは良い考えです...
Steven Baldasty

5
今日はこれをしなかったし、ファイルになかったではない失うコミットされていない変更:)(gitの2.17.1)
ファビオ・ディアス

173

私のノートブックでVMを使用すると、バッテリーが切れてこのエラーが発生しました。

エラー:オブジェクトファイル.git / objects / ce / theRefが空ですエラー:オブジェクトファイル.git / objects / ce / theRefが空です致命的:ルーズオブジェクトtheRef(.git / objects / ce / theRefに保存されています)が破損しています

2つのコマンドだけで、作業を失うことなく、リポジトリを再び機能させることができました(変更されたファイル/コミットされていない変更)

find .git/objects/ -size 0 -exec rm -f {} \;
git fetch origin

その後、私はを実行しましたgit statusが、レポは問題なく、変更が行われました(コミットされるのを待って、今すぐ実行してください。

gitバージョン1.9.1

このソリューションが機能せず、より根本的なアプローチが必要な場合に備えて、覚えているすべての変更をバックアップしてください。


10
find .git/objects/ -size 0 -exec rm -f {} \;私のために働く;)
ラサロフェルナンデスリマスレイマン

同じ問題があり、コマンドを実行し、Mint VMで完全に動作しました。
Ludvig Rydahl

また、他に何もしなくても完璧に機能しました。
Halsafar 2017年

1
VMではなく、これは私にとって何度も機能しました。IDKが現在のプロジェクトでこれが起こり続ける理由ですが、これにより毎回修正されます。
James

7
git symbolic-ref HEAD refs/heads/master.空のオブジェクトを削除した後に実行する必要がある場合があります。
ステファン

43

コミットメッセージを書いている最中にコンピューターがクラッシュしました。再起動後、作業ツリーは以前と同じ状態になり、変更を正常にコミットすることができました。

しかし、実行しようとするgit statusと、

error: object file .git/objects/xx/12345 is empty
fatal: loose object xx12345 (stored in .git/objects/xx/12345 is corrupt

他のほとんどの回答とは異なり、私はデータを回復しようとはしていませんでした。空のオブジェクトファイルについて文句を言うのをやめるには、Gitが必要でした。

概観

「オブジェクトファイル」は、あなたが気にする実際のファイルのgitのハッシュ表現です。Gitは、ハッシュされたバージョンのsome/file.whateverされた格納され.git/object/xx/12345、エラーの修正は、ほとんどの場合、「ルーズオブジェクト」がどのファイルを表すことになっていたかを理解することでした。

細部

可能なオプションは

  1. 空のファイルを削除する
  2. ファイルをGitが受け入れ可能な状態にする

アプローチ1:オブジェクトファイルを削除する

私が最初に試みたのは、オブジェクトファイルを移動することだけです。

mv .git/objects/xx/12345 ..

それはうまくいきませんでした-gitはリンク切れについて不平を言い始めました。アプローチ2に進みます。

アプローチ2:ファイルを修正する

Linus Torvaldsが、問題を解決したオブジェクトファイルを回復する方法について、すばらしい記事を書いています。ここでは、主要な手順をまとめています。

$> # Find out which file the blob object refers to
$> git fsck
broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
           to    blob xx12345
missing blob xx12345

$> git ls-tree 2d926
...
10064 blob xx12345  your_file.whatever

これは、空のオブジェクトがどのファイルであると想定されているかを示します。これで修復できます。

$> git hash-object -w path/to/your_file.whatever

これを行った後、私はをチェックしましたが.git/objects/xx/12345、空ではなくなったため、gitは文句を言うのをやめました。


リポジトリのリモートまたはバックアップがなく、破損したオブジェクトが最初のコミットの近くに追加されたため、おそらくツリー全体が破損している状況でした。私は自分の方法でオブジェクトを別のリポジトリに再作成しようとしましたが、この答えはより洗練された同じ結果を達成します。
Estecka

13

試す

git stash

これでうまくいきました。それはあなたがコミットしていないものを隠し、それが問題を回避しました。


おかしい!?! 今朝このエラーに出くわした。昨日コミットしたので、コミットされていない変更はありません。次の操作を行いました: git stash ...致命的: '/home/<user>/.git/index.lock'を作成できません:入出力エラー touch .git/a touch:タッチできません '.git / a':入出力エラー sudo touch /home/guest/.git/a NO ERROR git stash いいえ保存するローカル変更 git status ...コミットするものは何もない、作業ディレクトリはクリーン
go2null

1
@ go2nullこれには少し遅れますが、入出力エラーは一般的にハードドライブの問題を意味します。あなたはこれを今までに理解したと確信していますが。
arleslie 2016年

「現在のインデックスの状態を保存できません」
Vladimir Brasil

9

ガベージコレクションは、私の問題を修正します:

git gc --aggressive --prune=now

完了するまで少し時間がかかりますが、すべてのルーズオブジェクトや破損したインデックスが修正されました。


これは良い解決策です。私のために働いた。システムが誤ってシャットダウンしました。しかし、この1つのコマンドで、クローン作成やそれらすべての重いタスクから私を救いました。Jagoに感謝します。
Mukesh Kumar

「reflogの実行に失敗しました」
Vladimir Brasil

5

git prune修正済みのこの問題を実行してください


これは私にとってはうまくいき、最も簡単な解決策のようです。なぜこの回答がそれ以上の票を獲得しなかったのか分かりません。唯一の欠点は、次のものgit pullは通常よりも少し時間がかかることです。これは、削除されたオブジェクトなどを置き換えるためです。
steev

1
その理由は、git pruneが問題をまったく解決しないためかもしれません。
user3072843

4

私はちょうどこれを経験しました-Gitリポジトリに書き込み中にマシンがクラッシュし、破損しました。以下のように修正しました。

まず、リモートリポジトリにプッシュしなかったコミットの数を確認することから始めました。

gitk &

このツールを使用しない場合は非常に便利です。私の知る限り、すべてのオペレーティングシステムで使用できます。これは、私のリモコンに2つのコミットがないことを示しています。そのため、最新のリモートコミットを示すラベルをクリックしました(通常、これは/remotes/origin/master)をハッシュを取得しました(ハッシュは40文字ですが、簡潔にするために、ここでは10を使用しています-これは通常はとにかく動作します)。

ここにあります:

14c0fcc9b3

次に、次のコミット(つまり、リモートにない最初のコミット)をクリックして、そこにハッシュを取得します。

04d44c3298

次に、これらの両方を使用して、このコミットのパッチを作成します。

git diff 14c0fcc9b3 04d44c3298 > 1.patch

次に、他の欠落しているコミットについても同様に行いました。つまり、以前のコミットのハッシュとコミット自体のハッシュを使用しました。

git diff 04d44c3298 fc1d4b0df7 > 2.patch

次に、新しいディレクトリに移動し、リモートからリポジトリを複製しました。

git clone git@github.com:username/repo.git

次に、パッチファイルを新しいフォルダに移動し、それらを適用して、正確なコミットメッセージでコミットしました(これらgit loggitkウィンドウまたはウィンドウから貼り付けることができます)。

patch -p1 < 1.patch
git commit

patch -p1 < 2.patch
git commit

これは私のために物事を復元しました(そして、多くのコミットのためにそれを行うより速い方法がおそらくあることに注意してください)。しかし、破損したリポジトリのツリーを修復できるかどうかを知りたいと思っていました。上記のように利用可能な修復されたレポで、壊れたフォルダーで次のコマンドを実行します。

git fsck 

あなたはこのようなものを得るでしょう:

error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d

修復するには、壊れたフォルダで次のようにします。

rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d

つまり、破損したファイルを削除して、適切なファイルに置き換えます。これを数回行う必要がある場合があります。最後に、実行できるポイントがありますfsckエラーなし。レポートにはおそらく「ダングリングコミット」行と「ダングリングブロブ」行があります。これらは、このフォルダーのリベースと修正の結果であり、問​​題ありません。ガベージコレクターは、やがてそれらを削除します。

したがって、(少なくとも私の場合は)ツリーが破損しても、プッシュされていないコミットが失われるわけではありません。


3

壊れたルーズオブジェクトエラーも発生していました。

./objects/x/x

破損したオブジェクトのディレクトリに移動して、問題を修正しました。そのオブジェクトに割り当てられているユーザーが私のgitユーザーのものではないことがわかりました。どうやって起こったのかはわかりませんが、chown git:gitそのファイルでを実行すると、再び機能しました。

これは一部の人々の問題の潜在的な修正になる可能性がありますが、すべての問題に必要なわけではありません。


2

私の(windows)マシンが再起動することを決めた後、このエラーが発生しました。ありがたいことに、私のリモートリポジトリは最新の状態だったので、新しいgitクローンを作成しました。



2

ここでは他の多くの手順を実行しました。Linusによるgitツリー/オブジェクトの見方と不足しているものを見つける方法の説明は、特に役に立ちました。git-gitが破損したblobを回復する

しかし、結局のところ、私にとっては、部分的なディスク障害によって引き起こされた緩やかな/破損したツリーオブジェクトがあり、ツリーオブジェクトはそのドキュメントで簡単に回復/カバーされません。

最後に、私は競合をobjects/<ha>/<hash>邪魔にならないように移動git unpack-objectsし、適度に最新のクローンのパックファイルを使用しました。不足しているツリーオブジェクトを復元することができました。

それでもたくさんのぶら下がっているブロブが残っていますが、これは以前にアーカイブされたものを解凍することの副作用となる可能性があり、ここの他の質問対処されています


2

@ user1055643の最後のステップが欠落している答え:

$ rm -fr .git
$ git init
$ git remote add origin your-git-remote-url
$ git fetch
$ git reset --hard origin/master
$ git branch --set-upstream-to=origin/master master  

--set-upstream-toは有効な引数ですか?私はそうは思わない!
Sharif Mamun 2014年

2
gitのブランチ(--set-上流へ= <上流> | -u <上流>)[<branchname>]
エルトゥールルAltınboğa

.gitクローンプロジェクトから削除してコピーすると、リポジトリは機能しますが、ローカルブランチやスタッシュは保持されません。
Vladimir Vukanac 2017

1

ちょうどここに事件があった。問題は、破損したファイルの所有権が通常のユーザーではなくrootであることでした。これは、誰かが「sudo su-」を実行した後にサーバーで行われたコミットが原因でした。

まず、破損したファイルを次のように特定します。

$> git fsck --full

あなたはこのような答えを受け取るはずです:

fatal: loose object 11b25a9d10b4144711bf616590e171a76a35c1f9 (stored in .git/objects/11/b25a9d10b4144711bf616590e171a76a35c1f9) is corrupt

破損したファイルがあるフォルダーに移動し、次の操作を行います。

$> ls -la

破損したファイルの所有権を確認してください。それが異なる場合は、リポジトリのルートに戻って次のようにしてください。

$> sudo chown -R YOURCORRECTUSER:www-data .git/

それが役に立てば幸い!


1

私にとってこれは、実行中に停電が原因で起こりました git push

メッセージは次のようになりました。

$ git status
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
fatal: loose object c238824eb3fb602edc2c49fccb535f9e53951c74 (stored in .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74) is corrupt

私はgit fsckそのようなことを試しましたが、それは助けにはなりませんでした。クラッシュは中git pushに発生したため、サーバーが更新された後に発生するクライアント側の書き換え中に発生したことは明らかです。私は周りを見回してc2388、私の場合はコミットオブジェクトであることを理解しました.git/refs。だから私は見つけることができることを知っていましたc2388、履歴を見ると(Webインターフェースまたは2番目のクローンを介した。

2番目のクローンでは、git log -n 2 c2388の前身を識別するためにa を実行しましたc2388。その後、私は手動で変更し.git/refs/heads/master.git/refs/remotes/origin/masterc2388代わりにの前任者になりましたc2388。その後、私は行うことができますgit fetchgit fetch空のオブジェクト上の競合のために数回失敗しました。git fetch成功するまで、これらの空のオブジェクトをそれぞれ削除しました。これでリポジトリが修復されました。


1

私はこの方法で解決しました。破損していないオブジェクトファイルをバックアップのクローンから元のリポジトリに単にコピーすることにしました。これもうまくいきました。(ちなみに、名前で.git / objects /にオブジェクトが見つからない場合は、おそらくスペースを節約するために[パック] [パック]されています。)


0

私の裸のリモートgitリポジトリにも同じ問題がありました。多くのトラブルシューティングの後、同僚の1人が.git / objects内の一部のファイルに444(r--r--r)ではなく440(r--r -----)のアクセス許可があるコミットを行ったことがわかりました-)。裸のgitリポジトリ内の「chmod 444 -Rオブジェクト」で権限を変更するよう同僚に依頼した後、問題は修正されました。


0

私はこのような問題を抱えていました。私の特定の問題は、最新のコミット(したがって、マスターブランチ)を破壊するシステムクラッシュが原因でした。私はプッシュせず、そのコミットを作り直したいと思っていました。私の特定のケースでは、次のように対処できました。

  1. のバックアップを作成し.git/ます。rsync -a .git/ git-bak/
  2. を確認.git/logs/HEADし、有効なコミットIDの最後の行を見つけます。私にとって、これは2番目に新しいコミットでした。私はまだファイルの作業ディレクトリバージョンを持っているので、これは良かったので、必要なすべてのバージョンを使用できました。
  3. そのコミットでブランチを作成します。 git branch temp <commit-id>
  4. 壊れたコミットを作業ディレクトリのファイルで再実行します。
  5. git reset master temp 手順2で作成した新しいコミットにマスターブランチを移動します。
  6. git checkout masterそして、それがで正しく見えることを確認してくださいgit log
  7. git branch -d temp
  8. git fsck --fullこれで、fsckが検出した破損オブジェクトを削除しても安全です。
  9. 問題がなければ、プッシュしてみてください。それがうまくいけば、

それは私のために働いた。最近のコミットが破損している可能性が最も高いので、これはかなり一般的なシナリオだと思いますが、さらに1つ失うと、おそらくこのような方法を使用できgit cherrypick、とreflog を慎重に使用できますの中で.git/logs/HEAD


0

この問題が発生したとき、私は最近の変更をバックアップし(変更内容を知っていたので)、そのファイルを削除しました。次に、git pullを実行しました。ただし、注意してください。これは機能しない場合があります。


0

システムがクラッシュした後、これに遭遇しました。私がしたことはこれです:

(破損したコミットは失われますが、変更は保持されます。この手順の最後にこれらのコミットを再作成する必要がある場合があります)

  • コードをバックアップします。
  • 作業ディレクトリに移動し、.gitフォルダーを削除します。
  • 次に、リモートを別の場所に複製し、その中に.gitフォルダをコピーします。
  • 作業ディレクトリに貼り付けます。
  • 思い通りにコミットします。

-7

.gitフォルダを削除して、もう一度追加します。この簡単な解決策は私にとってうまくいきました。


3
これにより、ローカルリポジトリが破壊されます...、望ましくない副作用が発生する可能性があります:)提案を編集して警告を追加してください。
Felix

1
を削除.gitし、クローンプロジェクトからコピーすると、リポジトリは機能しますが、ローカルブランチやスタッシュは保持されません。また、友好的な提案として、反対票の受信を停止するために回答を完全に削除してください。
Vladimir Vukanac 2017

1
うわーネリー...ピンセットの仕事にバズーカを使うことについて話します。
TuncayGöncüoğlu18年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.