Getting rid of '... does not point to a valid object' for an old git branch

Solution 1:

This will clean out any missing refs:

git for-each-ref --format="%(refname)" | while read ref; do
    git show-ref --quiet --verify $ref 2>/dev/null || git update-ref -d $ref
done

Solution 2:

Check .git/refs/remotes/origin. They are there and the upstream no longer has them. To clean out the remotes that no longer exist run

git remote prune origin

You could also see what it would to by adding --dry-run before actually doing it.

Solution 3:

I run into this error on a regular basis. git remote prune origin does not work for me.

[ Update. AFAIU, I'm running into this problem because of using git alternate. Say I've got repo A, registered as alternate for repo B. When I create a new branch br in repo A, and fetch repo A as remote in repo B, git will create a remote ref .git/refs/remotes/A/br for the new branch. When I delete the branch in repo A, and after the corresponding object is garbage-collected, I get the 'error: refs/remotes/A/br does not point to a valid object!' ]

I've written this script (updated to deal with packed refs) to remove the dangling refs (using the info in Validate if commit exists).

#!/bin/sh

set -e

if [ $# -eq 0 ]; then
    dir="."
else
    dir="$1"
fi

if [ ! -d "$dir" ]; then
    echo "not a dir: $dir"
    exit 1
fi

if [ ! -d "$dir/.git" ]; then
    echo "not a git repo: $dir"
    exit 1
fi

cd "$dir"

files=$(find .git/refs -type f)

for f in $files; do
    id=$(cat "$f")
    if ! git rev-parse --quiet "$id" \
    >/dev/null 2>&1; then
    continue
    fi
    if ! git rev-parse --quiet --verify "$id^{commit}" \
    >/dev/null 2>&1; then
    echo "Removing ref $f with missing commit $id"
    rm "$f"
    fi
done

if [ ! -f .git/packed-refs ]; then
    exit 0
fi

packfiles=$(cat .git/packed-refs \
    | grep -v '#' \
    | awk '{print $2}')

for f in $packfiles; do
    if ! git rev-parse --quiet --verify "$f" \
    >/dev/null 2>&1; then
    continue
    fi
    id=$(git rev-parse "$f")
    if ! git rev-parse --quiet --verify "$id" \
    >/dev/null 2>&1; then
    continue
    fi
    if ! git rev-parse --quiet --verify "$id^{commit}" \
    >/dev/null 2>&1; then
    echo "Removing packed ref $f with missing commit $id"
    git update-ref -d $f
    fi
done

Solution 4:

Your local clone is probably fine, the problem is that the t_1140 branch objects are missing from your GitHub repository.

I had this problem too and GitHub support fixed it, I think by deleting refs/heads/t_1140 on their end.

Update: I got the error again with another branch and I was able to fix it by running this command:

git push origin :refs/heads/t_ispn982_master

You should get a warning message like this:

remote: warning: Allowing deletion of corrupt ref.

but the corrupted branch will be deleted

Solution 5:

You say that you have:

also checked .git/refs/heads and there's no reference to t_1140

... which is very surprising. I can only see how this error would occur if the file .git/refs/heads/t_1140 exists. Is it possible you were mistaken about this?

Correction: Charles Bailey points out below that the refs might be packed, in which case there is no corresponding file in .git/refs/heads