Git Troubleshooting - Solving Common Problems and Emergency Recovery

Git Troubleshooting

🟡 Intermediate 🔴 Advanced 🟣 Expert

Comprehensive guide to diagnosing and solving Git problems. From simple conflicts to complex repository corruption, learn to handle any Git emergency.

Diagnostic Tools

Repository Health Check

Comprehensive repository diagnosis
# Check repository integrity
git fsck --full --strict

# Verify object connectivity
git fsck --connectivity-only

# Check for dangling objects
git fsck --dangling

# Verify pack files
git verify-pack -v .git/objects/pack/*.idx
Healthy Repository Output:
Checking object directories: 100% (256/256), done.
Checking objects: 100% (1234/1234), done.
Problem Indicators:
error: sha1 mismatch for ./objects/ab/cd1234...
error: bad sha1 file: ./objects/ab/cd1234...
dangling commit abc123...
dangling blob def456...

Status and Information Commands

# Detailed status information
git status --porcelain --branch --ahead-behind

# Show current HEAD and recent history
git log --oneline --graph -10

# Check tracking branch relationships
git branch -vv

# Show reflog for recent activity
git reflog --date=relative -10

# Check configuration issues
git config --list --show-origin | grep -E "(user|remote|branch)"

Network and Remote Diagnostics

# Test remote connectivity
git ls-remote origin

# Verbose fetch to diagnose remote issues
git fetch --verbose --dry-run

# Check remote configuration
git remote -v
git remote show origin

# Test SSH connection (for SSH remotes)
ssh -T [email protected]

Common Problems and Solutions

❌ Problem: "fatal: not a git repository"

Diagnosis: You're not in a Git repository or .git directory is missing/corrupted.
Solutions:
# Check if you're in the right directory
pwd
ls -la

# Navigate to repository root
cd /path/to/your/repository

# If .git is missing, reinitialize (dangerous!)
git init
git remote add origin 

# Or clone again
git clone  new-directory

❌ Problem: "Your branch is ahead/behind"

Diagnosis: Local and remote branches are out of sync.
Solutions:
# Branch ahead - push your changes
git push origin main

# Branch behind - pull remote changes
git pull origin main

# Diverged branches - decide on strategy
git pull --rebase origin main  # rebase local commits
# OR
git pull --no-rebase origin main  # create merge commit

# Force push (dangerous - only if you're sure)
git push --force-with-lease origin main

❌ Problem: "fatal: refusing to merge unrelated histories"

Diagnosis: Trying to merge repositories with completely different histories.
Solutions:
# Allow unrelated histories (be careful!)
git pull origin main --allow-unrelated-histories

# Alternative: create new branch for merge
git checkout -b merge-unrelated
git pull origin main --allow-unrelated-histories
git checkout main
git merge merge-unrelated

❌ Problem: "error: failed to push some refs"

Diagnosis: Remote has commits you don't have locally.
Solutions:
# Fetch and check what's new
git fetch origin
git log HEAD..origin/main --oneline

# Pull before pushing
git pull origin main
git push origin main

# If conflicts occur during pull
git status  # see conflicted files
# resolve conflicts, then:
git add .
git commit
git push origin main

❌ Problem: "Permission denied (publickey)"

Diagnosis: SSH authentication failure.
Solutions:
# Check SSH key configuration
ssh-add -l

# Test SSH connection
ssh -T [email protected]

# Generate new SSH key if needed
ssh-keygen -t ed25519 -C "[email protected]"
ssh-add ~/.ssh/id_ed25519

# Add public key to GitHub/GitLab
cat ~/.ssh/id_ed25519.pub

# Alternative: use HTTPS instead
git remote set-url origin https://github.com/user/repo.git

❌ Problem: "detached HEAD state"

Diagnosis: HEAD points to specific commit, not a branch.
Solutions:
# Check current state
git status
git log --oneline -3

# Create branch from current position
git checkout -b fix-detached-head

# Or return to a branch
git checkout main

# If you made commits in detached HEAD
git branch temp-branch  # save commits
git checkout main
git merge temp-branch
git branch -d temp-branch

Advanced Merge Conflict Resolution

Understanding Conflict Markers

Conflict marker anatomy
function calculateTotal(items) {
<<<<<<< HEAD (Current Change)
    return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
=======
    let total = 0;
    for (const item of items) {
        total += item.cost * item.amount;
    }
    return total;
>>>>>>> feature/refactor-calculation (Incoming Change)
}
  • <<<<<<< HEAD - Start of your current changes
  • ======= - Separator between changes
  • >>>>>>> branch-name - End of incoming changes

Conflict Resolution Strategies

1. Manual Resolution

# Edit files to resolve conflicts
vim conflicted-file.js

# After resolving, mark as resolved
git add conflicted-file.js

# Continue merge
git commit

# Or abort if resolution isn't possible
git merge --abort

2. Use Merge Tools

# Configure merge tool
git config --global merge.tool vimdiff
# Options: vimdiff, meld, kdiff3, p4merge

# Launch merge tool
git mergetool

# Clean up backup files
git clean -f *.orig

3. Strategic Resolution

# Keep your version (ours)
git checkout --ours conflicted-file.js

# Keep their version (theirs)
git checkout --theirs conflicted-file.js

# Use specific merge strategy
git merge -X ours feature-branch
git merge -X theirs feature-branch

Complex Conflict Scenarios

Scenario: Multiple File Conflicts During Rebase

# Start interactive rebase
git rebase -i main

# Conflict occurs
# error: could not apply abc1234... Add new feature
# Resolve conflicts and run "git rebase --continue"

# Check which files have conflicts
git status

# Resolve each file
git add resolved-file1.js
git add resolved-file2.js

# Continue rebase
git rebase --continue

# If more conflicts occur, repeat the process
# To abort the entire rebase
git rebase --abort

Preventing Conflicts

  • Frequent small commits reduce conflict scope
  • Regular pulls keep branches synchronized
  • Communicate with team about overlapping work
  • Use feature flags instead of long-lived branches
  • Establish coding standards to reduce style conflicts

Advanced Recovery Techniques

Recovering Lost Commits

Find and recover lost commits
# Find lost commits in reflog
git reflog

# Search for specific content
git log --grep="search term" --all --source

# Find dangling commits
git fsck --dangling | grep commit

# Recover specific commit
git cherry-pick abc1234

# Create branch from lost commit
git branch recovered-work abc1234

Undoing Dangerous Operations

Recovery from Hard Reset

# Find the commit you reset from
git reflog

# The output shows recent HEAD changes:
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: Important work

# Recover the lost commits
git reset --hard def5678

# Or create a branch to save the work
git branch backup-important-work def5678

Recovery from Force Push

# If you have the commits locally in reflog
git reflog
git reset --hard abc1234  # the commit before force push

# If commits are completely lost, check team members
# They might have the commits in their local repositories

# Prevent future accidents
git config --global push.default simple
git config --global alias.pf 'push --force-with-lease'

File Recovery Techniques

# Recover deleted file from last commit
git checkout HEAD~1 -- deleted-file.txt

# Find when file was deleted
git log --oneline --follow -- deleted-file.txt

# Recover file at specific point
git show commit-hash:path/to/file > recovered-file.txt

# Find file in any commit
git log --all --full-history -- "*/filename.txt"

Repository Corruption and Repair

Diagnosing Corruption

Comprehensive corruption check
# Full integrity check
git fsck --full --strict

# Check specific object types
git fsck --tags --branches --remotes

# Verify all references
git for-each-ref --format='%(refname) %(objectname)' | while read ref obj; do
    git cat-file -e $obj || echo "Broken ref: $ref -> $obj"
done

Repair Strategies

Method 1: Automated Repair

# Garbage collection with aggressive cleanup
git gc --aggressive --prune=now

# Repack objects
git repack -ad

# Remove dangling objects
git reflog expire --expire=now --all
git gc --prune=now

Method 2: Manual Object Recovery

# Find missing objects
git fsck --missing

# Try to recover from other references
git show-ref --heads --tags

# Recover from backup or team member
git fetch origin
git reset --hard origin/main

Method 3: Repository Reconstruction

# Last resort: fresh clone
cd ..
git clone remote-url repository-backup
cd repository-backup

# Compare and recover any local-only work
# Use diff tools to compare directories
diff -r ../corrupted-repo ../repository-backup --exclude=.git
⚠️ Critical Warning: Always backup your repository before attempting repairs. Some repair operations are destructive and cannot be undone.

Performance Issues and Optimization

Diagnosing Slow Operations

Performance diagnostics
# Check repository size
du -sh .git/

# Analyze object storage
git count-objects -vH

# Find large files
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -nr | head -10 | awk '{print$1}')"

# Profile Git operations
GIT_TRACE=1 git status
GIT_TRACE_PERFORMANCE=1 git log --oneline -10

Optimization Techniques

Repository Cleanup

# Aggressive garbage collection
git gc --aggressive

# Remove unreachable objects
git prune --expire=now

# Repack for better compression
git repack -ad --depth=250 --window=250

Large File Management

# Remove large files from history
git filter-branch --tree-filter 'rm -f large-file.zip' HEAD
git push --force origin main

# Better: use BFG Repo-Cleaner
java -jar bfg.jar --delete-files large-file.zip .git
git reflog expire --expire=now --all && git gc --prune=now --aggressive

Configuration Tuning

# Optimize for performance
git config core.preloadindex true
git config core.fscache true
git config gc.auto 256

# Enable partial clone for large repos
git clone --filter=blob:none 

# Use shallow clones when appropriate
git clone --depth 1 

Emergency Procedures

🚨 Emergency Response Checklist

# Create full backup
cp -r .git .git.backup.$(date +%Y%m%d_%H%M%S)

# Or clone to safe location
git clone . ../emergency-backup
# Quick status check
git status
git log --oneline -5
git fsck --quick
# Work in separate branch
git checkout -b emergency-fix

# Or use separate worktree
git worktree add ../emergency-workspace

Inform team members about the issue and coordinate response.

Use the specific troubleshooting techniques from this guide.

# Test repository integrity
git fsck --full
git status
git log --graph --oneline -10

Document the issue and implement preventive measures.

Nuclear Option: Repository Rebuild

⚠️ LAST RESORT ONLY: Use only when all other recovery methods fail.
# Step 1: Save current work
cp -r . ../repo-backup-$(date +%Y%m%d_%H%M%S)

# Step 2: Fresh clone
cd ..
git clone remote-url repo-fresh
cd repo-fresh

# Step 3: Recover uncommitted work
# Copy files (not .git) from backup
rsync -av --exclude='.git' ../repo-backup-*/ ./

# Step 4: Review and commit recovered work
git status
git add .
git commit -m "Recover work after repository rebuild"

🛡️ Prevention is Better Than Cure

Regular Backups

  • Push frequently to remote repositories
  • Use multiple remotes for redundancy
  • Regular local backups of important repositories

Safe Practices

  • Never use --force without --force-with-lease
  • Test destructive commands on copies first
  • Use branches for experimental work

Monitoring

  • Regular repository health checks
  • Monitor repository size and performance
  • Keep Git updated to latest stable version