修复损坏的 Git 存储库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8271263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:24:09  来源:igfitidea点击:

Repair corrupted Git repository

gitcorruption

提问by Unknown

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 存储库在几次硬重启后损坏,现在我无法修复它(上次电源故障时我正在暂存一些文件):

$ 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?

所以,正如你所看到的,我当前的分支非常糟糕,我似乎无法修复它。我可以尝试修复什么?

回答by Nash Bridges

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

我针对类似情况的解决方案是将损坏对象的哈希替换.git/refs/heads/my-working-branch为先前提交的哈希(可以在 中找到.git/logs/HEAD)。

回答by nbushnell

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.

这只是发生在我身上。我在新文件夹中重新克隆存储库并手动移动我的最新更改。技术含量低,但每次都有效。希望你能记住你最近的变化。

回答by steve

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.

对我来说,我在 OS X 中使用非 Apple SSD(不推荐)启用了 TRIM,并且显然导致了我的启动盘上的各种损坏。因此,损坏的提交在历史中很深。

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?

理论上,由于这是一个本地存储库,我觉得 Git 应该能够使用 origin 来恢复/修复自己。为什么这不可能?

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

无论如何,我偶然发现了这种将分支推送到另一个本地 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'

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 logdidn't end in:

所以我从一个空的存储库开始,然后将分支推送到它工作正常。因此,对于我git log没有以以下结尾的任何本地分支:

....
    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:

我只是检查一下然后做git push --force local_remote HEAD。我做的最后一件事是:

! cd ~/Dev/repo_copy
! git remote add origin [email protected]:sdhull/my_repo.git  # real remote

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

然后我进入git config -e并设置了我的主分支,然后重新启动并运行,没有丢失任何东西!

回答by Michael Mior

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

尝试备份存储库,然后运行git reset --hard HEAD@{1}以返回到以前的版本HEAD,看看是否有效。HEAD损坏的可能只是电流。

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

fsck如果你还没有在你的磁盘上运行,你也应该运行。)

回答by SanjiMika

The most simple solution for me: You should git clonein a new folder, then replace the clean new_folder/.gitto the old folder (the broken folder). It has worked well for me!

对我来说最简单的解决方案:您应该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/

回答by gaborous

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

另一种对我有用的替代方法是使用以下方法将 Git 头部和索引重置为以前的状态:

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

回答by ony

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 <[email protected]> 1379583764 +0300    commit: plan: timings

By resetting masterto prev commit da9c14d03e4849394087b61ff6272399937f7cceas told by @Nash Bridges:

通过重置masterda9c14d03e4849394087b61ff6272399937f7cce@Nash Bridges 所说的prev 提交:

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 masterfrom broken:

创建一个新的空存储库,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.

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

恢复那些正在进行的更改master

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

回答by MrJ

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

我按照从损坏的 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

It worked for me.

它对我有用。

回答by student

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

我遇到了同样的问题,并使用git-repair 执行了以下步骤

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

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

成功后,树被设置回上次工作提交。

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

然后我确实meld myrepo myrepo.bak将更改从损坏的存储库的工作树应用到固定存储库。