git fsck: Repository Integrity Check
git fsck (file system check) is Git's built-in diagnostic tool for
verifying the integrity of your repository's object store. It checks
two things: that every object's SHA-1 hash matches its actual
content (detecting bit-rot or disk corruption), and that the object
graph is fully connected (every tree and blob referenced by a commit
actually exists). Running fsck regularly is a good practice for
long-lived repositories, especially on self-hosted servers.
Basic Usage
Basic integrity check
git fsck
Example output — healthy repo with some dangling objects
Checking object directories: 100% (256/256), done. Checking connectivity: done. dangling blob 4b825dc642cb6eb9a060e54bf8d69288fbee4904 dangling blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 dangling commit e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 notice: HEAD points to an unborn branch (main)
A clean output with only "dangling" notices is normal — dangling objects are unreachable but not corrupt. They are typically leftovers from git stash, git rebase, git reset, or git commit --amend operations. True problems appear as "missing" or "corrupt" entries.
Checking Packed Objects Too
By default, git fsck only checks loose objects. Use --full to also verify objects inside pack files. This is slower but more thorough and is the recommended flag for a complete integrity audit.
Full check including pack files
git fsck --full
Example --full output
Checking object directories: 100% (256/256), done. Checking objects in alternate object store: done. Checking pack files: done. Checking connectivity: done. dangling blob 4b825dc642cb6eb9a060e54bf8d69288fbee4904
Showing All Unreachable Objects
The --unreachable flag lists every object that cannot be reached from any branch, tag, or HEAD. This is useful when you want to find recoverable work — for example, commits that existed before a hard reset.
List unreachable objects
git fsck --unreachable
Example --unreachable output
unreachable commit 3a5f2c1b8d9e4a7f6b2c8d3e1f5a9b7c4d6e8f0a unreachable tree 7e1b9f3c5d2a4b6e8f0a1c3d5e7f9b2c4d6e8a0b unreachable blob 1c3d5e7f9b2c4d6e8a0b1c3d5e7f9b2c4d6e8a0b dangling blob 4b825dc642cb6eb9a060e54bf8d69288fbee4904
Reading fsck Output
Output Term | Meaning | Severity |
|---|---|---|
dangling blob | A file object with no parent tree — leftover from stash, reset, etc. | Normal |
dangling commit | A commit reachable from nothing — leftover from reset or branch delete | Normal |
dangling tree | A directory snapshot referenced by nothing currently reachable | Normal |
unreachable commit | Same as dangling commit but shown with --unreachable flag | Normal |
missing blob | A file object referenced by a tree but not present in the object store | Critical |
missing tree | A directory object referenced by a commit but absent from storage | Critical |
missing commit | A parent commit referenced in history but absent from storage | Critical |
corrupt object | An object whose content does not match its SHA hash — actual disk corruption | Critical |
bad object | An object that cannot be parsed (wrong format) | Critical |
Recovering a Dangling Commit
If you accidentally ran git reset --hard or deleted a branch with unmerged commits, those commits become dangling objects. You can inspect and recover them before garbage collection removes them (remember: gc only prunes objects older than 2 weeks by default).
Find and recover a dangling commit
# Step 1: Find dangling commits git fsck --unreachable | grep commit # Step 2: Inspect the commit to identify it git show 3a5f2c1b8d9e4a7f6b2c8d3e1f5a9b7c4d6e8f0a # Step 3: Create a branch pointing to it to make it reachable git branch recovered-work 3a5f2c1b8d9e4a7f6b2c8d3e1f5a9b7c4d6e8f0a # Step 4: Inspect the recovered branch git log recovered-work --oneline
Recovering a Dangling Blob (File)
If you added a file with git add but then ran git reset HEAD or git checkout -- without committing, the file content exists as a dangling blob. You can retrieve it:
Recovering a dangling blob
# List dangling blobs git fsck | grep "dangling blob" # Show the content of a blob git show 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Redirect to a file if you want to recover it git show 4b825dc642cb6eb9a060e54bf8d69288fbee4904 > recovered-file.txt
What to Do With Real Corruption
Re-clone as a recovery option
# If you have a remote with complete history git clone --mirror https://github.com/user/repo.git repo-recovered # Or clone into a new local directory and re-apply any local commits git clone origin-url fresh-clone cd fresh-clone # Cherry-pick commits from the corrupt repo if you can still read them
Using fsck as a Health Check
For self-hosted Git servers or high-value repositories, running git fsck --full on a regular schedule (weekly or monthly) is a good operational practice. It provides early warning of filesystem issues before they become catastrophic.
Weekly cron job for repository health check
# Add to crontab with: crontab -e # Run every Sunday at 2am, log results 0 2 * * 0 cd /path/to/repo && git fsck --full >> /var/log/git-fsck.log 2>&1
Check a bare repository on a Git server
cd /srv/git/myproject.git git fsck --full 2>&1 | grep -v "^dangling" | grep -v "^notice"