Repair corrupted Git repository

荒凉一梦 提交于 2019-12-28 02:49:07

问题


My Git repository got corrupted after a couple of hard reboots due to power supply issues and now I'm unable to fix it (I was in the middle of staging some files at the last power failure):

$ 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...)

So, as you can see, my current branch is pretty screwed up, and I don't seem to be able to fix it. What can I try to repair this?


回答1:


My solution for a similar situation was to replace a hash of the damaged object in .git/refs/heads/my-working-branch with a hash of previous commit (which can be found in .git/logs/HEAD).




回答2:


This just happened to me. I reclone the repository in a new folder and move my latest changes over manually. Low tech, but it works every time. Hopefully you can remember your last changes.




回答3:


For me, I had enabled TRIM in OS X with a non-Apple SSD (which is not recommended) and apparently caused various corruptions on my boot disk. So the corrupted commit was deep in the history.

I don't care too much about repairing my repository, except I have a few local branches that were too experimental to bother pushing to the remote repository, and I'd like to salvage the work in those branches.

Theoretically, since this is a local repository, I feel that Git should be able to recover/repair itself using origin. Why isn't this possible?

At any rate I stumbled across this cool strategy to push a branch to another local Git repository. Unfortunately, cloning the repository into ../repo_copy and then using that as a local remote resulted in the following error:

! 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'

So I started instead with an empty repository, and then pushing branches to it worked OK. So for any local branch I had whose git log didn't end in:

....
    Fixing cukes
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument

I simply would check it out and then do git push --force local_remote HEAD. The last thing I did was:

! cd ~/Dev/repo_copy
! git remote add origin git@github.com:sdhull/my_repo.git  # real remote

Then I went in to git config -e and set up my master branch and was back up and running with nothing lost!




回答4:


Try making a backup of the repository and then running git reset --hard HEAD@{1} to go back to the previous HEAD and see if this works. It may be just the current HEAD which is corrupted.

(You should also run fsck on your disk if you haven't already.)




回答5:


The most simple solution for me: You could git clone in a new folder, then replace the clean new_folder/.git to the old folder (the broken folder). It works well for me!

git clone ...(remote) new_folder
mv old_folder/.git  old_folder/.git_old
cp -R new_folder/.git  old_folder/



回答6:


Another alternative which worked for me was to reset the Git head and index to its previous state using:

git reset --keep

I also tried the following commands, but they did not work for me, but they might for you:

git reset --mixed
git fsck --full
git gc --auto
git prune --expire now
git reflog --all



回答7:


I was able to recover my repository from:

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 <virkony@gmail.com> 1379583764 +0300    commit: plan: timings

By resetting master to prev commit da9c14d03e4849394087b61ff6272399937f7cce as told by @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

Creating a new empty repository, fetching master from broken:

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.

To restore those changes that was on the way to master:

zsh(recover)% rm -rf * && cp -a ../broken/* ./
zsh(recover)% git add -u && git commit -m 'prepare for publishing'



回答8:


I followed the instructions found in Recovering from a corrupt Git repository:

$ 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

It worked for me.




回答9:


I had the same problem and did the following steps using git-repair

  • cp myrepo myrepo.bak
  • cd myrepo
  • git repair --force (first try it without force)

After this was successful the tree was set back to the last working commit.

Then I did meld myrepo myrepo.bak to apply changes from the working tree of the corrupted repository to the fixed repository.



来源:https://stackoverflow.com/questions/8271263/repair-corrupted-git-repository

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!