During software development and project delivery, we often need to package source code while excluding directories like .git/ and node_modules.

The common approach is to manually select the required files for packaging.
Or, delete unwanted files first, then package the entire folder.
Both methods require manual filtering.

So, is there an elegant way to conveniently package project source code?

TL;DR

Use the git archive command for packaging, which automatically excludes the .git/ directory and files listed in .gitignore.

Add a command called Git-ArchiveProject to your Windows PowerShell Profile.
When you use this command in a project directory, it packages the entire project and outputs a file named yyyyMMdd-projectName.zip in the parent directory.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Create a compressed archive of the current working directory, output to parent directory
# The archive contains a top-level directory named after the current working directory
# The output archive is named yyyyMMdd-projectName.zip
function Git-ArchiveProject {
    # Get the current working directory name as the project name
    $projectName = Split-Path -Path (Get-Location) -Leaf

    $date = Get-Date -Format "yyyyMMdd"
    $outputFile = "../$date-$projectName.zip"

    git archive --format=zip --prefix="$projectName/" --output="$outputFile" HEAD

    if ($LASTEXITCODE -eq 0) {
        Write-Host "Success: $outputFile" -ForegroundColor Green
    } else {
        Write-Host "Fail: $outputFile" -ForegroundColor Red
    }
}

If you’re using Linux, you can write a similar script in Bash.

What is Git Archive?

git archive is a command provided by Git to create source code archive files (like .zip or .tar) from a Git repository while automatically excluding version control information. It’s primarily used for:

  • Creating source code packages for releases
  • Distributing project code to users who don’t need access to version history
  • Deploying applications to server environments

The main feature of git archive is that it only packages files committed to the repository and automatically excludes the .git directory and files specified in .gitignore.

Basic Usage

Creating ZIP Format Archives

1
git archive --format=zip --output=project.zip HEAD

Creating Compressed TAR Files

1
git archive --format=tar HEAD | gzip > project.tar.gz

Key Parameters Explained

1. Format Specification: --format

1
git archive --format=zip HEAD

Supported formats primarily include zip and tar. If not specified, Git will guess the format based on the output filename.

2. Output Location: --output

1
git archive --format=zip --output=../releases/project.zip HEAD

Specifies the save path and filename for the archive file.

3. Adding a Prefix: --prefix

1
git archive --format=zip --prefix=project-name/ --output=project.zip HEAD

Adds a directory prefix to all files in the archive, creating a top-level directory.

4. Version Specification

1
2
3
4
5
6
7
8
# Archive a specific tag version
git archive --format=zip v1.0.0 --output=release-1.0.0.zip

# Archive the latest commit of a specific branch
git archive --format=zip feature/new-ui --output=new-ui.zip

# Archive a specific commit
git archive --format=zip 5a8e2 --output=specific-commit.zip

5. Directory-Limited Archiving

1
git archive --format=zip HEAD:src --output=src.zip

Archives only a specific subdirectory of the repository.

6. Remote Repository: --remote

1
git archive --remote=origin --format=zip master > remote-master.zip

Creates an archive from a remote repository (requires remote server support).

Archive File Scope Explanation

Understanding what files git archive includes is important:

  1. Committed files: Will be archived (latest committed version)
  2. Modified but uncommitted files: Will NOT be archived!
  3. Staged but uncommitted files: Will NOT be archived!
  4. Untracked files: Will NOT be archived!
  5. Ignored files: Will NOT be archived!

Special note: git archive cannot include the .git directory by design, with the purpose of creating clean archives without version control information.

Comparison with Other Packaging Methods

Compared to manual packaging with tools like 7-Zip or WinRAR, git archive offers these advantages:

  1. Automatic exclusion of non-tracked files: No need to manually specify exclusion rules
  2. Follows .gitignore rules: Maintains consistency with version control
  3. Excludes the .git directory: Prevents leakage of version control information
  4. Can specify any historical version: Makes it easy to create archives of specific versions

Conclusion

Not every client uses Git, and many private projects cannot be conveniently uploaded online.
For small projects, zip archives are the most direct delivery method.

Previously, I would manually select files for packaging, which was inefficient.
Later, I used 7z’s exclude command parameters to exclude some files, but that was still a bit cumbersome.

Since discovering the git archive command, project delivery has become much more convenient.