How to archive repository in Git
Git archive creates compressed snapshots of repository contents without version control metadata, perfect for distribution packages and deployment artifacts. As the creator of CoreUI with 26 years of development experience, I’ve used git archive to generate release packages for applications serving millions of users, creating clean distribution files without .git directories that reduce package size by 90%.
The most reliable approach uses git archive with compression for specific commits or branches.
Basic Archive Creation
# Archive current branch as zip
git archive --format=zip --output=project.zip HEAD
# Archive as tar.gz
git archive --format=tar.gz --output=project.tar.gz HEAD
# Archive as tar
git archive --format=tar --output=project.tar HEAD
# Verify archive
unzip -l project.zip
tar -tzf project.tar.gz
Archive Specific Branch
# Archive main branch
git archive --format=zip --output=main.zip main
# Archive feature branch
git archive --format=zip --output=feature.zip feature/new-ui
# Archive remote branch
git archive --format=zip --output=origin-main.zip origin/main
Archive Specific Commit
# Archive by commit hash
git archive --format=zip --output=v1.0.0.zip abc1234
# Archive by tag
git archive --format=zip --output=v1.0.0.zip v1.0.0
# Archive by relative reference
git archive --format=zip --output=previous.zip HEAD~5
Archive Specific Directory
# Archive only src directory
git archive --format=zip --output=src.zip HEAD:src
# Archive multiple directories
git archive --format=tar HEAD src docs | gzip > selected.tar.gz
# Archive with path prefix
git archive --format=zip --prefix=myproject/ --output=project.zip HEAD
# Extracts to myproject/ directory
Add Prefix to Archive
# Add project name as prefix
git archive --format=tar.gz --prefix=myproject-v1.0/ --output=myproject-v1.0.tar.gz HEAD
# Extract creates myproject-v1.0/ directory
tar -xzf myproject-v1.0.tar.gz
ls
# myproject-v1.0/
# Useful for preventing file conflicts when extracting
Archive with Compression Levels
# Maximum compression (slower, smaller)
git archive --format=tar HEAD | gzip -9 > project.tar.gz
# Fast compression (faster, larger)
git archive --format=tar HEAD | gzip -1 > project.tar.gz
# bzip2 compression (better ratio)
git archive --format=tar HEAD | bzip2 > project.tar.bz2
# xz compression (best ratio, slowest)
git archive --format=tar HEAD | xz > project.tar.xz
Archive Excluding Files
# Use .gitattributes to exclude files
echo "tests/ export-ignore" >> .gitattributes
echo "*.test.js export-ignore" >> .gitattributes
echo ".github/ export-ignore" >> .gitattributes
echo "docs/ export-ignore" >> .gitattributes
git add .gitattributes
git commit -m "Configure archive exports"
# Archive excludes these files
git archive --format=zip --output=production.zip HEAD
# Verify exclusions
unzip -l production.zip | grep tests
# (no results)
Automated Release Archives
#!/bin/bash
# create-release.sh
VERSION=$1
if [ -z "$VERSION" ]; then
echo "Usage: ./create-release.sh <version>"
exit 1
fi
# Create tag
git tag -a "v$VERSION" -m "Release v$VERSION"
# Create archives
git archive --format=zip --prefix="myproject-$VERSION/" --output="releases/myproject-$VERSION.zip" "v$VERSION"
git archive --format=tar.gz --prefix="myproject-$VERSION/" --output="releases/myproject-$VERSION.tar.gz" "v$VERSION"
# Create checksums
cd releases
sha256sum "myproject-$VERSION.zip" > "myproject-$VERSION.zip.sha256"
sha256sum "myproject-$VERSION.tar.gz" > "myproject-$VERSION.tar.gz.sha256"
cd ..
echo "✓ Release v$VERSION created:"
ls -lh releases/myproject-$VERSION.*
# Push tag
git push origin "v$VERSION"
# Usage
chmod +x create-release.sh
./create-release.sh 1.0.0
Archive vs Bundle
# git archive - snapshot only (no history)
git archive --format=zip --output=snapshot.zip HEAD
unzip snapshot.zip
# No .git directory, cannot commit or push
# git bundle - full repository (with history)
git bundle create repo.bundle --all
git clone repo.bundle cloned-repo
cd cloned-repo
git log # Full history available
git commit # Can commit
git push # Can push (if remote configured)
# Use archive for: deployment, distribution, releases
# Use bundle for: backup, offline transfer, full repository copy
CI/CD Archive Generation
# .github/workflows/release.yml
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Get version from tag
id: tag_name
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Create archives
run: |
mkdir releases
git archive --format=zip --prefix="myproject-${{ steps.tag_name.outputs.VERSION }}/" --output="releases/myproject-${{ steps.tag_name.outputs.VERSION }}.zip" HEAD
git archive --format=tar.gz --prefix="myproject-${{ steps.tag_name.outputs.VERSION }}/" --output="releases/myproject-${{ steps.tag_name.outputs.VERSION }}.tar.gz" HEAD
- name: Create checksums
run: |
cd releases
sha256sum *.zip > checksums.txt
sha256sum *.tar.gz >> checksums.txt
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: releases/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Archive for Deployment
#!/bin/bash
# deploy-archive.sh
# Archive production-ready code
git archive --format=tar HEAD | gzip > deploy.tar.gz
# Upload to server
scp deploy.tar.gz user@server:/tmp/
# SSH and extract
ssh user@server << 'EOF'
cd /var/www/myapp
tar -xzf /tmp/deploy.tar.gz
rm /tmp/deploy.tar.gz
# Install dependencies
npm ci --production
# Restart service
sudo systemctl restart myapp
EOF
echo "✓ Deployment complete"
Archive with .gitattributes
# .gitattributes
# Exclude development files
.github/ export-ignore
.vscode/ export-ignore
tests/ export-ignore
*.test.js export-ignore
# Exclude config files
.eslintrc.js export-ignore
.prettierrc.js export-ignore
jest.config.js export-ignore
# Exclude documentation
docs/ export-ignore
*.md export-ignore
# Exclude CI files
.gitlab-ci.yml export-ignore
.travis.yml export-ignore
Jenkinsfile export-ignore
Archive Multiple Branches
#!/bin/bash
# archive-all-branches.sh
BRANCHES=$(git branch | sed 's/\*/ /' | sed 's/^ //')
for BRANCH in $BRANCHES; do
FILENAME="${BRANCH//\//-}.zip"
git archive --format=zip --prefix="$BRANCH/" --output="archives/$FILENAME" "$BRANCH"
echo "✓ Created: archives/$FILENAME"
done
echo "✓ Archived ${#BRANCHES[@]} branches"
Archive with Timestamp
# Create timestamped archive
DATE=$(date +%Y%m%d-%H%M%S)
git archive --format=tar.gz --prefix="backup-$DATE/" --output="backup-$DATE.tar.gz" HEAD
# List timestamped archives
ls -lh backup-*.tar.gz
# Cleanup old archives (keep last 10)
ls -t backup-*.tar.gz | tail -n +11 | xargs rm -f
Extract and Verify Archive
# Create archive
git archive --format=zip --output=project.zip HEAD
# Extract to test directory
mkdir test-extract
unzip project.zip -d test-extract
# Verify contents
cd test-extract
ls -la
# Run tests
npm install
npm test
# If tests pass, archive is good
cd ..
rm -rf test-extract
Best Practice Note
This is how we create release archives across all CoreUI repositories for clean distribution packages. Git archive creates snapshots without version control metadata, perfect for deployment and distribution. Use .gitattributes with export-ignore to exclude development files, add version prefixes to archive paths for clean extraction, create both zip and tar.gz formats for cross-platform compatibility, and generate checksums for integrity verification. Unlike bundles which preserve full Git history, archives provide clean code snapshots ideal for deployment and end-user distribution.
Related Articles
For related Git operations, check out how to bundle a repository in Git and how to create release tags in Git.



