Overview
In Git, the index (also called the staging area) lives at .git/index and tracks what will be committed. If it becomes unreadable, commands fail with:
- fatal: index file corrupt
This guide shows how to safely rebuild the index, verify repository integrity, and handle edge cases common in DevOps workflows.
Quickstart
Safe, minimal sequence to recover:
- Identify the index path:
- bash: git rev-parse --git-path index
- Back up the current index file (even if corrupt):
- bash: cp "$(git rev-parse --git-path index)" "$(git rev-parse --git-path index)".bak 2>/dev/null || true
- Remove the corrupt index:
- bash: rm -f "$(git rev-parse --git-path index)"
- PowerShell: Remove-Item -Force (git rev-parse --git-path index)
- Rebuild the index from HEAD:
- git reset --mixed
- Verify and continue:
- git status
- git fsck --full
If uncommitted changes exist in your working tree, they will remain. Staged changes are lost but you can often re-stage them, or partially salvage from the backup (see below).
Minimal working example (Unix)
This demo creates a repo, corrupts the index, triggers the error, then fixes it.
set -euo pipefail
repo="$(mktemp -d)"
cd "$repo"
echo "Creating test repo"
git init -q
echo hello > file.txt
git add file.txt
git commit -q -m "init"
# Simulate index corruption (writes random bytes into the index)
dd if=/dev/urandom of=.git/index bs=1024 count=1 conv=notrunc status=none || true
# Observe failure
echo "Expect a failure:" || true
git status || true
# Fix
cp .git/index .git/index.bak 2>/dev/null || true
rm -f .git/index
git reset --mixed -q
echo "Recovered:" || true
git status
Step-by-step recovery
Confirm the problem
- Run any Git command that reads the index, e.g., git status. If you see “fatal: index file corrupt,” proceed.
Back up the index
- Even if corrupt, keep a copy for potential salvage.
- bash: cp "$(git rev-parse --git-path index)" "$(git rev-parse --git-path index)".bak 2>/dev/null || true
Remove the corrupt index
- bash: rm -f "$(git rev-parse --git-path index)"
- PowerShell: Remove-Item -Force (git rev-parse --git-path index)
Rebuild the index
- git reset --mixed
- This repopulates the index from HEAD without touching your working tree.
Verify repository health
- git status
- git fsck --full
- If fsck reports object issues, run git gc and/or investigate storage problems (disk, antivirus scanners, network filesystems).
Re-stage your changes
- git add -A
- If you had partial staging, use git add -p to re-create it.
Salvaging staged changes (optional)
If you backed up the corrupt index, you might extract the list of staged paths to help re-stage quickly:
- List entries that were staged (may still work even if Git can read the backup partially):
# Use the backup index to list staged entries
GIT_INDEX_FILE="$(git rev-parse --git-path index)".bak git ls-files -s > staged-entries.txt || true
cut -f2 -d$'\t' staged-entries.txt | awk '{print $2}' | sort -u > staged-paths.txt || true
# Re-stage paths (best-effort)
xargs -r git add < staged-paths.txt || true
This won’t perfectly restore partial hunks, but it quickly re-stages the same files.
Edge cases and special setups
- Worktrees
- The index path differs in linked worktrees. Always resolve via: git rev-parse --git-path index
- In-progress merges/rebases
- After rebuilding the index, Git might still track MERGE_HEAD or rebase state. Continue as normal (git merge --continue, git rebase --continue) or abort (git merge --abort, git rebase --abort) based on your workflow.
- Sparse checkout
- Reapply sparse patterns if needed: git sparse-checkout reapply
- Submodules
- Repair the superproject index first, then update submodules: git submodule sync --recursive && git submodule update --init --recursive
- Windows antivirus or file locking
- Exclude the repository directory if your antivirus interferes with .git/index. Ensure no other tools lock the file.
- Network or case-insensitive filesystems
- Prefer local, case-sensitive filesystems for critical repos. Corruption can stem from flaky network mounts.
Pitfalls to avoid
- Using git reset --hard blindly
- This discards local modifications. Prefer git reset --mixed for index rebuilds.
- Deleting the .git directory
- Never remove .git to fix index corruption; you’ll lose the repo metadata.
- Skipping a backup
- A quick copy of the index may enable salvage of what was staged.
- Ignoring recurring corruption
- If this happens repeatedly, look for underlying causes: disk errors, abrupt power loss, aggressive tools modifying .git, or misbehaving NFS/SMB mounts.
Performance notes
- Reset cost on large repos
- git reset --mixed or git read-tree -mu HEAD rebuilds the index by scanning the tree. On very large repos this can take time; run from fast local storage.
- Speeding up subsequent commands
- Run git gc after recovery to optimize objects and reduce metadata churn.
- Partial staging on large repos
- Use git add -p to avoid re-hashing the entire working tree when you only need selected changes.
- Windows performance
- Enable file system caching (core.fscache=true) and avoid real-time scanning of .git to reduce index churn.
Commands reference
# Resolve index path
git rev-parse --git-path index
# Backup and remove
cp "$(git rev-parse --git-path index)" "$(git rev-parse --git-path index)".bak 2>/dev/null || true
rm -f "$(git rev-parse --git-path index)"
# Rebuild index
git reset --mixed
# Verify
git status
git fsck --full
PowerShell equivalents:
$idx = git rev-parse --git-path index
Copy-Item $idx "$idx.bak" -ErrorAction SilentlyContinue
Remove-Item -Force $idx
git reset --mixed
git status
git fsck --full
FAQ
Will I lose my uncommitted changes?
- No. Removing the index does not delete working tree files. You will lose what was staged, but you can re-stage.
Is git reset --mixed safe?
- Yes. It rebuilds the index from HEAD and leaves your working files untouched.
What if git reset still fails?
- Run git fsck --full. If objects are missing, recover via git reflog or another remote/clone.
Can I prevent this in CI/CD?
- Use local ephemeral workspaces, avoid sharing .git across jobs, and run git clean -ffd && git reset --hard HEAD between jobs to start clean.
Why did it happen?
- Common causes include abrupt termination, disk issues, AV tools, or buggy network filesystems. Once recovered, address the root cause to prevent recurrence.