git archive: Exporting a Project Snapshot
git archive exports a clean snapshot of your project at any commit, branch, or tag — without including the .git directory. The output is a standard tar or zip archive containing only the tracked files as they existed at that point in history. This makes git archive the right tool for release distributions, deployment packages, and CI/CD build artifacts where you want source files but not version-control metadata.
What git archive Does
When you run git archive, Git reads the tree object for the ref you specify and writes every file in that tree to an archive. The result is a reproducible snapshot: run it twice on the same ref and you get bit-for-bit identical archives. There is no .git directory, no staged changes, and no untracked files — only the committed, tracked content at that exact revision.
Basic Export: HEAD as tar.gz
Export the current HEAD to a compressed tarball
git archive --format=tar.gz HEAD > project.tar.gz # Verify contents (no .git directory) tar -tzf project.tar.gz | head -20
Archive contents — no .git directory
README.md package.json tsconfig.json src/ src/index.ts src/components/ src/components/Button.tsx src/utils/ src/utils/formatDate.ts tests/ tests/Button.test.tsx
Export a Specific Tag as a Zip
The most common production use case is exporting a tagged release. Specify the tag name as the treeish argument and choose your preferred format and output file.
Export tag v1.0.0 as zip and as tar.gz
# Export as zip (Windows-friendly) git archive v1.0.0 --format=zip -o release-v1.0.0.zip # Export as tar.gz (smaller, Linux/macOS-friendly) git archive v1.0.0 --format=tar.gz -o release-v1.0.0.tar.gz # Verify the tag version is captured inside unzip -p release-v1.0.0.zip package.json | grep '"version"' # "version": "1.0.0",
Adding a Prefix (Root Folder in the Archive)
By default the archive has no root folder — all files appear at the top level of the archive. Use --prefix to wrap everything inside a named directory. This is the standard convention for open-source releases: when the user extracts the archive they get a single folder named after the project and version.
Archive with a root directory prefix
git archive --prefix=myapp-1.0/ HEAD > myapp.tar.gz # With a specific tag and the -o flag git archive v2.3.1 --format=tar.gz --prefix=myapp-2.3.1/ -o myapp-2.3.1.tar.gz # Verify the prefix tar -tzf myapp-2.3.1.tar.gz | head -5
Archive contents with prefix
myapp-2.3.1/ myapp-2.3.1/README.md myapp-2.3.1/package.json myapp-2.3.1/src/ myapp-2.3.1/src/index.ts
Export a Subdirectory Only
You can archive just a subtree of the repository by appending a colon and path to your treeish argument. This is extremely useful in monorepos where you want to distribute only one package, or in CI pipelines that only need a subset of the source.
Export only the src/ subdirectory
# Export only src/ from HEAD, pipe into an output directory git archive HEAD:src/ | tar -xf - -C output/ # Export only docs/ from a specific tag git archive v1.0.0:docs/ --format=zip -o docs-v1.0.0.zip # Export a monorepo package with a prefix git archive HEAD:packages/ui/ --prefix=ui-library/ -o ui-library.tar.gz
Supported Archive Formats
Format | --format value | Typical Extension | Notes |
|---|---|---|---|
Uncompressed tar | tar | .tar | Largest, no compression |
Gzip-compressed tar | tar.gz | .tar.gz or .tgz | Most common on Linux and macOS |
Bzip2-compressed tar | tar.bz2 | .tar.bz2 | Better compression than gzip, slower |
Zip | zip | .zip | Native on Windows, no extra tools needed |
XZ-compressed tar | tar.xz | .tar.xz | Best compression ratio, slowest |
Export to a Remote Repository via SSH
If the remote server supports it, you can archive directly without cloning locally first. This is useful when the repository is too large to clone but you only need a snapshot.
Archive directly from a remote server
git archive --remote=git@server:repo.git HEAD > snap.tar
Controlling Archive Contents with .gitattributes
You can mark files or directories to be excluded from archives by adding export-ignore to your .gitattributes file. This lets you keep test files, CI configurations, and development tooling in the repository without shipping them in release archives.
.gitattributes — exclude development files from archives
# These paths will be omitted from git archive output tests/ export-ignore .github/ export-ignore *.test.ts export-ignore jest.config.js export-ignore .eslintrc.json export-ignore docker-compose.yml export-ignore
Build a clean distribution archive respecting export-ignore
git archive v1.0.0 --format=tar.gz --prefix=myapp-1.0.0/ -o dist.tar.gz # Verify: tests/ and .github/ do not appear tar -tzf dist.tar.gz | grep -E "tests/|.github/" # (no output — they were excluded)
CI/CD Release Script
Here is a complete release script that uses git archive to produce both a tar.gz and a zip, with a prefix, checksums, and proper file naming from the latest tag.
release.sh — automated release artifact creation
#!/bin/bash
set -euo pipefail
VERSION=$(git describe --tags --abbrev=0)
ARCHIVE_NAME="myapp-${VERSION}"
echo "Building release archives for ${VERSION}..."
mkdir -p dist/
# tar.gz for Linux/macOS
git archive "${VERSION}" --format=tar.gz --prefix="${ARCHIVE_NAME}/" -o "dist/${ARCHIVE_NAME}.tar.gz"
# zip for Windows
git archive "${VERSION}" --format=zip --prefix="${ARCHIVE_NAME}/" -o "dist/${ARCHIVE_NAME}.zip"
# Checksums
cd dist/
sha256sum "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
sha256sum "${ARCHIVE_NAME}.zip" > "${ARCHIVE_NAME}.zip.sha256"
cd ..
echo "Done. Archives in dist/:"
ls -lh dist/Comparison: git archive vs git bundle vs plain cp
Feature | git archive | git bundle | cp -r (manual copy) |
|---|---|---|---|
Includes .git directory | No | Yes (as pack objects) | Yes (full copy) |
Includes full commit history | No | Yes | Yes |
Output format | tar / zip | Custom bundle format | Directory |
Can git clone/fetch from it | No | Yes | Yes |
Suitable for end-user release | Yes | No | No |
Respects .gitattributes export-ignore | Yes | No | No |
Can export a single subdirectory | Yes (HEAD:src/) | Limited | Yes (cp src/ ...) |
Reproducible output | Yes | Yes | No |
File size | Smallest | Small (delta-compressed) | Largest |
Use Cases
Release distributions — ship v1.2.0.tar.gz to users without exposing your .git history
Deployment artifacts — upload a snapshot to a server that runs source directly
CI/CD packaging — create a deterministic build input artifact from a tagged commit
Submitting code — export to zip for sending via email or upload portals
Auditing — provide an auditor with an exact snapshot of code at a specific release