# git-cleaner **Repository Path**: zhoufoxcn/git-cleaner ## Basic Information - **Project Name**: git-cleaner - **Description**: No description available - **Primary Language**: Go - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-30 - **Last Updated**: 2026-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Git Cleaner 一个用 Go 编写的 Git 仓库历史清理工具,功能类似 [BFG Repo-Cleaner](https://github.com/rtyley/bfg-repo-cleaner)。专注于从 Git 历史中快速移除敏感文件、敏感文本和大文件。 ## 为什么需要 Git Cleaner? 在开发过程中,开发者可能会不小心将以下类型的文件提交到仓库: - 配置文件(`.env`、`config.yaml`、`secrets.json`) - 证书和密钥(`.pem`、`.key`、`.p12`) - 密码、API Key、Token - 大型二进制文件或数据集 传统的 `git filter-branch` 速度慢且容易出错,而 BFG Repo-Cleaner 虽然快但需要 JRE。Git Cleaner 提供了一个**零依赖、跨平台、高性能**的替代方案。 ## 功能特性 | 功能 | 说明 | |------|------| | `--delete-files` | 删除所有历史中匹配的文件(支持逗号分隔的多文件名) | | `--delete-text` | 从所有历史中删除指定的敏感文本 | | `--replace-text` | 替换敏感文本,支持多组映射(`'old:new;old2:new2'`) | | `--big-files` | 删除所有历史中超过指定大小(MB)的文件 | | `--dry-run` | 预览清理结果,不实际修改任何内容 | | `--force` | 自动执行 reflog/gc/push,跳过交互式确认 | | `--repo` | 指定要清理的仓库路径 | ## 架构设计 ### 核心原理 Git Cleaner 不依赖 `go-git` 等第三方库,而是直接操作 Git 对象数据库(`.git/objects`),通过 zlib 解压和二进制解析来读写 Git 对象。这种设计带来了以下优势: - **零外部依赖** — 编译后只有一个二进制文件,无需安装任何运行时 - **极致性能** — 直接操作压缩对象,没有抽象层开销 - **跨平台** — 纯 Go 编写,支持 Windows/macOS/Linux ### 目录结构 ``` git-cleaner/ ├── main.go # CLI 入口,flag 解析,工作流编排 ├── Makefile # 构建脚本 ├── go.mod ├── internal/ │ ├── objectstore/ │ │ ├── objectstore.go # Git 对象读写(Reader/Writer) │ │ ├── walker.go # 遍历所有 Git 对象 │ │ └── replacer.go # 策略重写引擎 │ ├── logger/ │ │ └── dailyRotateAppLogger.go # 日志系统(按日轮转,lumberjack) │ ├── objectstore/ │ │ ├── objectstore.go # Git 对象读写(Reader/Writer) │ │ ├── walker.go # 遍历所有 Git 对象 │ │ └── replacer.go # 策略重写引擎 │ └── cleaner/ │ └── cleaner.go # 仓库操作辅助函数 └── bin/ # 编译产物目录 ``` ### 工作流程 ``` 1. 克隆裸仓库 (git clone --mirror) ↓ 2. 分析所有 Git 对象(commit → tree → blob) ↓ 3. 应用清理策略(删除文件 / 删除文本 / 替换文本 / 删除大文件) ↓ 4. 生成清理报告 ↓ 5. 执行后续操作(reflog expire + gc + force push) ``` ## 安装 ### 从源码编译 ```bash git clone https://gitee.com/zhoufoxcn/git-cleaner.git cd git-cleaner make build ``` 编译产物位于 `bin/git-cleaner`(Windows 下为 `bin/git-cleaner.exe`)。 ### 安装到系统 PATH ```bash make install ``` ## 日志 Git Cleaner 使用 `slog` + `lumberjack` 实现日志系统,支持按日轮转: - **控制台输出**: 实时显示所有日志到终端 - **文件输出**: 日志同时写入 `logs/git-cleaner-YYYY-MM-DD.log` 文件 - **自动轮转**: 每天生成新的日志文件,保留 60 天,单文件最大 100MB - **压缩备份**: 旧日志自动压缩为 `.gz` 格式 ## 使用方法 ### 基本用法 清理当前目录下的 Git 仓库: ```bash ./git-cleaner --delete-files ".env" ``` 指定仓库路径: ```bash ./git-cleaner --repo /path/to/repo --delete-files "config.yaml" ``` ### 示例 #### 删除指定文件 ```bash # 删除 .env 文件 ./git-cleaner --delete-files ".env" # 删除多个文件 ./git-cleaner --delete-files ".env,secrets.json,config.yaml" --force ``` #### 删除敏感文本 ```bash # 从所有历史中删除 "password123" ./git-cleaner --delete-text "password123" ``` #### 替换敏感文本 ```bash # 替换访问密钥 ./git-cleaner --replace-text "AKIAIOSFODNN7EXAMPLE:***REDACTED***" # 多组替换 ./git-cleaner --replace-text "password:***REDACTED***;api_key:***REDACTED***" ``` #### 删除大文件 ```bash # 删除所有超过 5MB 的文件 ./git-cleaner --big-files 5 ``` #### 预览模式 ```bash # 查看清理结果,不实际修改 ./git-cleaner --delete-files ".env" --dry-run ``` ### 清理后操作 非 `--force` 模式下,清理完成后会输出需要手动执行的命令: ```bash cd repo_cleaned git reflog expire --expire=now --all git gc --prune=now --aggressive git push origin --force --all # 推送所有分支到远程 git push origin --force --tags # 推送所有标签到远程 ``` **注意事项:** - `git push` 时 `--all` 和 `--tags` **不能同时使用**,必须分开执行 - 如果远程仓库配置了 `mirror` 模式,可以直接使用 `git push origin --force` - 如果不需要推送标签,可以跳过 `git push origin --force --tags` 步骤 - 如果只想推送特定分支,可以明确指定: `git push origin --force main develop` 使用 `--force` 参数可以自动执行以上所有步骤。 ## 构建命令 ```bash make build # 编译二进制文件 make upx # 编译并使用 UPX 压缩二进制文件(推荐发布使用) make build-all # 交叉编译所有平台(Linux/Windows 支持 UPX 压缩,macOS 仅编译不压缩) make install # 安装到系统 PATH make test # 运行测试 make clean # 清理构建产物 make fmt # 格式化代码 make check # 代码检查 ``` ## UPX 压缩 Git Cleaner 支持使用 [UPX (Ultimate Packer for eXecutables)](https://github.com/upx/upx) 对编译后的二进制文件进行压缩,进一步减小分发体积。 ### 安装 UPX **Windows (Chocolatey):** ```bash choco install upx ``` **macOS (Homebrew):** ```bash brew install upx ``` **Linux (Ubuntu/Debian):** ```bash sudo apt install upx ``` **Linux (CentOS/Fedora):** ```bash # CentOS/RHEL sudo yum install upx # Fedora sudo dnf install upx ``` **手动安装:** 从 [UPX GitHub Releases](https://github.com/upx/upx/releases) 下载对应平台的压缩包,解压后将 `upx` 可执行文件加入 PATH 环境变量。 ### 使用 UPX **方式一:单独压缩(推荐)** ```bash make build # 先编译 make upx # 再压缩 ``` **方式二:一步完成** ```bash make build-upx # 编译并压缩 ``` ### 压缩效果 | 平台 | 未压缩 | UPX 压缩后 | 压缩率 | |------|--------|-----------|--------| | Windows AMD64 | ~8 MB | ~3-4 MB | ~50-55% | | Linux AMD64 | ~6 MB | ~2-3 MB | ~55-60% | | Linux ARM64 | ~6 MB | ~2-3 MB | ~55-60% | | macOS AMD64/ARM64 | ~7 MB | N/A(不支持 UPX 压缩) | — | > macOS 平台的二进制文件由于 UPX 兼容性限制,不进行 UPX 压缩。UPX 压缩后的二进制文件完全兼容原版,无需任何额外运行时。 ## 与 BFG Repo-Cleaner 对比 | 特性 | Git Cleaner | BFG Repo-Cleaner | |------|-------------|------------------| | 语言 | Go | Java | | 依赖 | 零依赖 | 需要 JRE | | 安装 | 单个二进制 | JAR 文件 + JRE | | 跨平台 | ✅ 原生支持 | ✅ 跨平台但需 JRE | | 性能 | 直接操作对象数据库 | 使用 JGit 抽象层 | | 文件大小 | ~5-8 MB | ~10+ MB + JRE | | 通配符 | 逗号分隔多文件名 | glob 模式 | ## 注意事项 - **备份优先** — 在执行清理操作前,务必备份原始仓库 - **Force Push** — 重写历史后需要 `--force` 推送,会影响所有协作者 - **Mirrored Clone** — 工具会自动创建 `_cleaned` 后缀的裸仓库副本,清理完成后请手动删除 ## 技术细节 ### Git 对象操作 Git 对象数据库使用 zlib 压缩存储,Git Cleaner 直接读取 `.git/objects/XX/YYYY...` 文件: ``` Object 格式: "type content\0" Tree 格式: "mode name\0hash(20 bytes)" Commit 格式: 文本格式(tree, parent, author, committer, body) ``` ### 对象遍历 使用递归遍历从 commit 对象出发,依次访问 tree 和 blob 对象: ``` commit → tree → [blob, tree → [blob, tree ...]] ``` ### 重写策略 采用 Strategy 模式,支持多种清理策略的组合: ```go type Strategy struct { DeleteFiles map[string]bool // 删除的文件名集合 DeleteText string // 要删除的文本 ReplaceText map[string]string // 替换映射 BigFileMin int64 // 大文件阈值(字节) } ``` ## License MIT