- Developers who already know basic commit and branch actions
- Readers who want to understand command boundaries and risk
Command Reference
git-archive Tutorial
Explains how to use git-archive to export an archive from a commit or tree object.
- A basic mental model of worktree, index, and commits
- Comfort reading `git status` and a small commit graph
- Using local cleanup commands on already shared history
- Continuing to rewrite before confirming a recovery path
The short version
git-archive is used to export an archive from a commit or tree object.
When it is a good fit
- when you need to export an archive from a commit or tree object
- when you want this step to be repeatable instead of ad hoc
- when you need a clearer mental model of what Git is recording or updating
Basic example
git archive --format=zip HEAD > source.zip
What to watch most closely
These commands often change repository layout or collaboration patterns, so align on conventions first.
A safer working habit
Test the flow in a small sandbox repository before rolling it into the main repo or automation.
Useful angles for understanding it
- Distribute code or history
- Reduce clone or checkout scope
- Coordinate multi-repo or multi-worktree setups
Related reading
Read it alongside git status, git log, and git show so it is easier to see how the command changes history, refs, the index, or the working tree.
What problem this command solves in a workflow
git archive exports a code snapshot from a specific commit or tree object into a tar or zip file, excluding the .git directory. Think of it as the tool for "how do I deliver clean source code to users who do not need Git history?"
Typical use cases
- When publishing a release, use
git archiveto export a clean code snapshot for users to download. - Package a specific tag or commit as a zip file for scenarios that only need the source code, not the version history.
- In CI/CD pipelines, use archive to generate release artifacts without including the
.gitdirectory in the final deliverable.
Diagram view
Special cases and boundaries
- The exported archive does not contain a
.gitdirectory, so the recipient cannot use it as a Git repository. export-ignorerules in.gitattributescontrol which files are excluded from the archive, useful for omitting test files or build configs.- Untracked files are never included in the archive — only Git-tracked files are exported.
- Use
--prefixto add a directory prefix to archived files, so they extract into a specified subdirectory.
Export specific paths with prefix
The --prefix flag adds a directory wrapper around all archived files, which is essential for clean extraction:
# Creates my-project-v1.0/ containing all files
git archive --format=tar --prefix=my-project-v1.0/ v1.0 | gzip > my-project-v1.0.tar.gz
# ZIP with prefix
git archive --format=zip --prefix=release-2.0/ v2.0 -o release-2.0.zip
Without --prefix, files extract directly into the current directory, which can be messy.
Archive a subdirectory only
# Export only the docs/ directory
git archive --format=zip HEAD:docs/ -o docs-only.zip
# Export src/ with a custom prefix
git archive --format=tar --prefix=source-code/ HEAD -- src/ | gzip > source-code.tar.gz
The HEAD:path/ syntax lets you specify any tree path as the archive root.
Format comparison: tar vs zip
| Feature | tar | zip |
|---|---|---|
| Compression | Requires gzip/bzip2/xz (` | gzip`) |
| Preserves permissions | Yes | Limited |
| Preserves symlinks | Yes | Yes |
| Windows compatibility | Requires extraction tools | Native support |
| Streamable | Yes (piped) | No (needs file) |
| Archive size | Slightly smaller | Slightly larger |
When to use tar
# Best for: Linux/Unix deployment, CI pipelines
git archive --format=tar --prefix=deploy/ main | gzip > deploy.tar.gz
git archive --format=tar.gz --prefix=deploy/ main -o deploy.tar.gz # Git 2.30+
When to use zip
# Best for: sharing with Windows users, GitHub-style releases
git archive --format=zip --prefix=release/ v1.0 -o release-v1.0.zip
Note: Git also supports tar.gz and tar.bz2 as format names directly (Git 2.30+):
git archive --format=tar.gz HEAD -o source.tar.gz
git archive --format=tar.bz2 HEAD -o source.tar.bz2
Exclude files via export-ignore in .gitattributes
Use .gitattributes to control which files are excluded from archives without affecting the repository:
# .gitattributes
tests/ export-ignore
.github/ export-ignore
.gitlab-ci.yml export-ignore
*.test.js export-ignore
docs/internal/ export-ignore
How it works
- Files matching
export-ignoreare included ingit status,git log, and all Git operations - They are only excluded when creating an archive with
git archive - This is different from
.gitignore— the files are still tracked by Git
Verify what's in an archive
# List archive contents without extracting
tar -tzf release.tar.gz
unzip -l release.zip
# Compare with and without export-ignore
git archive --format=tar HEAD | tar -t
git archive --format=tar HEAD -- . | tar -t
Tag and revision export
Export by tag
# Clean release from a tag
git archive --format=zip --prefix=myapp-1.0/ v1.0 -o myapp-1.0.zip
Export by commit hash
git archive --format=tar --prefix=snapshot/ abc1234 -o snapshot.tar
Export by branch
git archive --format=zip --prefix=latest/ main -o latest.zip
Export with version information
# Using HEAD with a specific tag as version
VERSION=$(git describe --tags --always --dirty)
git archive --format=tar.gz --prefix="myapp-${VERSION}/" HEAD -o "myapp-${VERSION}.tar.gz"
Export from a specific date
# Archive the state of main as it was on a specific date
git archive --format=zip --prefix=snapshot/ "$(git rev-list -n1 --before='2024-06-01' main)" -o snapshot.zip
Remote archive
Git supports fetching archives from remote repositories without cloning:
# Archive from a remote (requires server support for upload-archive)
git archive --remote=git@github.com:user/repo.git --format=zip HEAD -o remote-archive.zip
# Archive a specific tag from remote
git archive --remote=git@github.com:user/repo.git v2.0 -o release.zip
Configure remote archive
# Set up a named remote for archiving
git remote add releases git@github.com:org/releases.git
git archive --remote=releases --format=tar.gz main | tar -tz
Note: Remote archive requires the server to have upload-archive enabled. GitHub does not support this, but self-hosted Git servers often do.
CI integration: auto-generate tarballs
GitHub Actions example
# .github/workflows/release.yml
name: Create Release Archive
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create archive
run: |
VERSION=${GITHUB_REF#refs/tags/}
git archive --format=tar.gz --prefix="${{ github.event.repository.name }}-${VERSION}/" \
"${VERSION}" -o "${{ github.event.repository.name }}-${VERSION}.tar.gz"
- name: Upload release asset
uses: softprops/action-gh-release@v1
with:
files: "*.tar.gz"
GitLab CI example
# .gitlab-ci.yml
archive:
stage: package
rules:
- if: $CI_COMMIT_TAG
script:
- git archive --format=tar.gz --prefix="app-${CI_COMMIT_TAG}/" "$CI_COMMIT_TAG" -o "app-${CI_COMMIT_TAG}.tar.gz"
artifacts:
paths:
- "*.tar.gz"
Makefile integration
VERSION := $(shell git describe --tags --always --dirty)
dist:
git archive --format=tar.gz --prefix="project-$(VERSION)/" HEAD -o "project-$(VERSION).tar.gz"
@echo "Created project-$(VERSION).tar.gz"
.PHONY: dist