Skip to content

show-index Git Command Guide

The git show-index command reads and displays the contents of Git pack index files (.idx), providing detailed information about packed objects, their offsets, and integrity validation. It’s primarily used for debugging pack files and understanding Git’s internal object storage.

Terminal window
git show-index [--object-format=<hash-algorithm>] [--objects | --no-objects] <pack-index>
OptionDescription
--objectsShow object information (default)
--no-objectsDon’t show object information
--object-format=<hash-algorithm>Specify hash algorithm
ParameterDescription
<pack-index>Path to pack index file (.idx)
Pack Index File Contents:
<packfile-offset> <object-hash> <object-type> <object-size>
<packfile-offset> <object-hash> <object-type> <object-size>
...
Example Output:
12 a1b2c3d4e5f6f7e8d9c0b1a2b3c4d5e6 blob 1234
567 abc123def456789012345678901234567890 commit 234
...
Git Object Types in Packs:
├── commit = Commit objects
├── tree = Tree objects (directory structure)
├── blob = File content objects
├── tag = Tag objects
└── ofs-delta = Offset delta (differential storage)
Pack Index File (.idx) Structure:
├── Header: Magic number and version
├── Fan-out table: Object count by first byte
├── Object hashes: Sorted list of all object hashes
├── CRC32 checksums: For each object
├── Pack file offsets: Location in .pack file
├── Pack file checksum: SHA-1 of .pack file
└── Index checksum: SHA-1 of index file
Terminal window
# Show contents of pack index
git show-index .git/objects/pack/pack-abc123.idx
# Show without object details
git show-index --no-objects pack-abc123.idx
# Show with specific hash algorithm
git show-index --object-format=sha1 pack-abc123.idx
Terminal window
# List all pack files in repository
find .git/objects/pack -name "*.idx"
# Show largest pack file
ls -la .git/objects/pack/*.idx | sort -k5 -nr | head -1
# Show pack file info
ls -la .git/objects/pack/
Terminal window
# Count objects in pack
git show-index pack-abc123.idx | wc -l
# Find largest objects
git show-index pack-abc123.idx | sort -k4 -nr | head -10
# Count object types
git show-index pack-abc123.idx | awk '{print $3}' | sort | uniq -c
Terminal window
# Analyze all pack files
for idx in .git/objects/pack/*.idx; do
echo "=== $(basename "$idx") ==="
git show-index "$idx" | head -5
echo "Total objects: $(git show-index "$idx" | wc -l)"
echo ""
done
# Find duplicate objects across packs
git show-index .git/objects/pack/*.idx | cut -d' ' -f2 | sort | uniq -d
# Check pack file integrity
for pack in .git/objects/pack/*.pack; do
idx="${pack%.pack}.idx"
if [ -f "$idx" ]; then
echo "✓ Pack file $(basename "$pack") has index"
else
echo "✗ Missing index for $(basename "$pack")"
fi
done
Terminal window
# Analyze pack efficiency
total_objects=$(git show-index .git/objects/pack/*.idx | wc -l)
total_size=$(du -bc .git/objects/pack/*.pack | tail -1 | cut -f1)
avg_size=$((total_size / total_objects))
echo "Total objects: $total_objects"
echo "Total pack size: $total_size bytes"
echo "Average object size: $avg_size bytes"
# Find oversized objects
git show-index .git/objects/pack/*.idx | awk '$4 > 1000000 {print $4, $2, $3}' | sort -nr
Terminal window
# Extract object from pack (advanced)
pack_file="pack-abc123.pack"
idx_file="pack-abc123.idx"
# Get object info
object_info=$(git show-index "$idx_file" | grep "a1b2c3d4")
offset=$(echo "$object_info" | cut -d' ' -f1)
hash=$(echo "$object_info" | cut -d' ' -f2)
# Use git unpack-objects for extraction
# Note: This is a low-level operation
Terminal window
# Configure pack behavior
git config pack.packSizeLimit 2g # Maximum pack size
git config pack.compression 6 # Compression level
git config pack.deltaCacheSize 256m # Delta cache size
# Configure repacking
git config pack.window 10 # Delta window size
git config pack.depth 50 # Maximum delta depth
Terminal window
# Use for pack analysis
git show-index .git/objects/pack/*.idx | head -20
# Check pack integrity
find .git/objects/pack -name "*.idx" -exec git show-index {} \; >/dev/null
# Monitor pack growth
du -sh .git/objects/pack/
Terminal window
# Check file exists
if [ -f ".git/objects/pack/$pack.idx" ]; then
git show-index ".git/objects/pack/$pack.idx"
else
echo "Pack index file not found"
fi
# Handle large outputs
git show-index "$idx_file" | head -100 # Limit output
#!/bin/bash
# Pack file maintenance with show-index
analyze_packs() {
echo "=== Pack File Analysis ==="
# List all pack files
pack_files=$(find .git/objects/pack -name "*.idx" | sort)
if [ -z "$pack_files" ]; then
echo "No pack files found"
return 0
fi
total_objects=0
total_size=0
for idx_file in $pack_files; do
pack_file="${idx_file%.idx}.pack"
pack_name=$(basename "$idx_file" .idx)
# Get pack statistics
objects=$(git show-index "$idx_file" | wc -l)
size=$(stat -f%z "$pack_file" 2>/dev/null || stat -c%s "$pack_file" 2>/dev/null || echo "0")
echo "$pack_name:"
echo " Objects: $objects"
echo " Size: $size bytes"
echo " Avg object size: $((size / objects)) bytes"
echo ""
total_objects=$((total_objects + objects))
total_size=$((total_size + size))
done
echo "Repository totals:"
echo " Total objects: $total_objects"
echo " Total pack size: $total_size bytes"
echo " Average object size: $((total_size / total_objects)) bytes"
}
# Repack optimization
optimize_packs() {
echo "=== Pack Optimization ==="
# Check if repacking is needed
loose_objects=$(find .git/objects -type f | grep -v pack | wc -l)
if [ "$loose_objects" -gt 100 ]; then
echo "Found $loose_objects loose objects - repacking recommended"
echo "Run: git gc"
else
echo "Repository is well-packed"
fi
# Analyze pack efficiency
largest_objects=$(git show-index .git/objects/pack/*.idx 2>/dev/null | sort -k4 -nr | head -5)
if [ -n "$largest_objects" ]; then
echo ""
echo "Largest objects in packs:"
echo "$largest_objects"
fi
}
analyze_packs
optimize_packs
Terminal window
# Debug pack file problems
debug_packs() {
echo "=== Pack File Debugging ==="
# Check pack file integrity
for pack in .git/objects/pack/*.pack; do
idx="${pack%.pack}.idx"
pack_name=$(basename "$pack" .pack)
if [ ! -f "$idx" ]; then
echo "✗ Missing index for $pack_name"
continue
fi
# Verify pack integrity
if git verify-pack "$pack" >/dev/null 2>&1; then
echo "$pack_name is valid"
else
echo "$pack_name has errors"
fi
done
# Check for unreachable objects
echo ""
echo "Unreachable objects:"
git fsck --unreachable | grep "^unreachable" | wc -l
# Analyze object distribution
echo ""
echo "Object type distribution:"
git show-index .git/objects/pack/*.idx 2>/dev/null | awk '{print $3}' | sort | uniq -c | sort -nr
}
debug_packs
Terminal window
# Monitor pack performance
pack_performance() {
echo "=== Pack Performance Analysis ==="
# Measure pack access time
start_time=$(date +%s.%3N)
git show-index .git/objects/pack/*.idx >/dev/null 2>&1
end_time=$(date +%s.%3N)
elapsed=$(echo "$end_time - $start_time" | bc 2>/dev/null || echo "0")
echo "Pack index read time: ${elapsed}s"
# Analyze pack structure
total_packs=$(ls .git/objects/pack/*.idx 2>/dev/null | wc -l)
echo "Number of packs: $total_packs"
if [ "$total_packs" -gt 10 ]; then
echo "⚠ Many pack files - consider repacking"
echo "Run: git repack -a -d"
fi
# Check pack file sizes
echo ""
echo "Pack file sizes:"
ls -lah .git/objects/pack/*.pack 2>/dev/null | sort -k5 -hr | head -5
}
pack_performance
Terminal window
# Find missing pack files
for idx in .git/objects/pack/*.idx; do
pack="${idx%.idx}.pack"
if [ ! -f "$pack" ]; then
echo "Missing pack file for $(basename "$idx")"
fi
done
# Recreate missing packs (if possible)
# Note: This usually requires repository recovery
Terminal window
# Detect corrupted packs
git fsck --full
# Verify specific pack
git verify-pack .git/objects/pack/pack-abc123.pack
# Recover from corruption
# Note: May require backup restoration
git fsck --full --unreachable | grep dangling
Terminal window
# Speed up pack operations
git config pack.threads 1 # Reduce thread contention
# Optimize pack access
git config core.deltaBaseCacheLimit 512m
# Repack for better performance
git repack -a -d --window=250 --depth=250
Terminal window
# Handle large pack files
git config pack.packSizeLimit 4g # Increase limit
# Use shallow clones for CI
git clone --depth 1 <url>
# Optimize pack window
git config pack.window 50
git config pack.depth 100
Terminal window
# Access objects in packs
git cat-file -p <object-hash>
# Check object existence
git cat-file -e <object-hash>
# Find object location
for idx in .git/objects/pack/*.idx; do
if git show-index "$idx" | grep -q "<object-hash>"; then
echo "Found in $(basename "$idx")"
break
fi
done
#!/bin/bash
# Comprehensive repository analysis
repository_analysis() {
echo "=== Comprehensive Repository Analysis ==="
# Pack file overview
echo "Pack File Overview:"
if ls .git/objects/pack/*.idx >/dev/null 2>&1; then
echo "Number of packs: $(ls .git/objects/pack/*.idx | wc -l)"
echo "Total pack size: $(du -sh .git/objects/pack/ | cut -f1)"
else
echo "No pack files found"
fi
# Object distribution
echo ""
echo "Object Distribution:"
if ls .git/objects/pack/*.idx >/dev/null 2>&1; then
git show-index .git/objects/pack/*.idx | awk '{print $3}' | sort | uniq -c | sort -nr | while read count type; do
echo " $type: $count"
done
fi
# Largest objects
echo ""
echo "Largest Objects:"
if ls .git/objects/pack/*.idx >/dev/null 2>&1; then
git show-index .git/objects/pack/*.idx | sort -k4 -nr | head -5 | while read offset hash type size; do
echo " $hash ($type): $size bytes"
done
fi
# Repository efficiency
echo ""
echo "Repository Efficiency:"
total_objects=$(find .git/objects -type f | grep -v pack | wc -l)
packed_objects=$(git show-index .git/objects/pack/*.idx 2>/dev/null | wc -l)
echo " Loose objects: $total_objects"
echo " Packed objects: $packed_objects"
if [ "$total_objects" -gt 100 ]; then
echo "⚠ Consider running: git gc"
fi
# Repository size breakdown
echo ""
echo "Size Breakdown:"
echo " Objects: $(du -sh .git/objects/ | cut -f1)"
echo " Refs: $(du -sh .git/refs/ | cut -f1)"
echo " Logs: $(du -sh .git/logs/ | cut -f1)"
echo " Config: $(du -sh .git/config | cut -f1)"
}
repository_analysis
Terminal window
# Automated pack maintenance
pack_maintenance() {
echo "=== Pack File Maintenance ==="
# Check pack file health
echo "Checking pack file health..."
corrupted=0
for pack in .git/objects/pack/*.pack; do
if ! git verify-pack "$pack" >/dev/null 2>&1; then
echo "✗ Corrupted pack: $(basename "$pack")"
((corrupted++))
fi
done
if [ "$corrupted" -eq 0 ]; then
echo "✓ All pack files are healthy"
fi
# Optimize pack structure
echo ""
echo "Optimizing pack structure..."
# Count unreachable objects
unreachable=$(git fsck --unreachable 2>/dev/null | grep "^unreachable" | wc -l)
echo "Unreachable objects: $unreachable"
if [ "$unreachable" -gt 1000 ]; then
echo "⚠ Many unreachable objects - consider cleanup"
echo "Run: git gc --prune=now"
fi
# Repack if needed
pack_count=$(ls .git/objects/pack/*.idx 2>/dev/null | wc -l)
if [ "$pack_count" -gt 5 ]; then
echo "⚠ Many pack files ($pack_count) - consider repacking"
echo "Run: git repack -a -d"
fi
# Update pack statistics
echo ""
echo "Pack Statistics:"
git count-objects -v | grep -E "(count|size|packs)"
}
pack_maintenance
Terminal window
# Debug repository problems
debug_repository() {
echo "=== Repository Debugging ==="
# Check basic repository health
if ! git status >/dev/null 2>&1; then
echo "✗ Repository is not valid"
return 1
fi
echo "✓ Repository is valid"
# Check pack file consistency
echo ""
echo "Pack file consistency:"
for idx in .git/objects/pack/*.idx; do
pack="${idx%.idx}.pack"
if [ -f "$pack" ]; then
# Quick integrity check
if git show-index "$idx" >/dev/null 2>&1; then
echo "✓ $(basename "$idx"): OK"
else
echo "✗ $(basename "$idx"): FAILED"
fi
else
echo "⚠ $(basename "$idx"): Missing pack file"
fi
done
# Check for missing objects
echo ""
echo "Missing object check:"
missing_objects=$(git fsck 2>&1 | grep "missing" | wc -l)
if [ "$missing_objects" -eq 0 ]; then
echo "✓ No missing objects"
else
echo "✗ Found $missing_objects missing objects"
fi
# Check reflog consistency
echo ""
echo "Reflog consistency:"
if git reflog | head -1 >/dev/null 2>&1; then
echo "✓ Reflog is accessible"
else
echo "⚠ Reflog issues detected"
fi
# Performance check
echo ""
echo "Performance check:"
start_time=$(date +%s.%3N)
git show-index .git/objects/pack/*.idx >/dev/null 2>&1
end_time=$(date +%s.%3N)
elapsed=$(echo "$end_time - $start_time" | bc 2>/dev/null || echo "0")
if (( $(echo "$elapsed > 5" | bc -l 2>/dev/null || echo "0") )); then
echo "⚠ Slow pack access (${elapsed}s)"
else
echo "✓ Pack access performance OK"
fi
}
debug_repository
Terminal window
# Analyze repository for migration
migration_analysis() {
echo "=== Repository Migration Analysis ==="
# Repository size analysis
echo "Repository size breakdown:"
echo " Total size: $(du -sh .git/ | cut -f1)"
echo " Pack files: $(du -sh .git/objects/pack/ 2>/dev/null | cut -f1)"
echo " Loose objects: $(find .git/objects -type f | grep -v pack | wc -l) files"
# Object type distribution
echo ""
echo "Object type distribution:"
git show-index .git/objects/pack/*.idx 2>/dev/null | awk '{print $3}' | sort | uniq -c | sort -nr
# Largest objects (potential migration issues)
echo ""
echo "Largest objects (top 10):"
git show-index .git/objects/pack/*.idx 2>/dev/null | sort -k4 -nr | head -10 | while read offset hash type size; do
echo " $hash ($type): $(numfmt --to=iec-i --suffix=B $size)"
done
# Branch and tag count
echo ""
echo "Reference counts:"
echo " Branches: $(git branch -a | wc -l)"
echo " Tags: $(git tag | wc -l)"
echo " Remotes: $(git remote | wc -l)"
# Migration recommendations
echo ""
echo "Migration recommendations:"
total_objects=$(git show-index .git/objects/pack/*.idx 2>/dev/null | wc -l)
if [ "$total_objects" -gt 100000 ]; then
echo "⚠ Large repository ($total_objects objects)"
echo " Consider shallow clone for CI/CD"
echo " Consider LFS for large files"
fi
large_files=$(git show-index .git/objects/pack/*.idx 2>/dev/null | awk '$4 > 100000000 {count++} END {print count+0}')
if [ "$large_files" -gt 0 ]; then
echo "⚠ Found $large_files very large files (>100MB)"
echo " Consider Git LFS migration"
fi
pack_count=$(ls .git/objects/pack/*.idx 2>/dev/null | wc -l)
if [ "$pack_count" -gt 20 ]; then
echo "⚠ Many pack files ($pack_count)"
echo " Run: git repack -a -d"
fi
}
migration_analysis
Terminal window
# Security and integrity verification
security_check() {
echo "=== Repository Security & Integrity Check ==="
# Verify pack file checksums
echo "Verifying pack file integrity..."
for pack in .git/objects/pack/*.pack; do
if git verify-pack "$pack" >/dev/null 2>&1; then
echo "✓ $(basename "$pack"): Verified"
else
echo "✗ $(basename "$pack"): FAILED VERIFICATION"
fi
done
# Check for suspicious objects
echo ""
echo "Checking for suspicious objects..."
suspicious_objects=$(git show-index .git/objects/pack/*.idx 2>/dev/null | awk '$4 > 10000000 {print $2, $3, $4}')
if [ -n "$suspicious_objects" ]; then
echo "⚠ Large objects found:"
echo "$suspicious_objects"
else
echo "✓ No excessively large objects"
fi
# Verify reference integrity
echo ""
echo "Verifying reference integrity..."
broken_refs=0
git show-ref | while read -r hash ref; do
if ! git cat-file -e "$hash" 2>/dev/null; then
echo "✗ Broken reference: $ref -> $hash"
((broken_refs++))
fi
done
if [ "$broken_refs" -eq 0 ]; then
echo "✓ All references are valid"
else
echo "✗ Found $broken_refs broken references"
fi
# Check pack file permissions
echo ""
echo "Checking pack file permissions..."
for pack in .git/objects/pack/*; do
perms=$(stat -c "%a" "$pack" 2>/dev/null)
if [ "$perms" != "444" ] && [ "$perms" != "644" ]; then
echo "⚠ Unusual permissions on $(basename "$pack"): $perms"
fi
done
echo "✓ Permission check complete"
}
security_check

What’s the difference between git show-index and git verify-pack?

Section titled “What’s the difference between git show-index and git verify-pack?”

git show-index displays pack index contents in human-readable format, while git verify-pack validates pack integrity and shows detailed object information.

How do I find all pack index files in a repository?

Section titled “How do I find all pack index files in a repository?”

Use find .git/objects/pack -name “.idx” or ls .git/objects/pack/.idx to locate pack index files.

Can git show-index work with remote repositories?

Section titled “Can git show-index work with remote repositories?”

No, show-index only works with local pack files. Use git ls-remote to inspect remote repository information.

How do I see the largest objects in a pack file?

Section titled “How do I see the largest objects in a pack file?”

Use git show-index <pack.idx> | sort -k4 -nr to sort objects by size in descending order.

What’s the structure of a pack index file?

Section titled “What’s the structure of a pack index file?”

Pack index files contain a header, fan-out table, sorted object hashes, CRC32 checksums, pack offsets, and checksums for integrity verification.

Can git show-index repair corrupted pack files?

Section titled “Can git show-index repair corrupted pack files?”

No, show-index only displays information. Use git fsck and git gc for repair operations, or restore from backups.

Use git show-index <pack.idx> | wc -l to count the total number of objects in the pack.

What’s the performance impact of show-index?

Section titled “What’s the performance impact of show-index?”

Very fast for reading index files, but can be slow for very large repositories with many pack files.

Can show-index work with different hash algorithms?

Section titled “Can show-index work with different hash algorithms?”

Yes, use —object-format to specify hash algorithm (sha1, sha256), though Git currently primarily uses SHA-1.

How do I find which pack file contains a specific object?

Section titled “How do I find which pack file contains a specific object?”

Search through all pack index files: for idx in .git/objects/pack/*.idx; do git show-index “$idx” | grep "" && echo “Found in $(basename “$idx”)”; done

What’s the difference between pack files and loose objects?

Section titled “What’s the difference between pack files and loose objects?”

Pack files store multiple objects compressed together, while loose objects are individual uncompressed files. Packs are more efficient for storage and transfer.

Can git show-index work with bare repositories?

Section titled “Can git show-index work with bare repositories?”

Yes, show-index works with any Git repository that has pack files, including bare repositories.

How do I monitor pack file growth over time?

Section titled “How do I monitor pack file growth over time?”

Use du -sh .git/objects/pack/ and git count-objects -v to track pack file sizes and object counts over time.

Git typically aims for pack files around 2GB, but this can be configured with pack.packSizeLimit.

Can show-index help with repository migration?

Section titled “Can show-index help with repository migration?”

Yes, use it to analyze repository size, object distribution, and identify large files that might need special handling during migration.

Applications of the git show-index command

Section titled “Applications of the git show-index command”
  1. Pack File Inspection: Examining contents and structure of Git pack files
  2. Repository Analysis: Understanding object distribution and pack efficiency
  3. Debugging: Investigating pack file corruption and integrity issues
  4. Performance Optimization: Analyzing pack file structure for better performance
  5. Migration Planning: Assessing repository size and composition for migration
  6. Security Auditing: Verifying pack file integrity and object validity
  7. Maintenance: Monitoring pack file health and optimization opportunities
  8. Forensic Analysis: Investigating repository history and object relationships