在软件开发和项目交付过程中,我们经常需要将源码打包,但打包文件中我们又需要排除 .git/node_modules 等目录。

一般做法是,手动勾选需要的文件,进行打包。
或者,把不想打包的文件先删除,再打包整个文件夹。
这两种方法,都需要人为的筛选。

那么,有什么优雅的办法,方便打包项目源码呢?

太长不看版

使用 git archive 命令打包,它会自动排除 .git/ ,以及 .gitignore 中的文件。

在你的 Windows 系统中的 PowerShell Profile 添加一个命令,Git-ArchiveProject
当你在项目目录使用这个命令,它就会打包整个项目,并在项目的上一层目录,输出一个名为 yyyyMMdd-projectName.zip 的打包文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 创建当前工作目录的压缩包,输出到上一级目录
# 压缩包中有一个顶级目录,名为当前的工作目录
# 输出的压缩包,命名为 yyyyMMdd-projectName.zip
function Git-ArchiveProject {
    # 获取当前工作目录的名称作为项目名称
    $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
    }
}

如果你用的是 Linux ,可以用 Bash 写一个类似的脚本。

什么是 Git Archive?

git archive 是 Git 提供的一个命令,用于从 Git 仓库创建源代码归档文件(如 .zip 或 .tar),同时自动排除版本控制相关的信息。它主要用于:

  • 创建发布版本的源代码包
  • 分发项目代码给无需访问版本历史的用户
  • 部署应用到服务器环境

git archive 的主要特点是只打包已提交到仓库的文件,并自动排除 .git 目录和 .gitignore 中指定的文件。

基本用法

创建 ZIP 格式归档

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

创建压缩的 TAR 文件

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

关键参数详解

1. 格式指定: --format

1
git archive --format=zip HEAD

支持的格式主要有 ziptar。如果未指定,Git 会根据输出文件名猜测格式。

2. 输出位置: --output

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

指定归档文件的保存路径和文件名。

3. 添加前缀: --prefix

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

在归档的所有文件前添加目录前缀,创建顶级目录。

4. 版本指定

1
2
3
4
5
6
7
8
# 归档特定标签版本
git archive --format=zip v1.0.0 --output=release-1.0.0.zip

# 归档特定分支最新提交
git archive --format=zip feature/new-ui --output=new-ui.zip

# 归档特定提交
git archive --format=zip 5a8e2 --output=specific-commit.zip

5. 限定目录归档

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

只归档仓库中的特定子目录。

6. 远程仓库: --remote

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

从远程仓库创建归档(需要远程服务器支持)。

归档文件范围说明

了解 git archive 归档的文件范围非常重要:

  1. 已提交文件:会被归档(最新提交版本)
  2. 已修改但未提交的文件:不会被归档!
  3. 已暂存但未提交的文件:不会被归档!
  4. 未跟踪的文件:不会被归档!
  5. 已忽略的文件:不会被归档!

特别注意git archive 无法包含 .git 目录,这是设计使然,目的是创建不包含版本控制信息的干净归档。

与其他打包方式的对比

与使用 7-Zip、WinRAR 等工具手动打包相比,git archive 具有以下优势:

  1. 自动排除非跟踪文件:无需手动指定排除规则
  2. 遵循 .gitignore 规则:保持与版本控制一致
  3. 不包含 .git 目录:避免版本控制信息泄露
  4. 可指定任意历史版本:便于创建特定版本的归档

结语

不是每个客户都会使用 Git ,许多私有项目也不方便上传到网上。
对于小型项目, zip 压缩包是最直接的交付方式。

以前我都是手动选择文件打包,实在低效。
后面用 7z 的 exclude 命令参数排除一些文件,也还是有点儿麻烦。

直到发现了 git archive 命令,项目交付方便多了。