28

One of my cloned repositories is getting this from a git fsck

fatal: loose object 40bda4e3b79c3d7bf598df31d9e68470f97a3f79 (stored in .git/objects/40/bda4e3b79c3d7bf598df31d9e68470f97a3f79) is corrupt

I've got another copy of it that fsck's cleanly.

I've tried nuking the directory/subdirectories that contain the fatal one, and recloning it. The problem continues.

I really don't care about any particular file, I just want the repository to checkout cleanly. What do I do?

Note: the remote repository is hosted on github.

svick
  • 236,525
  • 50
  • 385
  • 514
fishtoprecords
  • 2,394
  • 7
  • 27
  • 38

7 Answers7

31

Easy answer: move the old repo away and reclone. If you have stuff in the old repo you want to preserve, there are ways of getting them, but first get a good repo.

Seth Robertson
  • 30,608
  • 7
  • 64
  • 57
  • I nuked the repository/directory structure and recloned. The problem persists. Is there another way to "move" the old repo away? – fishtoprecords Jul 22 '12 at 01:09
  • @fishtoprecords: `git fsck` returns failure, right? Then `cd ..; mv reponame reponame-fatal-loose-object; git clone URL reponame` – Seth Robertson Jul 22 '12 at 01:11
  • Thanks, I swear that I did that once before, but this time it worked fine. – fishtoprecords Jul 22 '12 at 01:11
  • then a cp -rf reponame-fatal-loose-object/* reponame/ ? – knotito Aug 03 '15 at 18:31
  • @knotito: Yesish. This will miss files in the "loose" directory starting with ., but they are somewhat rare and of course you *want* to miss .git (and . and ..). You should also carefully check and test what you copy over since clearly something bad happened in that directory. I believe a safeish command to copy all files would be: `find . -mindepth 1 -maxdepth 1 ! -name .git -print | while read f; do cp -rf "$f" ../zz; done` – Seth Robertson Aug 03 '15 at 22:27
  • 1
    Better for me on this answer. Doesn't need rocket science because when in doubt, just clone a new one and back-up the old git repo ones and replace it with the new one. – David Dimalanta Jan 22 '16 at 04:11
7

The idea is:

  1. first remove your current git records which reside in your .git under your current project (let's denote it by "project A").
  2. Make copy of your current project, we denote the duplicate as "project B".
  3. Now cd into project A and git clone and reset to the last commit.
  4. Copy all the files from project B and replace those in project A.
  5. Now cd into project A and use git status to see the status of project A. It should be just as if there was no corruption happened ever.

In short, make a copy to reserve your current working area, and merge it with a fresh clone by replacing files and then deal with your changes as normal.

Here's it in action:

  1. First I see I have a corruption (which is because I forced my virtual machine to shutdown inproperly yesterday :P):

    ✘ domicor@ubuntu  ~/dotfiles   master ●  git status error: object file .git/objects/cd/593f6db1d5050406e15b9c80d215fd48db39f4 is empty error: object file .git/objects/cd/593f6db1d5050406e15b9c80d215fd48db39f4 is empty fatal: loose object cd593f6db1d5050406e15b9c80d215fd48db39f4 (stored in .git/objects/cd/593f6db1d5050406e15b9c80d215fd48db39f4) is corrupt corrupted

  2. Make a copy of my dotfiles folder and now remove the .git folder.

    $ cd ~/dotfiles $ rm -rf .git

    dotfiles

  3. Then recreate a git repo.

    $ git init

  4. Add a remote.

    $ git remote add origin git@git.oschina.net:domicor/dotfiles.git

  5. Fetch from the remote.

    $ git fetch

    Here's a screen shot of the above commands:rm-clone-fetch

  6. Now reset the HEAD.

    $ git reset --hard origin/master

    This is the shot: reset

    Notice that right after I fetched from remote I issued a git status command to check out the status of my repo. You can see all the files are untracked. And the lst part of the command line prompt is orange from my git init command to git reset command indicating that when I initialized my repo, git detected files and after the reset, all files are restored to the state of the HEAD thus the green prompt.

  7. Set the upstream branch:

    $ git branch --set-upstream-to=origin/master master

  8. Now copy your files from the backup folder (for me it's dotfiles (copy)) manually or through the command line to replace files in the dotfiles folder. Check out the status and there should be changes just like my screen shot:

    final

  9. Now you can git diff your-filename to check out if your changes are applied properly and you can add files and commit from now on. \o/

To understand it furthur, the git VCS just records your changes. When the VCS is corrupted, your files are still safe. They are still there as you left them. So you backup your files and restore the git records from elsewhere and git can compare the restore copy with your current file status and have ideas about what has changed just as it did before the corruption. And cheers \o/

Hustlion
  • 2,203
  • 1
  • 19
  • 22
  • Thank you, your detailed answer was by far the most useful! I've used `"rsync -ria --progress /* /"` to copy my changes. – Christian Benke Nov 06 '16 at 18:26
  • 2
    btw - what kind of git-aware bash-prompt are you using here? edit: Found it, Agnoster for ZSH (https://github.com/agnoster/agnoster-zsh-theme) – Christian Benke Nov 06 '16 at 18:32
6

I faced this issue and this simple trick solved the issue.

Step 1

Suppose you are facing this issue in a folder named "my-project" with branch "my-new-feature", clone the repo to a new folder named "my-project-dummy" and checkout to "my-new-feature"

Step 2

Delete ".git" folder in "my-project" folder and copy ".git" folder from "my-project-dummy" folder to "my-project"

Tadaaa you are good to go now.

Rameez Rami
  • 5,322
  • 2
  • 29
  • 36
  • 2
    This worked like a charm. You don't need to move your repo files like other answers suggest. I even had uncommitted changes in the repo and didn't have to do anything else to get them back. – BoDeX Mar 30 '21 at 02:26
4

First, you can check the file system for errors: fsck -y

Then, check the git repository: git fsck

Rich
  • 5,603
  • 9
  • 39
  • 61
Volodymyr Chumak
  • 756
  • 6
  • 12
0

Do git checkout to the other branch, you will get list of changed files , just commit them and push into the branch. If you do this the problem will be solved, next time when you do some changes git status should work.

gmponos
  • 2,157
  • 4
  • 22
  • 33
0

you should recreate a repo:

  • delete .git folder
  • copy everything from working directory to backup directory
  • git init
  • git remote add origin https://github.com/USERNAME/REPONAME.git
  • git pull
  • git checkout -b backup
  • git add .
  • git commit -m "add backup"
  • git checkout master
  • you are back to go (master branch)
fico7489
  • 7,931
  • 7
  • 55
  • 89
-4

Simplest answer is "rm -rf .git ..." http://www.bazhukov.net/2015/02/git-corrupt-loose-object/

bo858585
  • 117
  • 2
  • 10
  • this link is russian. I don't think that any sane software guy will be able to use this. – user23573 Jul 20 '15 at 07:04
  • When you see corrupt message use these commands: 1. rm -rf .git 2. git init 3. git remote add origin repository_address 4. git fetch 5. git reset --hard origin/master – bo858585 Jul 20 '15 at 22:56
  • 5
    Please DON'T do that, or only do it if you know what you're getting into. The final `reset --hard` step will make you lose any un-committed changes in your repository. – Chaosed0 Jul 31 '15 at 14:49
  • More detailed explanation on this kind of fix is on http://stackoverflow.com/a/13918515 – Stéphane Gourichon Dec 23 '15 at 15:45