web-dev-qa-db-ja.com

破損したGitリポジトリを修復する

電源の問題のために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...)

したがって、ご覧のとおり、現在のブランチはかなり台無しになっており、修正することはできないようです。これを修復するにはどうすればよいですか?

40
Unknown

同様の状況に対する私の解決策は、.git/refs/heads/my-working-branchの破損したオブジェクトのハッシュを以前のコミットのハッシュ(.git/logs/HEADにあります)に置き換えることでした。

35
Nash Bridges

これはちょうど私に起こった。リポジトリを新しいフォルダに複製し、最新の変更を手動で移動します。ローテクですが、毎回機能します。うまくいけば、最後の変更を思い出せるでしょう。

16
nbushnell

私にとっては、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そして、マスターブランチをセットアップし、何も失われることなくバックアップおよび実行されました。

9
steve

リポジトリのバックアップを作成してから、git reset --hard HEAD@{1}前のHEADに戻り、これが機能するかどうかを確認します。破損しているのは、現在のHEADだけかもしれません。

(ディスクでfsckをまだ実行していない場合は実行する必要があります。)

7
Michael Mior

私にとって最も簡単な解決策: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/
3
sanji_mika

リポジトリを次の場所から復元できました。

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'
2
ony

私のために働いた別の選択肢は、Gitのヘッドとインデックスを以前の状態にリセットすることでした:

git reset --keep

次のコマンドも試してみましたが、私にはうまくいきませんでしたが、あなたには役立つかもしれません:

git reset --mixed
git fsck --full
git gc --auto
git Prune --expire now
git reflog --all
2
gaborous

私は同じ問題を抱えていて、 git-repair を使用して次の手順を実行しました

  • cp myrepo myrepo.bak
  • cd myrepo
  • git repair --force(最初にforceなしで試してください)

これが成功した後、ツリーは最後の作業コミットに戻されました。

それから私はmeld myrepo myrepo.bak破損したリポジトリの作業ツリーから固定リポジトリに変更を適用します。

1
student

破損した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

それは私のために働いた。

1
MrJ