7z源码版本:2026年2月的,来源是:https://www.7-zip.org/
为 7-Zip 26.00 GUI 版本添加了 .gitignore 文件过滤支持功能。用户在压缩文件时,可以选择使用 .gitignore 规则自动排除指定的文件和目录。
- 在压缩对话框中添加 "Use .gitignore" 复选框选项
- 默认不勾选,用户可手动启用
- 勾选时自动检测源目录中是否存在
.gitignore文件 - 若
.gitignore文件不存在,显示警告提示并自动取消勾选 - 支持从父目录右键压缩文件夹时正确应用过滤规则
- 支持基本的 gitignore 模式匹配:
- 简单文件/目录名匹配(如
testpath) - 通配符匹配(如
*.log) - 以
/开头的根目录相对路径 - 取反模式(
!pattern)
- 简单文件/目录名匹配(如
路径: CPP/7zip/UI/GUI/CompressDialogRes.h
修改内容:
- 添加控件资源 ID 定义
// Gitignore option
#define IDX_COMPRESS_USE_GITIGNORE 4020路径: CPP/7zip/UI/GUI/CompressDialog.rc
修改内容:
- 增加分组框高度(从64改为80)
- 添加 "Use .gitignore" 复选框控件
路径: CPP/7zip/UI/GUI/CompressDialog.h
修改内容:
- 在
NCompressDialog::CInfo结构体中添加UseGitignore成员变量 - 在
CCompressDialog类中添加SourcePath成员变量(用于存储源文件路径)
路径: CPP/7zip/UI/GUI/CompressDialog.cpp
修改内容:
- 添加
#include "../../../Windows/FileFind.h"头文件 - 在
OnInit()中初始化 gitignore 复选框状态 - 在
OnButtonClicked()中添加复选框点击处理逻辑:- 检测源目录是否存在
.gitignore文件 - 不存在时显示警告并取消勾选
- 检测源目录是否存在
- 在
OnOK()中保存 gitignore 选项状态到Info.UseGitignore
路径: CPP/7zip/UI/Common/Update.h
修改内容:
- 在
CUpdateOptions结构体中添加UseGitignore成员变量 - 构造函数中初始化为
false
路径: CPP/7zip/UI/GUI/UpdateGUI.cpp
修改内容: 添加以下核心函数实现 gitignore 功能:
// 读取 .gitignore 文件内容
static bool ReadGitignoreFile(const FString &gitignorePath, UStringVector &patterns)
// 将 gitignore 模式添加到排除过滤器
static void AddGitignoreExcludeToCensor(NWildcard::CCensor &censor, const UString &pattern)
// 应用 gitignore 规则到文件过滤器
static void ApplyGitignoreRules(NWildcard::CCensor &censor, const FString &gitignorePath)在 UpdateGUI() 函数中添加 gitignore 处理逻辑:
- 检测源目录路径(支持目录和文件两种情况)
- 查找并读取
.gitignore文件 - 将排除规则添加到
CCensor过滤器
在 ShowDialog() 函数中传递源路径给对话框:
dialog.SourcePath = cp.Path;7-Zip GUI 采用以下架构:
- 7zFM.exe - 文件管理器,提供用户界面和文件操作入口
- 7zG.exe - GUI 压缩程序,接收参数后显示压缩对话框并执行压缩
流程:
- 用户在 7zFM 中选择文件并点击压缩
- 7zFM 通过
CompressFiles()启动 7zG.exe 进程 - 7zG 显示压缩对话框,用户配置选项
- 用户点击确定后,设置传递给
UpdateGUI()执行压缩
7-Zip 使用 NWildcard::CCensor 类进行文件过滤:
CensorPaths- 存储待处理的文件路径列表Pairs- 按 Prefix 分组的路径规则IncludeItems/ExcludeItems- 包含/排除规则列表
gitignore 规则通过 AddPreItem(false, pattern, props) 添加为排除模式,使用通配符匹配实现灵活的路径过滤。
为支持从任意目录压缩的场景,采用相对通配符模式:
- 简单名称
testpath→ 转换为*testpath模式 - 匹配任意路径中包含该名称的文件/目录
- 编译器: Microsoft Visual Studio 2022 Community
- 工具链: MSVC (nmake)
- 编译命令:
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" cd CPP\7zip\UI\GUI nmake
项目根目录下提供了编译脚本:
build_7z_gui.bat- 编译 7zG.exe 和 7zFM.exebuild_clean.bat- 清理编译输出
测试场景:
- ✅ 在目标目录内选择文件压缩 - gitignore 规则生效
- ✅ 从父目录右键压缩文件夹 - gitignore 规则生效
- ✅ gitignore 文件不存在时显示警告提示
- ✅ 基本模式匹配(目录名、文件名)
| 特性 | 示例 | 说明 | 状态 |
|---|---|---|---|
| 简单文件名匹配 | README.md |
匹配任意位置的指定文件名 | ✅ 已实现 |
| 简单目录名匹配 | node_modules |
匹配任意位置的指定目录名 | ✅ 已实现 |
通配符 * 匹配 |
*.log |
匹配任意字符(除路径分隔符) | ✅ 已实现 |
单字符 ? 匹配 |
file?.txt |
匹配单个任意字符 | ✅ 已实现 |
| 取反模式 | !important.log |
重新包含之前排除的文件 | ✅ 已实现 |
| 根目录相对路径 | /build/ |
仅匹配 .gitignore 所在目录的 build | ✅ 已实现 |
| 注释行 | # 这是注释 |
以 # 开头的行被忽略 | ✅ 已实现 |
| 空行忽略 | (空行) | 空行不影响匹配 | ✅ 已实现 |
| 特性 | 示例 | Git 行为 | 当前处理方式 |
|---|---|---|---|
| 双星号前缀 | **/node_modules |
匹配任意层级目录下的 node_modules | 替换为 *node_modules,可能匹配不完整 |
| 双星号后缀 | foo/** |
匹配 foo 目录下所有内容 | 替换为 foo/*,只匹配一层 |
| 双星号中间 | src/**/test |
匹配 src 下任意层级的 test | 替换为 src/*/test,只匹配一层 |
| 目录尾随斜杠 | build/ |
仅匹配目录,不匹配同名文件 | 保留斜杠传递,可能匹配文件 |
| 字符范围 | [abc].txt |
匹配 a.txt、b.txt、c.txt | 原样传递,7z 可能不识别 |
| 数字范围 | file[0-9].txt |
匹配 file0.txt 到 file9.txt | 原样传递,7z 可能不识别 |
| 取反字符范围 | [!abc].txt |
匹配非 a/b/c 开头的文件 | 原样传递,7z 可能不识别 |
| 转义空格 | file\ name.txt |
匹配含空格的文件名 | 不处理转义,当作普通字符 |
| 转义特殊字符 | \[test\] |
匹配字面量 [test] |
不处理转义,当作普通字符 |
| 多层 .gitignore | 子目录中的 .gitignore | 子目录规则覆盖或补充父目录规则 | 仅读取一个 .gitignore 文件 |
| 前导斜杠语义 | foo vs /foo |
无斜杠匹配任意层级,有斜杠仅匹配根目录 | 统一处理为任意层级匹配 |
当遇到未支持的 gitignore 语法时,采用以下策略:
| 情况 | 处理方式 | 结果 |
|---|---|---|
双星号 ** |
替换为单星号 * |
可能匹配范围变化,但不会报错 |
字符范围 [abc] |
原样传递给 7z 通配符引擎 | 7z 可能无法识别,匹配可能失败 |
转义字符 \ |
不处理,当作普通字符 | 含特殊字符的路径可能无法正确匹配 |
尾随斜杠 / |
保留但不特殊处理 | 可能同时匹配同名文件和目录 |
| 多层 .gitignore | 只读取源目录的一个文件 | 子目录的规则被忽略 |
总体原则: 不报错、不跳过、降级处理。保证程序稳定运行,但匹配结果可能与 Git 原生行为有差异。
.gitignore 内容: **/node_modules
Git 行为: 匹配 node_modules, a/node_modules, a/b/node_modules 等
当前实现: 转换为 *node_modules
可匹配: node_modules, abcnode_modules
可能遗漏: a/b/node_modules (深层目录)
.gitignore 内容: src/**/test
Git 行为: 匹配 src/test, src/a/test, src/a/b/test 等
当前实现: 转换为 src/*/test
可匹配: src/a/test
遗漏: src/test (无中间目录), src/a/b/test (多层)
- 基础版本: 7-Zip 26.00
- 修改日期: 2026-04-03
