Skip to content

pack-objects Git Command Guide

The git pack-objects command reads a list of objects from standard input and creates one or more packed archives. Packed archives store objects as compressed wholes or as differences (deltas) from other objects, providing efficient storage and transfer mechanisms for Git repositories.

Terminal window
git pack-objects [-q | --progress | --all-progress] [--all-progress-implied]
[--no-reuse-delta] [--delta-base-offset] [--non-empty]
[--local] [--incremental] [--window=<n>] [--depth=<n>]
[--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
[--cruft] [--cruft-expiration=<time>]
[--stdout [--filter=<filter-spec>] | <base-name>]
[--shallow] [--keep-true-parents] [--[no-]sparse]
[--name-hash-version=<n>] [--path-walk] < <object-list>
OptionDescription
--stdoutWrite pack to stdout instead of file
--filter=<filter-spec>Filter objects (with —stdout)
<base-name>Base name for output pack files
OptionDescription
-q, --quietSuppress progress output
--progressShow progress on stderr
--all-progressShow progress for all operations
--all-progress-impliedShow all progress by default
OptionDescription
--no-reuse-deltaDon’t reuse existing deltas
--delta-base-offsetUse offset-based delta bases
--window=<n>Delta search window size (default 10)
--depth=<n>Maximum delta depth (default 50)
--max-pack-size=<n>Maximum pack file size
OptionDescription
--revsRead revs from stdin
--unpackedLimit to unpacked objects
--allInclude all objects
--localLimit to local objects
--incrementalCreate incremental pack
--non-emptyOnly create non-empty packs
OptionDescription
--keep-pack=<pack-name>Don’t repack kept pack
--cruftCreate cruft pack
--cruft-expiration=<time>Cruft expiration time
--shallowCreate shallow pack
--keep-true-parentsKeep true parents
--[no-]sparseUse sparse reachability
--name-hash-version=<n>Name hash version
--path-walkUse path-based traversal
Pack file (.pack):
├── Header (signature + version)
├── Object entries (compressed/delta)
└── Trailer (checksum)
Index file (.idx):
├── Fan-out table (object distribution)
├── Object names (SHA-1 hashes)
├── CRC32 checksums
├── Pack offsets
└── Trailer (checksum)
Base object: Complete compressed object
Delta object: Differences from base object
Delta chain: Obj1 ← Obj2 ← Obj3 (each smaller)
Benefits: Significant space savings
Drawbacks: Slower access for deep chains
Object ordering: Related objects grouped together
Delta selection: Choose optimal base objects
Compression: zlib compression of all data
Indexing: Fast lookup by SHA-1
Terminal window
# Create pack from object list
git rev-list --objects HEAD | git pack-objects my-pack
# Create pack with progress
git rev-list --objects HEAD | git pack-objects --progress my-pack
# Create pack to stdout
git rev-list --objects HEAD | git pack-objects --stdout > my-pack.pack
Terminal window
# Create incremental pack (only new objects)
git rev-list --objects HEAD --not --all | git pack-objects --incremental incremental-pack
# Pack only unpacked objects
git pack-objects --revs --unpacked < /dev/null
Terminal window
# Create pack with blob filter
git rev-list --objects HEAD --filter=blob:limit=1m | git pack-objects --stdout --filter=blob:limit=1m > filtered.pack
# Pack specific object types
git cat-file --batch-check --batch-all-objects | grep "^blob" | cut -d' ' -f1 | git pack-objects blob-pack
Terminal window
# Optimize delta compression
git rev-list --objects HEAD | git pack-objects --window=50 --depth=200 optimized-pack
# Disable delta reuse for fresh compression
git rev-list --objects HEAD | git pack-objects --no-reuse-delta fresh-pack
# Use offset-based deltas
git rev-list --objects HEAD | git pack-objects --delta-base-offset offset-pack
#!/bin/bash
# Complete repository pack optimization
optimize_repository_packs() {
echo "Optimizing repository pack files..."
# Analyze current pack state
echo "Current packs:"
ls -lh .git/objects/pack/*.pack
# Create optimized pack
git rev-list --all --objects | \
git pack-objects --window=250 --depth=250 --threads=0 optimized
# Replace old packs
mv .git/objects/pack/pack-*.pack .git/objects/pack/old/
mv optimized-*.pack .git/objects/pack/
mv optimized-*.idx .git/objects/pack/
# Update refs
git update-server-info
# Clean up
rm -rf .git/objects/pack/old/
echo "Pack optimization complete"
}
optimize_repository_packs
Terminal window
# Create packs with size limits
split_large_pack() {
local max_size="$1"
local base_name="$2"
git rev-list --all --objects | \
git pack-objects --max-pack-size="$max_size" "$base_name"
}
# Create 100MB packs
split_large_pack "100m" "split-pack"
# Verify pack sizes
ls -lh split-pack-*.pack
Terminal window
# Pack objects newer than specific time
pack_recent_objects() {
local days="$1"
# Find recent commits
git rev-list --since="$days days ago" --all --objects | \
git pack-objects "recent-${days}days"
echo "Created pack with objects from last $days days"
}
pack_recent_objects 30
Terminal window
# Create pack for specific branch
pack_branch_objects() {
local branch="$1"
# Get objects unique to branch
git rev-list "$branch" --not --all --objects | \
git pack-objects "branch-${branch#refs/heads/}"
echo "Created pack for branch: $branch"
}
pack_branch_objects "refs/heads/feature-x"
Terminal window
# Configure compression levels
git config pack.compression 9 # Maximum compression
git config pack.deltaCacheSize 512m # Delta cache size
git config pack.threads 0 # Auto-detect CPU threads
git config pack.windowMemory "512m" # Window memory limit
# Delta compression tuning
git config pack.window 10 # Delta search window
git config pack.depth 50 # Maximum delta depth
git config pack.deltaCacheLimit 1000 # Delta cache entries
Terminal window
# Optimize for large repositories
git config core.packedGitLimit 256m # Packed git limit
git config core.packedGitWindowSize 16m # Window size
git config pack.packSizeLimit 100m # Maximum pack size
# Memory optimization
git config pack.windowMemory "1024m" # Increase window memory
git config pack.deltaCacheSize "1024m" # Increase delta cache
# Parallel processing
git config pack.threads 4 # Use 4 threads
Terminal window
# Optimize pack file layout
git config pack.writeBitmapIndex true # Write bitmap indexes
git config pack.writeReverseIndex true # Write reverse indexes
git config pack.useSparse true # Use sparse reachability
# Cruft pack configuration
git config gc.cruftPacks true # Enable cruft packs
git config gc.maxCruftSize "1G" # Maximum cruft size
#!/bin/bash
# Automated pack file maintenance
maintain_pack_files() {
echo "Performing pack file maintenance..."
# Repack loose objects
git pack-objects --revs --unpacked < /dev/null
# Repack all objects
if [ $(ls .git/objects/pack/*.pack 2>/dev/null | wc -l) -gt 5 ]; then
git repack -a -d --window=250 --depth=250
fi
# Expire old reflog entries
git reflog expire --expire=90.days.ago --all
# Clean up
git gc --prune=2.weeks.ago
echo "Pack maintenance complete"
}
# Run weekly
maintain_pack_files
Terminal window
# Optimize repository for serving
server_pack_optimization() {
local repo_path="$1"
cd "$repo_path"
# Create bitmap index for fast clones
git pack-objects --all --stdout | cat > /dev/null # Force packing
git repack -a -d --write-bitmap-index
# Update server info
git update-server-info
# Create multi-pack-index if needed
if [ $(ls .git/objects/pack/*.pack | wc -l) -gt 10 ]; then
git multi-pack-index write --bitmap
fi
echo "Server optimization complete for $repo_path"
}
server_pack_optimization "/srv/git/my-repo.git"
Terminal window
# Create optimized backup packs
create_backup_pack() {
local backup_name="$1"
echo "Creating backup pack: $backup_name"
# Include all reachable objects
git rev-list --all --objects | \
git pack-objects --all-progress --window=250 --depth=250 "$backup_name"
# Create verification file
sha256sum "$backup_name-"*.pack > "$backup_name.sha256"
echo "Backup pack created with verification"
}
create_backup_pack "full-backup-$(date +%Y%m%d)"
Terminal window
# Debug pack creation
GIT_TRACE=1 git rev-list --objects HEAD | git pack-objects test-pack
# Check object validity
git rev-list --objects HEAD | while read sha type; do
if ! git cat-file -t "$sha" >/dev/null 2>&1; then
echo "Invalid object: $sha"
fi
done
# Verify pack integrity
git verify-pack test-pack-*.pack
Terminal window
# Monitor memory usage
/usr/bin/time -v git pack-objects --window=250 --depth=250 large-pack < objects.txt
# Reduce memory usage
git pack-objects --window=50 --depth=100 --max-pack-size=500m memory-efficient-pack < objects.txt
# Use system limits
ulimit -v $((1024*1024*1024)) # 1GB memory limit
Terminal window
# Profile pack creation
time git pack-objects --progress --all-progress large-pack < objects.txt
# Optimize for speed
git pack-objects --window=10 --depth=10 --threads=1 fast-pack < objects.txt
# Check system resources
free -h
iostat -x 1 5
Terminal window
# Analyze delta effectiveness
git verify-pack large-pack-*.pack | \
awk '/delta/ {delta++} /blob|tree|commit|tag/ {total++} END {print "Deltas:", delta, "Total:", total, "Ratio:", delta/total}'
# Recreate with different delta settings
git pack-objects --no-reuse-delta --window=100 --depth=100 re-delta-pack < objects.txt
# Check delta chain lengths
git verify-pack large-pack-*.pack | grep "chain length" | sort -n
Terminal window
# Analyze pack file sizes
ls -lh .git/objects/pack/*.pack | sort -k5 -h
# Check object distribution
git verify-pack .git/objects/pack/*.pack | \
cut -d' ' -f1 | \
xargs -n1 git cat-file -t | \
sort | uniq -c | sort -nr
# Optimize for size
git pack-objects --window=500 --depth=500 --compression=9 size-optimized-pack < objects.txt
#!/bin/bash
# Migrate repository with optimized packs
migrate_repository() {
local source_repo="$1"
local target_repo="$2"
echo "Migrating $source_repo to $target_repo"
# Clone bare repository
git clone --bare "$source_repo" "$target_repo"
cd "$target_repo"
# Optimize pack files for migration
git repack -a -d --window=250 --depth=250 --threads=0
# Create bitmap index for fast access
git pack-objects --all --stdout --progress | cat > /dev/null
# Generate multi-pack-index
git multi-pack-index write --bitmap
# Update server info
git update-server-info
# Verify migration
git fsck --full
echo "Repository migration complete"
cd -
}
migrate_repository "/old/repo" "/new/repo"
Terminal window
# Optimize large enterprise repository
enterprise_repo_optimization() {
local repo_path="$1"
cd "$repo_path"
echo "Optimizing large repository: $(basename "$repo_path")"
# Pre-optimization analysis
echo "Before optimization:"
du -sh .git/
echo "Pack files: $(ls .git/objects/pack/*.pack | wc -l)"
echo "Loose objects: $(find .git/objects -type f -name '[0-9a-f]*' | wc -l)"
# Aggressive repacking
git repack -a -d -f --window=500 --depth=500 --threads=0
# Create additional optimization packs
git pack-objects --revs --unpacked < /dev/null
# Generate bitmap indexes
git pack-objects --all --stdout --progress | cat > /dev/null
# Multi-pack-index for many packs
git multi-pack-index write --bitmap
# Post-optimization analysis
echo "After optimization:"
du -sh .git/
echo "Pack files: $(ls .git/objects/pack/*.pack | wc -l)"
# Verify integrity
git fsck --full --strict
echo "Enterprise optimization complete"
}
enterprise_repo_optimization "/repos/large-project"
Terminal window
# Create incremental backup packs
incremental_backup() {
local backup_dir="$1"
local last_backup="${2:-HEAD}"
mkdir -p "$backup_dir"
# Get objects since last backup
git rev-list --objects "$last_backup..HEAD" | \
git pack-objects "$backup_dir/incremental-$(date +%Y%m%d-%H%M%S)"
# Update last backup reference
git update-ref "refs/backup/last" HEAD
# Create backup manifest
cat > "$backup_dir/manifest.txt" << EOF
Backup: $(date)
From: $last_backup
To: $(git rev-parse HEAD)
Objects: $(git rev-list --count "$last_backup..HEAD")
Size: $(ls -lh "$backup_dir"/incremental-*.pack | awk '{sum += $5} END {print sum}')
EOF
echo "Incremental backup created in $backup_dir"
}
incremental_backup "/backups/my-repo" "$(git rev-parse refs/backup/last 2>/dev/null || echo HEAD~30)"

What’s the difference between pack-objects and git gc?

Section titled “What’s the difference between pack-objects and git gc?”

git gc uses pack-objects internally for repacking; pack-objects provides direct control over pack creation parameters and output.

How do I create a pack file from specific objects?

Section titled “How do I create a pack file from specific objects?”

Pipe object list to git pack-objects: echo “object1 object2” | git pack-objects my-pack

—window sets objects considered for delta base selection; —depth limits delta chain length. Higher values improve compression but increase time/memory.

Yes, reads object list from stdin. Use git rev-list —objects to generate input, or specify objects manually.

Forces fresh delta computation instead of reusing existing deltas. Slower but can achieve better compression.

Use git verify-pack pack-file.pack to check pack integrity and analyze object sizes and delta chains.

Can pack-objects create multiple pack files?

Section titled “Can pack-objects create multiple pack files?”

Yes, with —max-pack-size option to split large packs into smaller files for better management.

What’s the relationship between pack-objects and pack files?

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

pack-objects creates .pack and .idx files; pack files store compressed objects, indexes provide fast lookup.

How do I optimize pack creation for speed?

Section titled “How do I optimize pack creation for speed?”

Use lower —window/—depth values, increase —threads, reduce —max-pack-size for parallel processing.

Can pack-objects work in bare repositories?

Section titled “Can pack-objects work in bare repositories?”

Yes, operates on Git objects regardless of working directory. Essential for server-side pack optimization.

What’s the difference between incremental and full packs?

Section titled “What’s the difference between incremental and full packs?”

Incremental packs contain only new objects; full packs contain all objects. Incremental packs are smaller but require base packs.

How do I handle pack-objects memory issues?

Section titled “How do I handle pack-objects memory issues?”

Reduce —window/—depth, increase system memory limits, use —max-pack-size to split large operations.

Applications of the git pack-objects command

Section titled “Applications of the git pack-objects command”
  1. Repository Optimization: Create efficient pack files for storage and transfer optimization
  2. Backup Creation: Generate compressed archives of repository objects for backup purposes
  3. Migration Support: Prepare repositories for transfer with optimized pack structures
  4. Server Performance: Create pack files optimized for Git server operations and cloning
  5. Storage Management: Maintain efficient object storage through intelligent packing strategies
  6. Incremental Operations: Support incremental backup and synchronization workflows