電源の問題のために2、3回ハードリブートした後、Gitリポジトリが破損しましたが、今は修正できません(最後の電源障害でいくつかのファイルをステージングしていました)。
$ git status
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git fsck
fatal: failed to read object 24377c609184c192f3f3c1733bac7115c1080758: Invalid argument
$ git branch -a
(...works, lists branches...)
$ git checkout someotherbranch
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log someotherbranch
(...works, shows commits...)
したがって、ご覧のとおり、現在のブランチはかなり台無しになっており、修正することはできないようです。これを修復するにはどうすればよいですか?
同様の状況に対する私の解決策は、.git/refs/heads/my-working-branch
の破損したオブジェクトのハッシュを以前のコミットのハッシュ(.git/logs/HEAD
にあります)に置き換えることでした。
これはちょうど私に起こった。リポジトリを新しいフォルダに複製し、最新の変更を手動で移動します。ローテクですが、毎回機能します。うまくいけば、最後の変更を思い出せるでしょう。
私にとっては、OS Xで非Apple SSDを使用してTRIMを有効にし(推奨されません)、明らかにブートディスクでさまざまな破損を引き起こしました。そのため、破損したコミットは歴史の奥深くにありました。
リポジトリの修復についてはあまり気にしませんが、リモートリポジトリにプッシュするのが面倒なローカルブランチがいくつかあり、それらのブランチで作業を回収したい場合を除きます。
理論的には、これはローカルリポジトリであるため、GitはOriginを使用して自身を回復/修復できるはずです。なぜこれが不可能なのですか?
とにかく偶然出会ったのは ブランチを別のローカルGitリポジトリにプッシュするこのクールな戦略 です。残念ながら、リポジトリを../repo_copy
そして、それをローカルリモートとして使用すると、次のエラーが発生しました。
! git Push --force local_remote HEAD
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument
error: failed to Push some refs to '/Users/steve/Dev/repo_copy'
そのため、代わりに空のリポジトリで開始し、そこにブランチをプッシュして問題なく動作しました。そのため、git log
で終わらない:
....
Fixing cukes
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument
単純にチェックアウトしてからgit Push --force local_remote HEAD
。私が最後にしたことは:
! cd ~/Dev/repo_copy
! git remote add Origin [email protected]:sdhull/my_repo.git # real remote
それから私はgit config -e
そして、マスターブランチをセットアップし、何も失われることなくバックアップおよび実行されました。
リポジトリのバックアップを作成してから、git reset --hard HEAD@{1}
前のHEAD
に戻り、これが機能するかどうかを確認します。破損しているのは、現在のHEAD
だけかもしれません。
(ディスクでfsck
をまだ実行していない場合は実行する必要があります。)
私にとって最も簡単な解決策:git clone
を新しいフォルダーに入れてから、きれいなnew_folder/.gitを古いフォルダー(壊れたフォルダー)に置き換えます。それは私のためにうまくいきます!
git clone ...(remote) new_folder
mv old_folder/.git old_folder/.git_old
cp -R new_folder/.git old_folder/
リポジトリを次の場所から復元できました。
zsh(broken)% git log master
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
fatal: loose object 7fcab8648a989d9bb3f5246e6be7220395493395 (stored in .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395) is corrupt
zsh(broken)% cat .git/refs/heads/master
7fcab8648a989d9bb3f5246e6be7220395493395
e311726c4eb970f4d4f504ad86248d322855018f da9c14d03e4849394087b61ff6272399937f7cce Nikolay Orliuk <[email protected]> 1379583764 +0300 commit: plan: timings
master
をリセットしてprev commit da9c14d03e4849394087b61ff6272399937f7cce
@Nash Bridgesによると:
zsh(broken)% echo da9c14d03e4849394087b61ff6272399937f7cce > .git/refs/heads/master
zsh(broken)% git log --oneline -1 master
da9c14d plan: timings
zsh(broken)% git fsck
Checking object directories: 100% (256/256), done.
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
fatal: loose object 0eace931fdc851da254e9522596d1517d0ed51c5 (stored in .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5) is corrupt
壊れたmaster
を取得して、新しい空のリポジトリを作成します。
zsh(broken)% mkdir ../recover && cd ../recover && git init
Initialized empty Git repository in /home/nikolay/talks/y/recover/.git/
zsh(recover)% git fetch ../broken master
remote: Counting objects: 44, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 44 (delta 20), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
From ../broken
* branch master -> FETCH_HEAD
zsh(recover)% git reset --hard FETCH_HEAD
HEAD is now at da9c14d plan: timings
zsh% git fsck
Checking object directories: 100% (256/256), done.
master
への途中にあった変更を復元するには:
zsh(recover)% rm -rf * && cp -a ../broken/* ./
zsh(recover)% git add -u && git commit -m 'prepare for publishing'
私のために働いた別の選択肢は、Gitのヘッドとインデックスを以前の状態にリセットすることでした:
git reset --keep
次のコマンドも試してみましたが、私にはうまくいきませんでしたが、あなたには役立つかもしれません:
git reset --mixed
git fsck --full
git gc --auto
git Prune --expire now
git reflog --all
私は同じ問題を抱えていて、 git-repair を使用して次の手順を実行しました
cp myrepo myrepo.bak
cd myrepo
git repair --force
(最初にforce
なしで試してください)これが成功した後、ツリーは最後の作業コミットに戻されました。
それから私はmeld myrepo myrepo.bak
破損したリポジトリの作業ツリーから固定リポジトリに変更を適用します。
破損したGitリポジトリからの回復にある指示に従いました。
$ cd /tmp/
$ git clone good-Host:/path/to/good-repo
$ cd /home/user/broken-repo
$ echo /tmp/good-repo/.git/objects/ > .git/objects/info/alternates
$ git repack -a -d
$ rm -rf /tmp/good-repo
それは私のために働いた。