Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'd first check whether `git fsck` gives you more information.

There isn't a simple and fast way to find parent objects, but here is a slow hack:

    git_find_references() {
        if [ "$#" -ne 1 ] || [ "${1#-}" != "$1" ]; then
            echo "usage: git_find_references <HASH>" >&2; return 1
        fi
        local target="$1"
        git cat-file --batch-check --batch-all-objects --unordered |
            while read -r hash type size; do
                if [ "$type" != "blob" ] && git cat-file -p "$hash" | grep -F -q "$target"; then
                    printf "%s %s\n" "$hash" "$type"
                fi
            done
    }

    # example:
    git_find_references 1cae71a9d5b24991c0d632b45186ca8a250e5d52
This will output the hashes and types of the objects that refer to the target. (The command is similar to the one posted by @Denvercoder9, but is slightly more sophisticated.)

Note that this function will be very slow on large repositories. I can't think of a way to make it faster without writing actual code. (My only tip is that you can search for multiple targets at once by changing the grep command to `grep -E -q "$target"` and then using `git_find_references "HASH1|HASH2|HASH3"`.)

Once you find the referring objects, you can use `git cat-file -p <hash>` on them to see their content, and you can repeatedly invoke this function to walk up a directory tree until you get to the enclosing commit.

---

To actually fix the corruption, you have a couple of options:

- If the corruption is in a branch that you don't care about, just delete the branch.

- Find a good copy of the object, e.g. from another repository (you said the object did not appear, but I just want to point out that you should check using `git cat-file -p <hash>` rather than by looking in .git/objects/, because objects can also be stored in packs). Or you might be able to work out what the content was (if the corrupt object is a blob, aka file, you might be able to work out the content based on the previous and next versions of that file; `git hash-object <file>` will tell you if it's exactly right, but won't give you any hints if it's slightly wrong).

- Rewrite the history to remove/replace the corrupt object. You can use a tool such as `git-filter-repo` (docs: https://htmlpreview.github.io/?https://github.com/newren/git..., in particular see --strip-blobs-with-ids). You can also use `git replace` to temporarily replace the corrupt object with a placeholder; it won't fix the commit history, but it might be useful if the corruption causes commands to fail.



Edit: To allow the corrupted object to be pruned, you should also run `git reflog expire --all --stale-fix`.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: