This error indicates Git repository corruption where a tree object references another tree or blob that no longer exists. Recovery involves fetching missing objects from remotes, restoring from backups, or reconstructing the missing objects.
When you run `git fsck` to verify your repository's integrity, Git traverses all objects (commits, trees, and blobs) and checks that every referenced object exists. A "broken link from tree" error means a tree object (which represents a directory) points to another object that is missing from your repository. Tree objects in Git store references to blobs (files) and other trees (subdirectories). Each entry contains a mode (file permissions), a filename, and a SHA-1 hash pointing to the referenced object. When Git cannot find the object matching that hash, it reports a broken link. This is a serious error because it means your repository's object database is incomplete. The missing tree could represent an entire directory structure, and any commits that depend on this tree will be partially or fully unrecoverable without intervention.
Before attempting any repairs, make a complete backup of your repository in its current state:
# Create a tarball backup
tar -czvf repo-backup-$(date +%Y%m%d).tar.gz /path/to/your/repo
# Or use rsync for a copy
rsync -av /path/to/your/repo/ /path/to/backup/repo-copy/This ensures you can recover if the repair process makes things worse.
Get detailed information about what's broken using git fsck with the --name-objects flag (Git 2.10+):
git fsck --full --name-objectsThis will show you exactly which refs lead to the broken objects:
broken link from tree b5eb6ff... (refs/heads/main~37:src/) to tree ec5cf80...
missing tree ec5cf80...The output tells you:
- Which tree contains the broken reference
- How to reach it (e.g., through refs/heads/main)
- The hash of the missing object
If the repository has a remote origin, try fetching all objects fresh:
# Fetch all branches and tags from all remotes
git fetch --all
# Git 2.36+: Force re-fetch all objects like a fresh clone
git fetch --refetchIf the remote has the missing objects, this may resolve the issue. Run git fsck again to verify.
If you have a backup or another clone of the repository:
# Copy all objects from the backup into your corrupted repo
cp -r /path/to/backup/.git/objects/* /path/to/corrupted/.git/objects/
# Alternatively, unpack objects from a fresh clone's pack files
cd /path/to/corrupted/
git unpack-objects < /path/to/fresh-clone/.git/objects/pack/pack-*.packAfter copying, run git fsck to verify the objects are restored.
If you can find a working reference to the parent tree, list its contents:
# Find what the parent tree should contain
git ls-tree <parent-tree-sha>This shows you the expected contents, which can help you understand what was lost and potentially reconstruct it.
The git-repair tool can automatically attempt to recover corrupted repositories:
# Install git-repair (Ubuntu/Debian)
sudo apt install git-repair
# Or on macOS with Homebrew
brew install git-repair
# Run the repair tool
cd /path/to/corrupted-repo
git-repairgit-repair will:
1. Delete corrupt objects
2. Retrieve missing objects from remotes
3. Optionally reset branches if recovery isn't possible
After running, use git fsck to verify the repair was successful.
For simple cases where you know the tree's contents, you can recreate it:
# Example: Recreating a tree with a single .gitkeep file
echo -e "100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\t.gitkeep" | git mktreeThis outputs the new tree's SHA. If it matches the missing tree's expected SHA, the object is restored.
Note: This only works if you know exactly what the tree should contain and all referenced blobs already exist.
If all else fails, create a fresh clone and preserve your working directory:
# Save your working directory files
cp -r /path/to/corrupted-repo /path/to/working-files-backup
rm -rf /path/to/working-files-backup/.git
# Fresh clone
git clone <remote-url> /path/to/fresh-repo
# Copy your working files into the fresh clone
cp -r /path/to/working-files-backup/* /path/to/fresh-repo/
# Check status and commit any changes
cd /path/to/fresh-repo
git status
git diffThis approach loses any unpushed commits and stashes, but preserves your current working directory changes.
### Understanding Git Tree Objects
A tree object in Git represents a directory. Its internal format is:
tree <size>\0
<mode> <filename>\0<20-byte-sha>
<mode> <filename>\0<20-byte-sha>
...Each entry points to either a blob (file) or another tree (subdirectory). The SHA-1 hash is stored as raw bytes, not hex. When any referenced object is missing, the tree is considered broken.
### Prevention Strategies
1. Avoid cloud sync folders: Never store Git repositories in Dropbox, OneDrive, or Google Drive folders. File conflicts corrupt the object database.
2. Use reliable storage: Prefer SSDs over HDDs. Monitor disk health with SMART tools.
3. Regular backups: Use git bundle or mirror clones:
git bundle create backup.bundle --all
# Or maintain a mirror
git clone --mirror <repo-url> repo-mirror.git4. Don't interrupt Git operations: Let clone, fetch, and gc complete naturally.
### Examining Pack Files
Sometimes missing objects are actually in pack files but the index is corrupt:
# List all pack files
ls .git/objects/pack/
# Verify pack integrity
git verify-pack -v .git/objects/pack/pack-*.idx
# Unpack all objects to loose format
mv .git/objects/pack/pack-*.pack /tmp/
git unpack-objects < /tmp/pack-*.pack### When Running git fsck
Common useful flags:
- --full: Check all objects, not just reachable ones
- --name-objects: Show how broken objects are reachable (Git 2.10+)
- --connectivity-only: Faster check, only verifies references exist
- --unreachable: Also report unreachable objects
### Partial History Recovery
If you only need recent history and can afford to lose old commits:
# Create a shallow clone with limited history
git clone --depth 100 <remote-url> recovered-repoThis gives you the last 100 commits without needing older objects.
fatal: bad object in rev-list input
Git rev-list encounters bad or invalid object
fatal: Out of memory, malloc failed during pack operation
Out of memory during Git pack operation
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git