git-side 深度解析:用 Rust 给「不该进主仓库」的文件另起一套版本控制
项目主页:https://github.com/Solexma/git-side
crates.io:https://crates.io/crates/git-side
语言:Rust(最低 Rust 1.85,Edition 2024)
协议:MIT
作者:Marco Orlandin(Solexma)
当前版本:0.2.3 · GitHub 12 Stars
痛点:主仓库里那些「该管但不该进」的文件
开发中总有一类文件,它们:
- 本质上需要版本控制(你不想丢历史)
- 但绝不该进主仓库(不想污染项目历史、不想团队共享)
- 通常被
.gitignore排除在外
典型场景:
BACKLOG.md/TODO.md— 个人项目笔记.vscode/launch.json— 本地调试配置,不共享docker-compose.override.yml— 本地开发环境覆盖,不想推上去scratch/— 临时实验和原型.claude//.cursor/rules/— AI 上下文配置,团队不想 track- 构建产物缓存、AI prompts 的中间结果……
这类文件 Git 本身能跟踪,但你不该把它们塞进主仓库。git-side 就是来解决这个矛盾的。
核心设计:一个对主仓库完全透明的空仓库
side repo 的存放位置
每个项目,git-side 在项目外部(~/.local/share/git-side/)懒创建式地建立一个 bare Git 仓库:
~/.local/share/git-side/<initial-commit-sha>/
这里用项目第一个 commit 的 SHA 作为项目唯一标识符。选它的理由很巧妙:
- 存在于每个仓库里(空仓库除外)
- 不受文件系统位置影响
- clone 到哪里都一样稳定
对主仓库零侵入
这是 git-side 最核心的设计原则。它保证:
- 没有 submodule
- 没有 config 变更
- 没有 hooks(除非你主动
git side hook install) - 没有任何元数据文件进入项目目录
主仓库完全感知不到 side repo 的存在。其他协作者 clone 你的项目,不会看到任何 git-side 的痕迹。
配置路径(平台相关)
| 平台 | 配置目录 | 数据目录 |
|---|---|---|
| Linux | ~/.config/git-side/ | ~/.local/share/git-side/ |
| macOS | ~/Library/Application Support/git-side/ | 同上 |
如果不想用默认路径,可以为每个项目指定自定义路径:
git side init --path /mnt/external/side-repos/
映射关系存在配置目录里,不改主仓库。
核心技术:目录是语义容器 + 强制绕过 gitignore
目录 = 语义容器
git-side 把目录视为语义容器。如果 tracking 一个目录,工具会负责:
- 新增文件
- 删除文件
- 重命名文件
- 嵌套子目录
这些行为是 git-side 自己实现的,不是依赖 Git 的默认行为。这样能保证语义一致,不受 Git 默认忽略规则影响。
强制绕过 .gitignore
side repo 用这样的方式添加文件:
git add -f <path>
-f(force)标志会故意绕过所有忽略规则:
.gitignore- 全局 ignore(
core.excludesFile) - 系统级 ignore
这是设计上的有意选择,不是 workaround。因为 side repo 的文件本来就不应该被主仓库忽略规则约束。
与 dotfiles 方案的根本区别:vcsh vs git-side
git-side 的灵感来源是 vcsh,但解决的问题域不同:
| vcsh | git-side | |
|---|---|---|
| 工作树 | 固定为 $HOME | 当前 Git 项目目录 |
| 管理对象 | $HOME 下的多套配置(zsh/vim/ssh 等各自一个 repo) | 单个项目内的局部文件 |
| 场景 | 管理整个家目录的配置,做跨机器同步 | 管理项目中"不该进主仓库"的局部文件 |
| 冲突策略 | 多 repo 并存 | Push/Pull 都是 force,不解决冲突 |
简单说:vcsh 是给"整个 $HOME"当仓库用的,git-side 是给"某个项目里的局部文件"当仓库用的。
两者都基于 bare repo + 分离 GIT_DIR/WORK_TREE 的原理,但应用场景完全不同。
安装与使用
安装
预编译二进制(Linux / macOS / Windows):
# 下载 Release:https://github.com/Solexma/git-side/releases
chmod +x git-side-*
sudo mv git-side-* /usr/local/bin/git-side
从源码安装:
cargo install --git https://github.com/Solexma/git-side.git
需要 Rust 1.85+(Edition 2024)。
核心命令
git side add <path> # 跟踪文件或目录(强制绕过 gitignore)
git side rm <path> # 取消跟踪
git side status # 查看 side repo 状态
git side commit -m "msg" # 在 side repo 提交
git side log # 查看 side repo 历史
git side auto # 同步、提交、推送(自动沿用主仓库的 commit message)
# 初始化自定义路径
git side init --path /mnt/external/side-repos/
# Hook 安装(post-commit / pre-push / post-merge)
git side hook install # 默认在 post-commit
git side hook install --on pre-push
# 远程同步
git side remote add origin git@github.com:user/project-side.git
git side push # force,本地永远覆盖远程
git side pull # fetch + reset --hard,远程永远覆盖本地
使用示例
# 在项目里跟踪一些文件
git side add BACKLOG.md
git side add scratch/
# 在 side repo 提交
git side commit -m "Added personal backlog"
# 或者直接沿用主仓库的 commit message
git commit -m "Refactor parsing logic"
git side auto # 自动同步到 side repo
远程同步的设计哲学
Push 和 Pull 都是强制操作,不解决冲突:
push→--force,本地永远赢pull→fetch+reset --hard,远程永远赢
作者的解释很直接:如果你需要 merge 语义,说明你 track 的文件可能放错了地方。side repo 是"本地优先"的设计,远程同步只是可选的补充。
重要提醒:git-side 不是给你的密钥准备的
官方明确警告:
git-side 不用于存储 secrets。
.env、API keys、tokens、credentials 等文件永远不要 commit 到任何仓库——包括 side repo。使用专门的 secrets manager。没有例外。
技术规格
| 项目 | 值 |
|---|---|
| 当前版本 | 0.2.3 |
| 最低 Rust 版本 | 1.85(Edition 2024) |
| 代码行数 | ~916 行(Rust,20 个文件) |
| 许可 | MIT |
| 作者 | Marco Orlandin(MiPnamic) |
| crates.io 下载量 | 72(近期 42) |
| 发布时间 | 2026-02-03 |
| 关键词 | cli, dotfiles, git, side-repo, version-control |
适用场景 vs 不适用场景
适用:
- 项目里的个人笔记(BACKLOG.md、REFACTORING.md)
- 本地开发配置(.vscode/、.idea/)
- 本地环境覆盖(docker-compose.override.yml)
- 临时实验目录(scratch/、temp/)
- AI 工具上下文配置(不想进主仓库的 .claude/)
不适用:
- 跨机器同步 dotfiles(用 vcsh / bare repo dotfiles 方案)
- 多人共享的配置(需要合并语义,用 git 本身或 git-lfs)
- 存储密钥(用 Vault / 1Password / .env 文件)
总结
git-side 的价值在于它填补了一个一直被忽视的需求:对项目里"局部、临时、个人、不该进主仓库"的文件,提供一套轻量、Git 原生、完全不影响主仓库历史的版本控制方案。
它不是 dotfiles 管理工具的替代品,也不是另一种 Git 替代品。它是 Git 的延伸——让你在同一个项目里同时维护两条平行的版本线:一条给团队,一条给自己。
Rust + Edition 2024 的选择也很有意思,说明作者希望用现代 Rust 的 async/await 和其他新特性来构建这个工具。
GitHub:https://github.com/Solexma/git-side