GitVerifying Repos (git fsck)

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

Bash
git fsck

Example output — healthy repo with some dangling objects

Text
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

Bash
git fsck --full

Example --full output

Text
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

Bash
git fsck --unreachable

Example --unreachable output

Text
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

Bash
# 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
Tip
The reflog is usually faster than fsck for recovering recent work. Try `git reflog` first — it shows a history of every position HEAD has been at, including before hard resets. Use `git fsck` when the reflog has already expired or when you need to find objects by type (blobs) rather than by commit.
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

Bash
# 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
Warning
If git fsck reports "corrupt object" or "missing" critical objects (commits, trees, blobs referenced in history), your repository has suffered actual data loss — usually from hardware failure, filesystem corruption, or interrupted writes. At this point, your best recovery option is restoring from a known-good backup or re-cloning from the remote. Attempting to repair a critically corrupt object store by hand is extremely risky and rarely successful. Always maintain off-site backups of important repositories.

Re-clone as a recovery option

Bash
# 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

Bash
# 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

Bash
cd /srv/git/myproject.git
git fsck --full 2>&1 | grep -v "^dangling" | grep -v "^notice"
Note
Filtering out "dangling" and "notice" lines in automated checks means your monitoring system only gets alerted when real problems (missing or corrupt objects) occur. Dangling objects are normal and will be cleaned up by the next gc run.