verify-pack Git Command Guide
The git verify-pack command validates pack files for corruption and displays detailed information about their contents, including object types, sizes, and deltas. It’s essential for diagnosing repository issues, optimizing storage, and ensuring data integrity.
git verify-pack Syntax:
Section titled “git verify-pack Syntax:”git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idxgit verify-pack --stdin [-v | --verbose] [-s | --stat-only] [--fix-thin] < <pack>Verification Options:
Section titled “Verification Options:”| Option | Description |
|---|---|
-v, --verbose | Show objects contained in pack |
-s, --stat-only | Show statistics only (no object list) |
--fix-thin | Stream complete objects for thin packs |
--stdin | Read pack from stdin instead of file |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<pack>.idx | Pack index file to verify |
<pack> | Pack file (when using —stdin) |
Understanding Pack File Verification:
Section titled “Understanding Pack File Verification:”Pack File Structure:
Section titled “Pack File Structure:”Git Pack File Components:├── Pack File (.pack): Compressed object data├── Pack Index (.idx): Lookup table for objects├── Object Types: Commits, trees, blobs, tags, deltas├── Delta Chains: Space-efficient object storage├── Checksums: SHA-1 integrity verification└── Metadata: Object offsets and typesVerification Process:
Section titled “Verification Process:”Pack File Verification Steps:├── Header Validation: Check pack signature and version├── Checksum Verification: Validate SHA-1 integrity├── Object Parsing: Ensure all objects are valid├── Delta Resolution: Verify delta chains are correct├── Cross-Reference Check: Validate internal references└── Index Consistency: Verify index matches pack contentObject Analysis:
Section titled “Object Analysis:”Pack Object Information:├── Object SHA-1: Unique identifier├── Object Type: commit, tree, blob, tag├── Object Size: Compressed and uncompressed sizes├── Delta Base: Reference for delta-compressed objects├── Chain Length: Delta chain depth└── Offset: Position in pack fileBasic Verify-Pack Operations:
Section titled “Basic Verify-Pack Operations:”Verify Pack File Integrity:
Section titled “Verify Pack File Integrity:”# Verify specific pack filegit verify-pack .git/objects/pack/pack-abc123.idx
# Verify all pack filesfor idx in .git/objects/pack/*.idx; do echo "Verifying $idx..." git verify-pack "$idx" || echo "Failed: $idx"done
# Verify pack from stdincat pack-file.pack | git verify-pack --stdinDisplay Pack Statistics:
Section titled “Display Pack Statistics:”# Show pack statistics onlygit verify-pack --stat-only .git/objects/pack/pack-abc123.idx
# Show detailed object informationgit verify-pack -v .git/objects/pack/pack-abc123.idxAnalyze Pack Contents:
Section titled “Analyze Pack Contents:”# List all objects in packgit verify-pack -v .git/objects/pack/pack-abc123.idx | head -20
# Count objects by typegit verify-pack -v .git/objects/pack/pack-abc123.idx | awk ' /blob/ {blobs++} /tree/ {trees++} /commit/ {commits++} /tag/ {tags++} END {print "Blobs:", blobs, "Trees:", trees, "Commits:", commits, "Tags:", tags}'
# Find largest objectsgit verify-pack -v .git/objects/pack/pack-abc123.idx | sort -k3 -nr | head -10Advanced Verify-Pack Scenarios:
Section titled “Advanced Verify-Pack Scenarios:”Repository Health Analysis:
Section titled “Repository Health Analysis:”# Analyze repository pack healthanalyze_pack_health() { echo "=== Repository Pack Health Analysis ==="
# Check all pack files total_objects=0 total_size=0
for idx in .git/objects/pack/*.idx; do echo "Analyzing $(basename "$idx")..."
# Get pack statistics stats=$(git verify-pack --stat-only "$idx") objects=$(echo "$stats" | grep "objects" | cut -d' ' -f1) size=$(echo "$stats" | grep "pack-sz" | cut -d' ' -f1)
echo " Objects: $objects" echo " Size: $size bytes"
total_objects=$((total_objects + objects)) total_size=$((total_size + size)) done
echo "Total objects: $total_objects" echo "Total pack size: $total_size bytes" echo "Average object size: $((total_size / total_objects)) bytes"}
# Find unreachable objectsfind_unreachable_objects() { echo "Finding unreachable objects in packs..."
# Get all packed objects git verify-pack -v .git/objects/pack/*.idx | cut -d' ' -f1 | sort > packed_objects.txt
# Get all reachable objects git rev-list --all --objects | cut -d' ' -f1 | sort > reachable_objects.txt
# Find unreachable objects comm -23 packed_objects.txt reachable_objects.txt > unreachable.txt
unreachable_count=$(wc -l < unreachable.txt) echo "Found $unreachable_count unreachable objects"
if [ "$unreachable_count" -gt 0 ]; then echo "Unreachable objects:" head -10 unreachable.txt echo "..." fi
# Cleanup rm packed_objects.txt reachable_objects.txt unreachable.txt}Pack File Optimization:
Section titled “Pack File Optimization:”# Analyze pack efficiencyanalyze_pack_efficiency() { echo "=== Pack File Efficiency Analysis ==="
for idx in .git/objects/pack/*.idx; do echo "Pack: $(basename "$idx")"
# Get detailed object info git verify-pack -v "$idx" | while read -r sha type size offset; do # Analyze delta chains if [[ "$type" == *"delta"* ]]; then chain_length=$(git verify-pack -v "$idx" | grep -c "^$sha") echo "Delta object: $sha, chain length: $chain_length" fi done
# Calculate compression ratio pack_size=$(stat -f%z "${idx%.idx}.pack" 2>/dev/null || stat -c%s "${idx%.idx}.pack") object_sizes=$(git verify-pack -v "$idx" | awk '{sum += $3} END {print sum}') ratio=$((object_sizes / pack_size))
echo "Compression ratio: ${ratio}:1" echo done}
# Repack for better compressionoptimize_packs() { echo "Optimizing pack files..."
# Unpack all objects temp_dir=$(mktemp -d) for pack in .git/objects/pack/*.pack; do git unpack-objects < "$pack" 2>/dev/null done
# Remove old packs rm -f .git/objects/pack/*.pack .git/objects/pack/*.idx
# Repack with optimal settings git config pack.window 250 git config pack.depth 250 git config pack.compression 9
git repack -a -d --depth=250 --window=250
# Cleanup temp directory rm -rf "$temp_dir"
echo "Pack optimization complete"}Corruption Detection and Recovery:
Section titled “Corruption Detection and Recovery:”# Detect pack file corruptiondetect_corruption() { echo "Detecting pack file corruption..."
corrupted_packs=()
for idx in .git/objects/pack/*.idx; do pack_file="${idx%.idx}.pack"
echo "Checking $(basename "$idx")..."
# Verify pack integrity if ! git verify-pack "$idx" >/dev/null 2>&1; then echo "✗ Corrupted: $(basename "$idx")" corrupted_packs+=("$idx") else echo "✓ Valid: $(basename "$idx")" fi done
if [ ${#corrupted_packs[@]} -gt 0 ]; then echo "Found ${#corrupted_packs[@]} corrupted pack(s)" echo "Consider running: git fsck --full" else echo "All pack files are valid" fi}
# Recover from pack corruptionrecover_from_corruption() { echo "Attempting recovery from pack corruption..."
# Create backup cp -r .git .git.backup
# Try to recover valid objects for pack in .git/objects/pack/*.pack; do echo "Attempting to recover from $(basename "$pack")..."
# Use strict verification to extract valid objects if git unpack-objects --strict < "$pack" 2>/dev/null; then echo "✓ Recovered objects from $(basename "$pack")" else echo "✗ Could not recover from $(basename "$pack")" fi done
# Clean up corrupted packs rm -f .git/objects/pack/*.pack .git/objects/pack/*.idx
# Rebuild repository git fsck --full git gc --aggressive
echo "Recovery attempt complete" echo "Original repository backed up in .git.backup"}Configuration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Pack Verification:
Section titled “Git Configuration for Pack Verification:”# Configure pack verification behaviorgit config pack.verifyObjects true # Verify objects during packinggit config transfer.fsckObjects true # Verify objects during transfer
# Configure pack creationgit config pack.window 10 # Delta window sizegit config pack.depth 50 # Delta depthgit config pack.compression 6 # Compression level
# Configure pack maintenancegit config gc.auto 670 # Objects before auto-GCgit config gc.autopacklimit 50 # Packs before auto-repackSafe Verify-Pack Operations:
Section titled “Safe Verify-Pack Operations:”# Safe pack verification with error handlingsafe_verify_pack() { local pack_idx="$1"
if [ ! -f "$pack_idx" ]; then echo "Error: Pack index file not found: $pack_idx" return 1 fi
echo "Verifying pack: $(basename "$pack_idx")"
# Attempt verification if git verify-pack "$pack_idx" >/dev/null 2>&1; then echo "✓ Pack file is valid" return 0 else echo "✗ Pack file verification failed" return 1 fi}
# Batch verification with progressbatch_verify_packs() { local pack_count pack_count=$(ls -1 .git/objects/pack/*.idx 2>/dev/null | wc -l) local current=0
echo "Batch verifying $pack_count pack files..."
for idx in .git/objects/pack/*.idx; do ((current++)) echo -n "[$current/$pack_count] Checking $(basename "$idx")... "
if safe_verify_pack "$idx" >/dev/null 2>&1; then echo "✓" else echo "✗" fi done
echo "Batch verification complete"}
# Usagebatch_verify_packsPerformance Optimization:
Section titled “Performance Optimization:”# Optimize pack verification performancefast_pack_verification() { local pack_idx="$1"
echo "Fast verifying pack: $(basename "$pack_idx")"
# Use parallel verification if available export GIT_VERIFY_PACK_THREADS=$(nproc 2>/dev/null || echo 4)
# Disable unnecessary checks for speed time git verify-pack --stat-only "$pack_idx" >/dev/null}
# Memory-efficient verificationmemory_efficient_verify() { local pack_idx="$1"
echo "Memory-efficient pack verification..."
# Reduce memory usage ulimit -v 1048576 # 1GB limit
# Process in chunks git verify-pack -v "$pack_idx" | head -1000 | while read -r line; do # Process objects in batches echo "$line" >/dev/null done
echo "Memory-efficient verification complete"}Integration with Development Workflows:
Section titled “Integration with Development Workflows:”Repository Maintenance Automation:
Section titled “Repository Maintenance Automation:”#!/bin/bash# Automated pack file maintenance
automated_pack_maintenance() { echo "=== Automated Pack File Maintenance ==="
# Daily pack verification daily_pack_check() { echo "Performing daily pack verification..."
log_file="/var/log/git-pack-maintenance.log" { echo "=== Daily Pack Check $(date) ==="
# Verify all packs batch_verify_packs
# Check pack efficiency analyze_pack_health
# Clean up old packs if needed if [ $(ls .git/objects/pack/*.pack 2>/dev/null | wc -l) -gt 10 ]; then echo "Consolidating pack files..." git repack -a -d fi
echo "Daily pack check complete" } >> "$log_file" 2>&1 }
# Weekly pack optimization weekly_pack_optimization() { echo "Performing weekly pack optimization..."
# Aggressive optimization git config pack.window 250 git config pack.depth 250 git config pack.compression 9
git repack -a -d --depth=250 --window=250 git gc --aggressive --prune=now
echo "Weekly pack optimization complete" }
# Setup automated maintenance setup_automated_maintenance() { echo "Setting up automated pack maintenance..."
# Daily verification (crontab -l ; echo "0 2 * * * $(pwd)/automated-pack-maintenance.sh daily") | crontab -
# Weekly optimization (Sundays at 3 AM) (crontab -l ; echo "0 3 * * 0 $(pwd)/automated-pack-maintenance.sh weekly") | crontab -
echo "Automated maintenance scheduled" }
# Interactive maintenance case "${1:-}" in "daily") daily_pack_check ;; "weekly") weekly_pack_optimization ;; "setup") setup_automated_maintenance ;; *) echo "Usage: $0 {daily|weekly|setup}" echo " daily - Daily pack verification" echo " weekly - Weekly pack optimization" echo " setup - Setup automated maintenance" ;; esac}
# Usageautomated_pack_maintenance "$@"CI/CD Pipeline Integration:
Section titled “CI/CD Pipeline Integration:”# Pack verification in CI/CD pipelinesci_pack_verification() { echo "=== CI/CD Pack File Verification ==="
# Pre-deployment pack validation validate_deployment_packs() { echo "Validating deployment pack files..."
# Find pack files in build artifacts find build/ -name "*.pack" | while read -r pack_file; do echo "Validating $pack_file..."
# Verify pack integrity if git verify-pack --stdin < "$pack_file" >/dev/null 2>&1; then echo "✓ Pack file valid: $(basename "$pack_file")"
# Get pack statistics stats=$(git verify-pack --stat-only --stdin < "$pack_file") echo " Statistics: $stats" else echo "✗ Pack file corrupted: $(basename "$pack_file")" return 1 fi done
echo "All pack files validated" }
# Generate pack file report generate_pack_report() { echo "Generating pack file report..."
cat > pack-report.md << EOF# Pack File Analysis Report
Generated: $(date)Repository: $(basename "$(pwd)")Build: ${CI_BUILD_ID:-unknown}
## Pack File Statistics
EOF
# Analyze each pack file find .git/objects/pack/ -name "*.idx" | while read -r idx_file; do pack_name=$(basename "${idx_file%.idx}") echo "### Pack: $pack_name" >> pack-report.md
stats=$(git verify-pack --stat-only "$idx_file") echo "\`\`\`" >> pack-report.md echo "$stats" >> pack-report.md echo "\`\`\`" >> pack-report.md echo "" >> pack-report.md done
echo "Pack report generated: pack-report.md" }
# Performance benchmarking benchmark_pack_operations() { echo "Benchmarking pack operations..."
# Measure verification time start_time=$(date +%s.%3N) git verify-pack .git/objects/pack/*.idx >/dev/null 2>&1 end_time=$(date +%s.%3N)
verify_time=$(echo "$end_time - $start_time" | bc) echo "Pack verification time: ${verify_time}s"
# Measure pack access time start_time=$(date +%s.%3N) git log --oneline -100 >/dev/null 2>&1 end_time=$(date +%s.%3N)
access_time=$(echo "$end_time - $start_time" | bc) echo "Pack access time (100 commits): ${access_time}s" }
# Run CI/CD pack operations validate_deployment_packs generate_pack_report benchmark_pack_operations}
# Usage in CIci_pack_verificationRepository Analysis Tools:
Section titled “Repository Analysis Tools:”# Advanced repository analysis using verify-packrepository_pack_analysis() { echo "=== Repository Pack Analysis ==="
# Analyze object distribution analyze_object_distribution() { echo "Analyzing object type distribution..."
git verify-pack -v .git/objects/pack/*.idx | awk ' / blob / {blobs += $3; blob_count++} / tree / {trees += $3; tree_count++} / commit / {commits += $3; commit_count++} / tag / {tags += $3; tag_count++} END { total = blobs + trees + commits + tags print "Object Type Distribution:" print " Blobs: " blob_count " objects, " blobs " bytes (" int(blobs*100/total) "%)" print " Trees: " tree_count " objects, " trees " bytes (" int(trees*100/total) "%)" print " Commits: " commit_count " objects, " commits " bytes (" int(commits*100/total) "%)" print " Tags: " tag_count " objects, " tags " bytes (" int(tags*100/total) "%)" print "Total: " (blob_count + tree_count + commit_count + tag_count) " objects, " total " bytes" } ' }
# Find duplicate objects find_duplicate_objects() { echo "Finding duplicate objects across packs..."
# Extract all object hashes git verify-pack -v .git/objects/pack/*.idx | cut -d' ' -f1 | sort | uniq -d > duplicates.txt
duplicate_count=$(wc -l < duplicates.txt) echo "Found $duplicate_count duplicate objects"
if [ "$duplicate_count" -gt 0 ]; then echo "Duplicate objects:" head -10 duplicates.txt echo "..."
# Suggest repack echo "Consider running: git repack -a -d" fi
rm -f duplicates.txt }
# Analyze delta chains analyze_delta_chains() { echo "Analyzing delta compression chains..."
max_chain=0 total_chains=0
git verify-pack -v .git/objects/pack/*.idx | while read -r sha type size offset; do if [[ "$type" == *"delta"* ]]; then # Count chain length (simplified) chain_length=1 current_sha="$sha"
# This is a simplified analysis # Real delta chain analysis is more complex while [[ "$type" == *"delta"* ]]; do ((chain_length++)) # In practice, you would follow the delta base done
((total_chains++)) [ "$chain_length" -gt "$max_chain" ] && max_chain="$chain_length" fi done
echo "Delta chain analysis:" echo " Total delta chains: $total_chains" echo " Maximum chain length: $max_chain"
if [ "$max_chain" -gt 50 ]; then echo "⚠ Long delta chains detected, consider repacking" fi }
# Generate comprehensive report generate_comprehensive_report() { echo "Generating comprehensive pack analysis report..."
cat > pack-analysis-report.md << EOF# Repository Pack Analysis Report
Generated: $(date)Repository: $(basename "$(pwd)")
## Repository Statistics- Total Objects: $(git rev-list --all --count)- Pack Files: $(ls .git/objects/pack/*.pack 2>/dev/null | wc -l)- Loose Objects: $(find .git/objects -type f | grep -v pack | wc -l)
## Pack File DetailsEOF
# Add pack details for idx in .git/objects/pack/*.idx; do pack_name=$(basename "${idx%.idx}") echo "### $pack_name" >> pack-analysis-report.md echo "\`\`\`" >> pack-analysis-report.md git verify-pack --stat-only "$idx" >> pack-analysis-report.md echo "\`\`\`" >> pack-analysis-report.md echo "" >> pack-analysis-report.md done
echo "## Recommendations" >> pack-analysis-report.md
# Add recommendations pack_count=$(ls .git/objects/pack/*.pack 2>/dev/null | wc -l) if [ "$pack_count" -gt 20 ]; then echo "- Consider consolidating packs: \`git repack -a -d\`" >> pack-analysis-report.md fi
loose_count=$(find .git/objects -type f | grep -v pack | wc -l) if [ "$loose_count" -gt 1000 ]; then echo "- Consider packing loose objects: \`git gc\`" >> pack-analysis-report.md fi
echo "Comprehensive report generated: pack-analysis-report.md" }
# Run all analyses analyze_object_distribution echo find_duplicate_objects echo analyze_delta_chains echo generate_comprehensive_report}
# Usagerepository_pack_analysisTroubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Pack File Corruption Issues:
Section titled “Pack File Corruption Issues:”# Diagnose pack corruptiondiagnose_pack_corruption() { echo "Diagnosing pack file corruption..."
# Check pack file headers for pack in .git/objects/pack/*.pack; do echo "Checking header of $(basename "$pack")..."
# Read first 12 bytes (pack header) header=$(dd if="$pack" bs=1 count=12 2>/dev/null | od -c) expected="177 P A C K \0 \0 \0 \2"
if [[ "$header" == *"$expected"* ]]; then echo "✓ Valid pack header" else echo "✗ Invalid pack header" fi done
# Check index files for idx in .git/objects/pack/*.idx; do echo "Checking index of $(basename "$idx")..."
if git verify-pack "$idx" >/dev/null 2>&1; then echo "✓ Valid pack index" else echo "✗ Invalid pack index" fi done}
# Recover from pack corruptionrecover_pack_corruption() { echo "Attempting to recover from pack corruption..."
# Method 1: Use git fsck to find issues echo "Running git fsck..." git fsck --full 2>&1 | grep -E "(missing|corrupt)"
# Method 2: Try to unpack valid objects echo "Attempting to extract valid objects..." for pack in .git/objects/pack/*.pack; do pack_name=$(basename "$pack") echo "Processing $pack_name..."
# Create backup cp "$pack" "${pack}.backup"
# Try strict unpacking if git unpack-objects --strict < "$pack" 2>/dev/null; then echo "✓ Successfully unpacked some objects from $pack_name" else echo "✗ Could not unpack objects from $pack_name" fi done
# Method 3: Rebuild from known good state echo "Rebuilding repository from known good refs..." git gc --aggressive git fsck --full
echo "Recovery attempt complete"}Performance Issues:
Section titled “Performance Issues:”# Troubleshoot pack performance issuestroubleshoot_pack_performance() { echo "Troubleshooting pack file performance..."
# Check pack file sizes echo "Pack file sizes:" ls -lh .git/objects/pack/*.pack | while read -r line; do size=$(echo "$line" | awk '{print $5}') name=$(echo "$line" | awk '{print $9}') echo " $(basename "$name"): $size" done
# Check delta chain lengths echo "Analyzing delta chains..." long_chains=$(git verify-pack -v .git/objects/pack/*.idx | awk ' /delta/ {count++} END {print count} ')
echo "Objects in delta chains: $long_chains"
# Check pack window settings echo "Current pack settings:" git config --list | grep "^pack\." | while read -r config; do echo " $config" done
# Recommendations pack_count=$(ls .git/objects/pack/*.pack 2>/dev/null | wc -l) if [ "$pack_count" -gt 10 ]; then echo "Recommendation: Consolidate packs with 'git repack -a -d'" fi
if [ "$long_chains" -gt 1000 ]; then echo "Recommendation: Increase pack.window and repack" fi}
# Optimize pack accessoptimize_pack_access() { echo "Optimizing pack file access..."
# Enable pack bitmap indexes git repack --write-bitmap-index -a -d
# Configure for better performance git config core.deltaBaseCacheLimit 2g git config pack.threads 4 git config pack.useBitmaps true
# Warm up object cache echo "Warming up object cache..." git log --all --oneline >/dev/null
echo "Pack access optimization complete"}Memory and Resource Issues:
Section titled “Memory and Resource Issues:”# Handle memory issues during verificationhandle_memory_issues() { echo "Handling memory issues during pack verification..."
# Reduce memory usage git config pack.windowMemory "100m" git config pack.packSizeLimit "100m"
# Process packs individually for idx in .git/objects/pack/*.idx; do echo "Verifying $(basename "$idx") with limited memory..."
# Use ulimit to restrict memory (ulimit -v 524288; git verify-pack "$idx" >/dev/null 2>&1 && echo "✓" || echo "✗") done
# Reset memory limits git config --unset pack.windowMemory git config --unset pack.packSizeLimit}
# Handle large pack fileshandle_large_packs() { echo "Handling large pack files..."
# Find large packs find .git/objects/pack/ -name "*.pack" -size +100M | while read -r pack; do echo "Large pack detected: $(basename "$pack")"
# Consider splitting or optimizing pack_size=$(stat -f%z "$pack" 2>/dev/null || stat -c%s "$pack") echo "Size: $((pack_size / 1024 / 1024))MB"
# Suggest optimization echo "Consider: git repack -a -d --max-pack-size=500m" done}
# Batch processing for many packsbatch_pack_processing() { echo "Batch processing pack files..."
# Process in parallel if possible max_jobs=$(nproc 2>/dev/null || echo 2)
ls .git/objects/pack/*.idx | xargs -n 1 -P "$max_jobs" -I {} bash -c ' idx="$1" if git verify-pack "$idx" >/dev/null 2>&1; then echo "✓ $(basename "$idx")" else echo "✗ $(basename "$idx")" fi ' _ {}}
# Usagehandle_memory_issueshandle_large_packsbatch_pack_processingReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Enterprise Repository Maintenance:
Section titled “Enterprise Repository Maintenance:”#!/bin/bash# Enterprise pack file maintenance system
enterprise_pack_maintenance() { echo "=== Enterprise Pack File Maintenance ==="
# Multi-repository pack analysis analyze_multi_repo_packs() { local repos_dir="$1"
echo "Analyzing pack files across repositories..."
find "$repos_dir" -name "*.git" -type d | while read -r repo; do echo "## Repository: $(basename "${repo%.git}")"
if [ -d "$repo/objects/pack" ]; then pack_count=$(ls "$repo/objects/pack"/*.pack 2>/dev/null | wc -l) total_size=$(du -bc "$repo/objects/pack"/*.pack 2>/dev/null | tail -1 | cut -f1)
echo " Pack files: $pack_count" echo " Total size: $((total_size / 1024 / 1024))MB"
# Check for corruption find "$repo/objects/pack" -name "*.idx" | while read -r idx; do if ! git --git-dir="$repo" verify-pack "$idx" >/dev/null 2>&1; then echo " ⚠ Corrupted pack: $(basename "$idx")" fi done else echo " No pack files" fi echo done }
# Automated pack consolidation consolidate_enterprise_packs() { local repos_dir="$1"
echo "Consolidating pack files across enterprise repositories..."
find "$repos_dir" -name "*.git" -type d | while read -r repo; do repo_name=$(basename "${repo%.git}") echo "Processing $repo_name..."
# Count packs before packs_before=$(ls "$repo/objects/pack"/*.pack 2>/dev/null | wc -l)
# Consolidate packs git --git-dir="$repo" repack -a -d >/dev/null 2>&1
# Count packs after packs_after=$(ls "$repo/objects/pack"/*.pack 2>/dev/null | wc -l)
if [ "$packs_before" != "$packs_after" ]; then echo " Consolidated: $packs_before → $packs_after packs" fi done
echo "Enterprise pack consolidation complete" }
# Generate enterprise pack report generate_enterprise_report() { local repos_dir="$1" local report_file="enterprise-pack-report-$(date +%Y%m%d).md"
echo "Generating enterprise pack report..."
cat > "$report_file" << EOF# Enterprise Pack File Report
Generated: $(date)Repositories Directory: $repos_dir
## Summary StatisticsEOF
total_repos=0 total_packs=0 total_size=0
find "$repos_dir" -name "*.git" -type d | while read -r repo; do ((total_repos++)) repo_name=$(basename "${repo%.git}")
if [ -d "$repo/objects/pack" ]; then pack_count=$(ls "$repo/objects/pack"/*.pack 2>/dev/null | wc -l) repo_size=$(du -bc "$repo/objects/pack"/*.pack 2>/dev/null | tail -1 | cut -f1 || echo 0)
((total_packs += pack_count)) ((total_size += repo_size))
echo "- $repo_name: $pack_count packs, $((repo_size / 1024 / 1024))MB" >> "$report_file" fi done
cat >> "$report_file" << EOF
## Overall Statistics- Total Repositories: $total_repos- Total Pack Files: $total_packs- Total Pack Size: $((total_size / 1024 / 1024))MB- Average Packs per Repo: $((total_packs / total_repos))- Average Size per Repo: $((total_size / total_repos / 1024 / 1024))MB
## RecommendationsEOF
# Add recommendations avg_packs=$((total_packs / total_repos)) if [ "$avg_packs" -gt 5 ]; then echo "- Consider pack consolidation (average $avg_packs packs per repository)" >> "$report_file" fi
avg_size=$((total_size / total_repos / 1024 / 1024)) if [ "$avg_size" -gt 500 ]; then echo "- Large repositories detected (average ${avg_size}MB per repository)" >> "$report_file" fi
echo "Enterprise pack report generated: $report_file" }
# Interactive enterprise maintenance echo "Enterprise Pack Maintenance Options:" echo "1. Analyze multi-repository packs" echo "2. Consolidate enterprise packs" echo "3. Generate enterprise report"
read -p "Select option (1-3): " option
case "$option" in 1) read -p "Repositories directory: " repos_dir analyze_multi_repo_packs "$repos_dir" ;; 2) read -p "Repositories directory: " repos_dir consolidate_enterprise_packs "$repos_dir" ;; 3) read -p "Repositories directory: " repos_dir generate_enterprise_report "$repos_dir" ;; esac}
enterprise_pack_maintenanceForensic Repository Analysis:
Section titled “Forensic Repository Analysis:”# Forensic pack file analysisforensic_pack_analysis() { echo "=== Forensic Pack File Analysis ==="
# Analyze pack creation timeline analyze_pack_timeline() { echo "Analyzing pack file creation timeline..."
ls -la .git/objects/pack/ | while read -r line; do if [[ "$line" == *".pack" ]]; then # Extract timestamp and filename timestamp=$(echo "$line" | awk '{print $6, $7, $8}') filename=$(echo "$line" | awk '{print $9}')
echo "$timestamp - $filename" fi done | sort
echo "Timeline analysis complete" }
# Extract pack metadata extract_pack_metadata() { echo "Extracting pack file metadata..."
for idx in .git/objects/pack/*.idx; do pack_name=$(basename "${idx%.idx}") echo "Pack: $pack_name"
# Get pack statistics git verify-pack --stat-only "$idx" | while read -r line; do echo " $line" done
# Get creation time pack_file="${idx%.idx}.pack" if [ -f "$pack_file" ]; then created=$(stat -c%y "$pack_file" 2>/dev/null || stat -f%Sm -t "%Y-%m-%d %H:%M:%S" "$pack_file") echo " Created: $created" fi
echo done }
# Detect pack file anomalies detect_pack_anomalies() { echo "Detecting pack file anomalies..."
# Check for unusually large packs find .git/objects/pack/ -name "*.pack" -size +1G | while read -r pack; do size=$(stat -f%z "$pack" 2>/dev/null || stat -c%s "$pack") echo "⚠ Large pack detected: $(basename "$pack") ($((size / 1024 / 1024))MB)" done
# Check for packs with unusual object counts for idx in .git/objects/pack/*.idx; do object_count=$(git verify-pack --stat-only "$idx" | grep "objects" | cut -d' ' -f1)
if [ "$object_count" -gt 100000 ]; then echo "⚠ Pack with many objects: $(basename "$idx") ($object_count objects)" elif [ "$object_count" -lt 10 ]; then echo "⚠ Pack with few objects: $(basename "$idx") ($object_count objects)" fi done
# Check for packs created in rapid succession ls -t .git/objects/pack/*.pack | head -5 | while read -r pack; do mtime=$(stat -c%Y "$pack" 2>/dev/null || stat -f%Sm -t "%s" "$pack") current_time=$(date +%s) age_minutes=$(( (current_time - mtime) / 60 ))
if [ "$age_minutes" -lt 5 ]; then echo "⚠ Recently created pack: $(basename "$pack") (${age_minutes} minutes ago)" fi done }
# Generate forensic report generate_forensic_report() { echo "Generating forensic pack analysis report..."
cat > forensic-pack-report.md << EOF# Forensic Pack File Analysis Report
Generated: $(date)Repository: $(basename "$(pwd)")Analyst: $(whoami)
## Executive SummaryThis report contains forensic analysis of Git pack files in the repository.
## Pack File TimelineEOF
analyze_pack_timeline >> forensic-pack-report.md
echo >> forensic-pack-report.md echo "## Pack Metadata" >> forensic-pack-report.md extract_pack_metadata >> forensic-pack-report.md
echo "## Anomalies Detected" >> forensic-pack-report.md detect_pack_anomalies >> forensic-pack-report.md
echo "## Conclusions" >> forensic-pack-report.md echo "Forensic analysis complete. Review anomalies above for potential security concerns." >> forensic-pack-report.md
echo "Forensic report generated: forensic-pack-report.md" }
# Run forensic analysis analyze_pack_timeline echo extract_pack_metadata echo detect_pack_anomalies echo generate_forensic_report}
# Usageforensic_pack_analysisAutomated Backup with Pack Verification:
Section titled “Automated Backup with Pack Verification:”# Automated backup system with pack verificationautomated_pack_backup() { echo "=== Automated Pack-Based Backup System ==="
# Configuration BACKUP_ROOT="/srv/backups/git" RETENTION_DAYS=30 VERIFY_BACKUPS=true
# Create verified pack backup create_verified_backup() { local repo_name="$1" local repo_path="$2"
echo "Creating verified backup for $repo_name..."
backup_dir="$BACKUP_ROOT/$repo_name" mkdir -p "$backup_dir"
timestamp=$(date +%Y%m%d-%H%M%S) backup_pack="$backup_dir/backup-$timestamp.pack"
# Create pack file cd "$repo_path" git pack-objects "$backup_pack" --all
# Verify pack integrity if [ "$VERIFY_BACKUPS" = true ]; then echo "Verifying backup integrity..."
if git verify-pack --stdin < "$backup_pack" >/dev/null 2>&1; then echo "✓ Backup verification successful"
# Create verification manifest cat > "${backup_pack}.manifest" << EOFRepository: $repo_nameCreated: $timestampVerified: $(date)SHA256: $(sha256sum "$backup_pack" | cut -d' ' -f1)Pack Stats: $(git verify-pack --stat-only --stdin < "$backup_pack")EOF
else echo "✗ Backup verification failed" rm -f "$backup_pack" return 1 fi fi
# Cleanup old backups cleanup_old_backups "$backup_dir"
echo "Verified backup created: $backup_pack" }
# Restore from verified backup restore_verified_backup() { local backup_pack="$1" local restore_path="$2"
echo "Restoring from verified backup..."
# Verify backup integrity before restore if [ ! -f "${backup_pack}.manifest" ]; then echo "No verification manifest found" return 1 fi
# Check manifest expected_sha=$(grep "SHA256:" "${backup_pack}.manifest" | cut -d' ' -f2) actual_sha=$(sha256sum "$backup_pack" | cut -d' ' -f1)
if [ "$expected_sha" != "$actual_sha" ]; then echo "Backup integrity check failed" return 1 fi
# Restore repository mkdir -p "$restore_path" cd "$restore_path"
git init git unpack-objects < "$backup_pack"
# Restore refs if available # This would require additional metadata
echo "✓ Verified backup restored successfully" }
# Cleanup old backups cleanup_old_backups() { local backup_dir="$1"
echo "Cleaning up old backups..."
# Remove backups older than retention period find "$backup_dir" -name "backup-*.pack" -mtime +$RETENTION_DAYS | while read -r old_backup; do echo "Removing old backup: $(basename "$old_backup")" rm -f "$old_backup" "${old_backup}.manifest" done
# Remove empty directories find "$BACKUP_ROOT" -type d -empty -delete }
# Monitor backup health monitor_backup_health() { echo "Monitoring backup system health..."
total_backups=0 valid_backups=0 total_size=0
find "$BACKUP_ROOT" -name "backup-*.pack" | while read -r backup; do ((total_backups++))
# Check size size=$(stat -f%z "$backup" 2>/dev/null || stat -c%s "$backup") ((total_size += size))
# Verify integrity if git verify-pack --stdin < "$backup" >/dev/null 2>&1; then ((valid_backups++)) else echo "✗ Corrupted backup: $(basename "$backup")" fi done
echo "Backup Health Summary:" echo " Total backups: $total_backups" echo " Valid backups: $valid_backups" echo " Total size: $((total_size / 1024 / 1024))MB"
validity_rate=$((valid_backups * 100 / total_backups)) echo " Validity rate: ${validity_rate}%"
if [ "$validity_rate" -lt 95 ]; then echo "⚠ Low backup validity rate detected" fi }
# Interactive backup management echo "Automated Pack Backup System Options:" echo "1. Create verified backup" echo "2. Restore from verified backup" echo "3. Monitor backup health"
read -p "Select option (1-3): " option
case "$option" in 1) read -p "Repository name: " repo_name read -p "Repository path: " repo_path create_verified_backup "$repo_name" "$repo_path" ;; 2) read -p "Backup pack file: " backup_pack read -p "Restore path: " restore_path restore_verified_backup "$backup_pack" "$restore_path" ;; 3) monitor_backup_health ;; esac}
# Usageautomated_pack_backup