Sometimes a commit will be viewable on GitHub, but will not exist in your local clone of the repository.
When you use
git show to view a specific commit on the command line, you may get a fatal error.
For example, you may receive a
bad object error locally:
git show 1095ff3d0153115e75b7bca2c09e5136845b5592 fatal: bad object 1095ff3d0153115e75b7bca2c09e5136845b5592
However, when you visit the commit online, you'll be able to see it without and problems:
There are several possible explanations:
- The local repository is out of date.
- The branch that contains the commit was deleted, so the commit is no longer referenced.
- Someone force pushed over the commit.
The local repository is out of date
Your local repository may not have the commit yet. To get information from your remote repository to your local clone, use
git fetch remote
This safely copies information from the remote repository to your local clone without making any changes to the files you have checked out.
You can use
git fetch upstream to get information from a repository you've forked, or
git fetch origin to get information from a repository you've only cloned.
The branch that contained the commit was deleted
If a collaborator on the repository has deleted the branch containing the commit or has force pushed over the branch, the missing commit may have been orphaned (i.e. it cannot be reached from any reference) and therefore will not be fetched into your local clone.
Fortunately, if any collaborator has a local clone of the repository with the missing commit, they can push it back to GitHub. They need to make sure the commit is referenced by a local branch and then push it as a new branch to GitHub.
Let's say that the person still has a local branch (call it
B) that contains
the commit. This might be tracking the branch that was force pushed or deleted
and they simply haven't updated yet. To preserve the commit, they can push that
local branch to a new branch (call it
recover-B) on GitHub. For this example,
let's assume they have a remote named
upstream via which they have push access
The other person runs:
git branch recover-B B # Create a new local branch referencing the commit git push upstream B:recover-B # Push local B to new upstream branch, creating new reference to commit
Now, you can run:
git fetch upstream recover-B # Fetch commit into your local repository.
Avoid force pushes
Avoid force pushing to a repository unless absolutely necessary. This is especially true if more than one person can push to the repository.