Skip to content

prune-packed Git Command Guide

The git prune-packed command removes extra loose objects from the object database that are already efficiently stored in pack files. This optimizes repository storage by eliminating redundant loose object copies.

Terminal window
git prune-packed [-n | --dry-run] [-q | --quiet]
OptionDescription
-n, --dry-runShow what would be removed without removing
-q, --quietSuppress output messages
Loose Objects:
├── Individual files in .git/objects/??/
├── One file per object (SHA-1 named)
├── Uncompressed or zlib compressed
├── Fast for single object access
└── Inefficient for bulk storage
Packed Objects:
├── Stored in .pack files with .idx indexes
├── Delta compression between related objects
├── Optimized for bulk access and transfer
├── Slower for single object access
└── Efficient for storage and network transfer
Object Analysis:
1. Scan all pack files for contained objects
2. Identify loose objects with same SHA-1
3. Mark redundant loose objects for removal
4. Remove loose copies, keep packed versions
Benefits:
├── Reduced storage usage
├── Faster repository operations
├── Consistent object access
└── Optimized for Git's usage patterns
Terminal window
# Remove redundant loose objects
git prune-packed
# Dry run to see what would be removed
git prune-packed --dry-run
# Quiet operation
git prune-packed --quiet
# Combined with other maintenance
git prune-packed && git prune --expire=2.weeks.ago
Terminal window
# Analyze before and after pruning
echo "Before prune-packed:"
git count-objects -v
git prune-packed --dry-run
echo "After prune-packed:"
git count-objects -v
Terminal window
# Complete repository cleanup
git gc --auto # Auto maintenance
git prune-packed # Remove packed duplicates
git prune --expire=2.weeks.ago # Remove old unreachable
#!/bin/bash
# Comprehensive repository storage optimization
optimize_storage() {
echo "Analyzing repository storage..."
# Pre-optimization stats
echo "=== Before Optimization ==="
git count-objects -v
echo "Loose objects: $(find .git/objects -type f -name '[0-9a-f]*' | wc -l)"
echo "Pack files: $(ls .git/objects/pack/*.pack 2>/dev/null | wc -l)"
echo "Total size: $(du -sh .git/ | cut -f1)"
# Optimization steps
echo "=== Optimization Steps ==="
# Repack repository
echo "Repacking repository..."
git repack -a -d --depth=250 --window=250
# Prune packed objects
echo "Removing redundant loose objects..."
git prune-packed
# Clean up old objects
echo "Removing unreachable objects..."
git prune --expire=2.weeks.ago
# Update auxiliary files
echo "Updating auxiliary files..."
git update-server-info
# Post-optimization stats
echo "=== After Optimization ==="
git count-objects -v
echo "Loose objects: $(find .git/objects -type f -name '[0-9a-f]*' | wc -l)"
echo "Pack files: $(ls .git/objects/pack/*.pack 2>/dev/null | wc -l)"
echo "Total size: $(du -sh .git/ | cut -f1)"
echo "Storage optimization complete"
}
optimize_storage
Terminal window
# Incremental repository maintenance
incremental_maintenance() {
echo "Performing incremental maintenance..."
# Check if maintenance is needed
loose_count=$(find .git/objects -type f -name '[0-9a-f]*' | wc -l)
pack_count=$(ls .git/objects/pack/*.pack 2>/dev/null | wc -l)
if [ "$loose_count" -gt 1000 ] || [ "$pack_count" -gt 5 ]; then
echo "Maintenance needed: $loose_count loose objects, $pack_count packs"
# Perform maintenance
git prune-packed --quiet
git repack -a -d -q
echo "Incremental maintenance completed"
else
echo "Repository is well-maintained"
fi
}
incremental_maintenance
Terminal window
# Maintenance with backup protection
safe_maintenance() {
echo "Safe repository maintenance with backup..."
# Create backup snapshot
backup_ref="maintenance-backup-$(date +%Y%m%d-%H%M%S)"
git update-ref "refs/backup/$backup_ref" HEAD
echo "Backup created: $backup_ref"
# Perform maintenance
if git prune-packed --quiet && \
git repack -a -d -q && \
git prune --expire=1.week.ago --quiet; then
# Verify repository integrity
if git fsck --connectivity-only --quiet; then
echo "✓ Maintenance successful, repository healthy"
# Clean up old backups (keep last 5)
git for-each-ref --format="%(refname)" refs/backup/ | \
head -n -5 | xargs -r git update-ref -d
return 0
else
echo "✗ Repository corruption detected after maintenance"
# Restore from backup
git reset --hard "refs/backup/$backup_ref"
return 1
fi
else
echo "✗ Maintenance failed"
return 1
fi
}
safe_maintenance
Terminal window
# Configure automatic maintenance
git config gc.auto 6700 # Objects threshold for auto-gc
git config gc.autoPackLimit 50 # Pack limit for auto-gc
git config gc.pruneExpire 2.weeks.ago # Prune expiration
# Configure maintenance schedule
git config maintenance.gc.enabled true
git config maintenance.commit-graph.enabled true
git config maintenance.loose-objects.enabled true
git config maintenance.incremental-repack.enabled true
Terminal window
# Optimize for large repositories
git config core.deltaBaseCacheLimit 512m # Delta cache size
git config core.looseCompression 1 # Loose object compression
git config pack.threads 0 # Auto-detect CPU threads
# Configure pack window for better deltas
git config pack.window 10
git config pack.depth 50
git config pack.windowMemory "512m"
Terminal window
# Monitor repository health
monitor_repo_health() {
echo "Repository Health Report"
# Object counts
git count-objects -v
# Check for excessive loose objects
loose_count=$(find .git/objects -type f -name '[0-9a-f]*' | wc -l)
if [ "$loose_count" -gt 10000 ]; then
echo "WARNING: High loose object count ($loose_count)"
echo "Consider running: git prune-packed"
fi
# Check pack file count
pack_count=$(ls .git/objects/pack/*.pack 2>/dev/null | wc -l)
if [ "$pack_count" -gt 20 ]; then
echo "WARNING: Many pack files ($pack_count)"
echo "Consider running: git repack -a -d"
fi
# Repository size
repo_size=$(du -sh .git/ | cut -f1)
echo "Repository size: $repo_size"
}
monitor_repo_health
#!/bin/bash
# CI/CD pipeline with repository optimization
ci_optimization() {
echo "CI/CD repository optimization..."
# Shallow clone optimization
if [ -n "$CI" ]; then
# For CI, focus on cleaning without full repack
git prune-packed --quiet
git prune --expire=1.day.ago --quiet
else
# Full optimization for maintenance jobs
git gc --aggressive --quiet
git prune-packed --quiet
fi
# Update commit graph for performance
git commit-graph write --reachable --changed-paths
echo "CI optimization complete"
}
ci_optimization
#!/bin/bash
# Automated repository maintenance
automated_maintenance() {
local log_file="maintenance-$(date +%Y%m%d).log"
echo "Starting automated maintenance at $(date)" | tee "$log_file"
# Pre-maintenance stats
echo "Pre-maintenance:" | tee -a "$log_file"
git count-objects -v | tee -a "$log_file"
# Maintenance steps
echo "Running prune-packed..." | tee -a "$log_file"
git prune-packed --quiet
echo "Running repack..." | tee -a "$log_file"
git repack -a -d -q
echo "Running prune..." | tee -a "$log_file"
git prune --expire=2.weeks.ago --quiet
# Post-maintenance stats
echo "Post-maintenance:" | tee -a "$log_file"
git count-objects -v | tee -a "$log_file"
# Integrity check
if git fsck --connectivity-only --quiet; then
echo "✓ Maintenance completed successfully" | tee -a "$log_file"
return 0
else
echo "✗ Maintenance failed - repository corruption detected" | tee -a "$log_file"
return 1
fi
}
# Run maintenance
automated_maintenance
Terminal window
# Clean up after repository migration
post_migration_cleanup() {
local source_repo="$1"
echo "Post-migration cleanup for repository from $source_repo"
# Remove redundant loose objects
git prune-packed --quiet
# Consolidate pack files
git repack -a -d -f
# Clean up migration artifacts
find . -name "*.orig" -delete 2>/dev/null || true
# Final optimization
git gc --aggressive --prune=now
echo "Post-migration cleanup complete"
echo "Repository size: $(du -sh .git/ | cut -f1)"
}
post_migration_cleanup "/path/to/source/repo"
Terminal window
# Debug what prune-packed would remove
git prune-packed --dry-run | head -20
# Check why objects are considered redundant
for obj in $(git prune-packed --dry-run | head -5); do
echo "Object: $obj"
git cat-file -t "$obj"
# Check if object exists in packs
git verify-pack -v .git/objects/pack/*.idx | grep "$obj" | head -1
done
Terminal window
# Diagnose and repair repository issues
repair_after_prune() {
echo "Diagnosing repository after prune-packed..."
# Run fsck to check for issues
git fsck --full --strict 2>&1 | tee fsck-report.txt
# Check for missing objects
if grep -q "missing" fsck-report.txt; then
echo "Missing objects detected - attempting repair"
# Try to recover from reflog
git reflog | head -10
# Restore from backup if available
ls -la .git/refs/heads/ | grep backup
echo "Manual intervention may be required"
else
echo "Repository appears healthy"
fi
}
repair_after_prune

Performance Issues with Large Repositories:

Section titled “Performance Issues with Large Repositories:”
Terminal window
# Handle large repository pruning efficiently
large_repo_prune() {
echo "Optimizing large repository pruning..."
# Check system resources
free -h
df -h .
# Use incremental approach
echo "Loose objects before: $(find .git/objects -type f -name '[0-9a-f]*' | wc -l)"
# Prune in batches if needed
git prune-packed --quiet
echo "Loose objects after: $(find .git/objects -type f -name '[0-9a-f]*' | wc -l)"
# Follow up with repack
git repack -a -d --depth=250 --window=250 --threads=0
echo "Large repository optimization complete"
}
large_repo_prune
Terminal window
# Handle permission issues during pruning
fix_prune_permissions() {
echo "Fixing permission issues for prune-packed..."
# Check permissions
ls -la .git/objects/
# Fix ownership
sudo chown -R $(whoami) .git/
# Fix permissions
find .git -type d -exec chmod 755 {} \;
find .git -type f -exec chmod 644 {} \;
# Retry operation
git prune-packed --dry-run
echo "Permission issues resolved"
}
fix_prune_permissions
#!/bin/bash
# Enterprise-scale repository maintenance
enterprise_repo_maintenance() {
local repo_path="$1"
local retention_days="${2:-90}"
cd "$repo_path"
echo "Enterprise maintenance for $(basename "$repo_path")"
# Pre-maintenance analysis
echo "Pre-maintenance analysis:"
git count-objects -v
echo "Repository size: $(du -sh .git/ | cut -f1)"
# Create maintenance checkpoint
checkpoint="maintenance-$(date +%Y%m%d-%H%M%S)"
git tag "$checkpoint" -m "Maintenance checkpoint"
# Safe maintenance procedure
echo "Step 1: Prune packed objects..."
git prune-packed --quiet
echo "Step 2: Repack repository..."
git repack -a -d --depth=250 --window=250 --threads=0
echo "Step 3: Clean old objects..."
git prune --expire="${retention_days} days ago" --quiet
echo "Step 4: Update auxiliary files..."
git update-server-info
git commit-graph write --reachable
# Post-maintenance analysis
echo "Post-maintenance analysis:"
git count-objects -v
echo "Repository size: $(du -sh .git/ | cut -f1)"
# Integrity verification
if git fsck --connectivity-only --quiet; then
echo "✓ Enterprise maintenance completed successfully"
# Clean up old checkpoints (keep last 3)
git tag | grep "^maintenance-" | head -n -3 | xargs git tag -d
return 0
else
echo "✗ Maintenance failed - repository integrity check failed"
echo "Checkpoint preserved: $checkpoint"
return 1
fi
}
enterprise_repo_maintenance "/repos/critical-project" 180
Terminal window
# Team workflow with regular maintenance
team_maintenance_workflow() {
echo "Team maintenance workflow..."
# Check if maintenance is needed
loose_objects=$(find .git/objects -type f -name '[0-9a-f]*' | wc -l)
pack_files=$(ls .git/objects/pack/*.pack 2>/dev/null | wc -l)
if [ "$loose_objects" -gt 1000 ] || [ "$pack_files" -gt 10 ]; then
echo "Maintenance recommended:"
echo " Loose objects: $loose_objects"
echo " Pack files: $pack_files"
# Perform maintenance
git prune-packed --quiet
git repack -a -d -q
echo "✓ Maintenance completed"
echo "Consider committing and pushing maintenance results"
else
echo "Repository is well-maintained"
fi
}
team_maintenance_workflow
Terminal window
# Optimize repositories for backup efficiency
backup_optimization() {
local repo_path="$1"
cd "$repo_path"
echo "Optimizing repository for backup: $(basename "$repo_path")"
# Pre-optimization
echo "Before optimization:"
git count-objects -v
# Optimize for backup
git prune-packed --quiet
git repack -a -d -f --depth=250 --window=250
# Create backup pack
git bundle create "backup-$(date +%Y%m%d).bundle" --all
# Clean up temporary files
git prune --expire=1.day.ago --quiet
# Post-optimization
echo "After optimization:"
git count-objects -v
echo "Backup optimization complete"
echo "Bundle created: backup-$(date +%Y%m%d).bundle"
}
backup_optimization "/repos/my-project"

What’s the difference between prune-packed and git prune?

Section titled “What’s the difference between prune-packed and git prune?”

prune-packed removes loose objects that exist in packs; git prune removes unreachable loose objects (not in any pack). Use both for complete cleanup.

Run after git repack operations, during repository maintenance, or when git count-objects shows many loose objects. Part of regular git gc workflow.

No, it only removes loose objects that have packed copies. The packed versions remain intact and accessible.

How do I check what prune-packed will remove?

Section titled “How do I check what prune-packed will remove?”

Use —dry-run to see which loose objects would be removed without actually deleting them.

What’s the impact of prune-packed on performance?

Section titled “What’s the impact of prune-packed on performance?”

Improves performance by reducing loose object count. Repository operations become faster with fewer loose objects to check.

Can prune-packed work on bare repositories?

Section titled “Can prune-packed work on bare repositories?”

Yes, operates on object database regardless of working directory. Essential for server-side repository maintenance.

How does prune-packed interact with git gc?

Section titled “How does prune-packed interact with git gc?”

git gc calls prune-packed as part of its maintenance routine. Manual prune-packed useful for targeted loose object cleanup.

Operation is atomic - either completes or doesn’t modify repository. Can safely restart interrupted operations.

Can prune-packed remove objects that are still needed?

Section titled “Can prune-packed remove objects that are still needed?”

No, only removes loose objects that have packed equivalents. Packed objects ensure data availability.

How do I monitor prune-packed effectiveness?

Section titled “How do I monitor prune-packed effectiveness?”

Compare git count-objects output before/after, check loose object count reduction, monitor repository size changes.

What’s the relationship between prune-packed and pack files?

Section titled “What’s the relationship between prune-packed and pack files?”

prune-packed identifies objects in pack files and removes their loose counterparts, optimizing storage without affecting packed data.

Can prune-packed work with multiple pack files?

Section titled “Can prune-packed work with multiple pack files?”

Yes, analyzes all pack files in .git/objects/pack/ and removes loose objects found in any pack.

How do I handle prune-packed in automated scripts?

Section titled “How do I handle prune-packed in automated scripts?”

Use —quiet for silent operation, check exit codes, implement dry-run verification, log operations for audit trails.

What’s the performance overhead of prune-packed?

Section titled “What’s the performance overhead of prune-packed?”

Depends on loose object count and pack file complexity. Fast for small repositories, may take time for large ones with many packs.

Can prune-packed be run concurrently with other Git operations?

Section titled “Can prune-packed be run concurrently with other Git operations?”

Generally safe but best run during maintenance windows. Avoid during active development to prevent conflicts.

How do I recover if prune-packed removes needed objects?

Section titled “How do I recover if prune-packed removes needed objects?”

Objects remain in pack files. If loose objects were needed for some reason, they’re still accessible through packs.

Applications of the git prune-packed command

Section titled “Applications of the git prune-packed command”
  1. Repository Optimization: Remove redundant loose objects to improve storage efficiency and performance
  2. Maintenance Automation: Include in automated repository maintenance schedules
  3. Post-Repack Cleanup: Clean up loose objects after repacking operations
  4. Storage Management: Reduce repository size by eliminating duplicate object storage
  5. Performance Tuning: Improve Git operation speed by reducing loose object overhead
  6. Backup Preparation: Optimize repositories before backup operations