Skip to content

Drootkit/7z-gitignore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

7z源码版本:2026年2月的,来源是:https://www.7-zip.org/

7-Zip GUI .gitignore 功能扩展 - Changelog

功能概述

为 7-Zip 26.00 GUI 版本添加了 .gitignore 文件过滤支持功能。用户在压缩文件时,可以选择使用 .gitignore 规则自动排除指定的文件和目录。

image-20260403102642180

功能特性

  • 在压缩对话框中添加 "Use .gitignore" 复选框选项
  • 默认不勾选,用户可手动启用
  • 勾选时自动检测源目录中是否存在 .gitignore 文件
  • .gitignore 文件不存在,显示警告提示并自动取消勾选
  • 支持从父目录右键压缩文件夹时正确应用过滤规则
  • 支持基本的 gitignore 模式匹配:
    • 简单文件/目录名匹配(如 testpath
    • 通配符匹配(如 *.log
    • / 开头的根目录相对路径
    • 取反模式(!pattern

修改的文件

1. CompressDialogRes.h

路径: CPP/7zip/UI/GUI/CompressDialogRes.h

修改内容:

  • 添加控件资源 ID 定义
// Gitignore option
#define IDX_COMPRESS_USE_GITIGNORE      4020

2. CompressDialog.rc

路径: CPP/7zip/UI/GUI/CompressDialog.rc

修改内容:

  • 增加分组框高度(从64改为80)
  • 添加 "Use .gitignore" 复选框控件

3. CompressDialog.h

路径: CPP/7zip/UI/GUI/CompressDialog.h

修改内容:

  • NCompressDialog::CInfo 结构体中添加 UseGitignore 成员变量
  • CCompressDialog 类中添加 SourcePath 成员变量(用于存储源文件路径)

4. CompressDialog.cpp

路径: CPP/7zip/UI/GUI/CompressDialog.cpp

修改内容:

  • 添加 #include "../../../Windows/FileFind.h" 头文件
  • OnInit() 中初始化 gitignore 复选框状态
  • OnButtonClicked() 中添加复选框点击处理逻辑:
    • 检测源目录是否存在 .gitignore 文件
    • 不存在时显示警告并取消勾选
  • OnOK() 中保存 gitignore 选项状态到 Info.UseGitignore

5. Update.h

路径: CPP/7zip/UI/Common/Update.h

修改内容:

  • CUpdateOptions 结构体中添加 UseGitignore 成员变量
  • 构造函数中初始化为 false

6. UpdateGUI.cpp

路径: 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 压缩程序,接收参数后显示压缩对话框并执行压缩

流程:

  1. 用户在 7zFM 中选择文件并点击压缩
  2. 7zFM 通过 CompressFiles() 启动 7zG.exe 进程
  3. 7zG 显示压缩对话框,用户配置选项
  4. 用户点击确定后,设置传递给 UpdateGUI() 执行压缩

过滤机制

7-Zip 使用 NWildcard::CCensor 类进行文件过滤:

  • CensorPaths - 存储待处理的文件路径列表
  • Pairs - 按 Prefix 分组的路径规则
  • IncludeItems / ExcludeItems - 包含/排除规则列表

gitignore 规则通过 AddPreItem(false, pattern, props) 添加为排除模式,使用通配符匹配实现灵活的路径过滤。

路径匹配策略

为支持从任意目录压缩的场景,采用相对通配符模式:

  • 简单名称 testpath → 转换为 *testpath 模式
  • 匹配任意路径中包含该名称的文件/目录

编译工具

Windows 平台 (Visual Studio)

  • 编译器: 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.exe
  • build_clean.bat - 清理编译输出

测试验证

测试场景:

  1. ✅ 在目标目录内选择文件压缩 - gitignore 规则生效
  2. ✅ 从父目录右键压缩文件夹 - gitignore 规则生效
  3. ✅ gitignore 文件不存在时显示警告提示
  4. ✅ 基本模式匹配(目录名、文件名)

已知限制

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

About

The 7z compression tool has added filtering functionality based on .gitignore, making it suitable for transferring internal coding projects.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors