@zhujunzhujun/git-repo-sync
v0.0.4
Published
One-way Git repository sync CLI built with Bun.
Maintainers
Readme
@zhujunzhujun/git-repo-sync
基于 Bun + TypeScript 的 Git 仓库单向同步 CLI。把多个源仓库的所有分支(可选 tags)同步到对应的目标仓库,适合代码备份、跨平台镜像、内外网仓库同步、迁移过渡等场景。
功能
- 单向同步:只从
sourceRepo同步到targetRepo,不会反向写回。 - 多仓库配置:一个配置文件中可以维护多组同步任务,每个仓库可单独覆盖默认值。
- 全分支同步:同步源仓库下所有
refs/heads/*。 - 可选同步 tags:
syncTags控制是否同步refs/tags/*。 - 可选强制推送:
allowForcePush控制是否覆盖目标仓库同名分支或 tag。 - 可选删除目标多余分支:
deleteMissingBranches控制源仓库删除分支后是否同步删除目标仓库分支。 - 补同步:计划时间已过且当天未成功同步时,
run-once会自动补跑一次。 - 邮件通知:仓库推送完成后可通过 SMTP 给指定邮箱发送成功通知,也可以在 Web 管理台配置。
- 本地 Web 管理台:
git-repo-sync web启动浏览器面板,查看状态、触发同步、对比差异、查看日志。 - 状态与日志:每个仓库独立记录状态文件、JSONL 日志、并发锁。
环境要求
- Bun ≥ 1.0(运行期必需,CLI 入口为
#!/usr/bin/env bun) - Git
- 可访问源仓库和目标仓库的 Git 凭证(SSH key、Git 凭证管理器或 CI/CD 注入的凭证)
bun --version
git --version安装
# 推荐:Bun 全局安装
bun add -g @zhujunzhujun/git-repo-sync
# 也支持 npm
npm install -g @zhujunzhujun/git-repo-sync安装完成后,git-repo-sync 命令应该可以直接使用:
git-repo-sync --help注意:即使通过
npm安装,运行时依然需要本机有bun可执行,因为 CLI 入口使用 Bun 的 shebang。
快速开始
1. 创建配置文件
默认配置文件位于当前用户目录下的 .git_repo_sync/config.yaml。首次启动 Web 管理台时会自动创建这个文件:
git-repo-sync web也可以手动创建或编辑:
- Windows:
C:\Users\<用户名>\.git_repo_sync\config.yaml - Linux/macOS:
~/.git_repo_sync/config.yaml
示例:
defaults:
scheduleTime: "09:00"
timezone: "Asia/Shanghai"
syncAllBranches: true
syncTags: true
allowForcePush: false
deleteMissingBranches: false
syncOnMissedSchedule: true
maxRetries: 3
retryIntervalSeconds: 60
runtimeDir: ~/.git_repo_sync/runtime
emailNotification:
enabled: false
host: smtp.example.com
port: 465
secure: true
username: [email protected]
password: your-smtp-password-or-app-token
from: [email protected]
to:
- [email protected]
repositories:
- id: my-project
description: My project mirror
sourceRepo: [email protected]:team/my-project.git
targetRepo: [email protected]:team/my-project.git
- id: another-project
description: Mirror with stricter rules
sourceRepo: https://gitee.com/team/another-project.git
targetRepo: [email protected]:team/another-project.git
allowForcePush: true
deleteMissingBranches: true完整字段说明见 配置项参考。
2. 立即同步
git-repo-sync sync now3. 查看状态
git-repo-sync status4. (可选)启动 Web 管理台
git-repo-sync web默认监听 http://127.0.0.1:5174。如果要使用其他配置文件,所有命令都可以通过 --config <file> 覆盖默认路径。
命令清单
sync now — 立即同步
git-repo-sync sync now [--config <file>]行为:
- 逐个读取配置中的
repositories。 - 缓存仓库不存在时执行
git clone --mirror <sourceRepo>,已存在则更新origin并git fetch --prune。 - 推送源分支到目标仓库;
syncTags: true时同时推送 tags。 deleteMissingBranches: true时删除目标仓库中源仓库已不存在的分支。- 每次运行在
runtimeDir/runs/下生成sync-now-*.jsonl汇总。
run-once — 补同步检查
git-repo-sync run-once [--config <file>]适合交给 Windows 计划任务、Linux cron 或 CI/CD 周期性调用:
- 当前时间已到
scheduleTime且当天还未成功完成计划同步,则执行同步;成功后更新lastScheduledDateCompleted。 - 还没到计划时间或当天已完成,则跳过。
- 进程执行完即退出。
status — 查看同步状态
git-repo-sync status [--config <file>]输出每个仓库的状态 JSON,字段:
lastSuccessfulSyncAt:最近一次成功同步时间。lastScheduledDateCompleted:最近一次完成计划同步的日期。lastResult:success/failure/never。lastError:最近一次失败原因。branches/tags:最近一次成功同步时各 ref 对应的 hash。
web — 本地 Web 管理台
git-repo-sync web [--config <file>] [--host <host>] [--port <port>] [--no-open]参数默认值:--host 127.0.0.1、--port 5174。默认会尝试打开浏览器,后台运行时建议加 --no-open。
页面能力:总览、仓库列表、单仓库详情、立即同步、对比源/目标 refs 差异、批量同步、仅重试失败、查看 JSONL 日志、运行历史。
默认仅监听本地回环地址。如果显式绑定
0.0.0.0暴露到局域网,请自行评估安全风险。
daemon — 常驻调度
git-repo-sync daemon [--config <file>] [--interval-seconds 60]行为:
- 常驻运行,每隔
--interval-seconds秒重新加载一次配置文件。 - 对每个启用的仓库执行计划检查:已到
scheduleTime且当天未完成计划同步时触发同步。 - 同步成功后更新
lastScheduledDateCompleted,避免同一天重复执行计划同步。 - 复用仓库锁文件,避免 Web 管理台、
sync now、其他 daemon 实例对同一仓库并发同步。 - 收到
Ctrl+C、SIGINT或SIGTERM后会在当前检查周期结束后退出。
定时运行示例
有两种推荐运行方式:
run-once:进程执行完即退出,适合交给 Windows 计划任务、Linux cron 或 CI/CD 周期性调用。daemon:工具自己常驻检查计划,适合交给 systemd、NSSM、Windows 计划任务开机启动等进程守护器托管。
Windows 计划任务
让计划任务每天在 scheduleTime 之后执行一次,例如配置里是 09:00,计划任务设为 09:05。
- 程序:
git-repo-sync - 参数:
run-once --config C:\path\to\git-sync.yaml - 起始位置:任一你希望存放
runtime/数据的目录
如需更稳妥,可以让计划任务每 30 分钟跑一次 run-once。工具会通过状态文件判断当天是否已经完成计划同步,不会重复补跑。
如果希望常驻后台运行,可以创建“开机时启动”的计划任务:
- 程序:
git-repo-sync - 参数:
daemon --config C:\path\to\git-sync.yaml --interval-seconds 60 - 起始位置:任一你希望存放
runtime/数据的目录
Web 管理台后台运行示例:
- 程序:
git-repo-sync - 参数:
web --config C:\path\to\git-sync.yaml --host 127.0.0.1 --port 5174 --no-open
需要进程崩溃自动拉起时,推荐用 NSSM 把上面两个命令分别注册为 Windows 服务,并把 stdout/stderr 指到 runtime/daemon.out.log、runtime/daemon.err.log 或 runtime/web-server.out.log、runtime/web-server.err.log。
Linux cron
每天 09:05 执行:
5 9 * * * cd /path/to/sync-workspace && git-repo-sync run-once --config ./git-sync.yaml每 30 分钟检查一次:
*/30 * * * * cd /path/to/sync-workspace && git-repo-sync run-once --config ./git-sync.yamlLinux systemd
仓库提供了两个 systemd 模板:
deploy/systemd/git-repo-sync-daemon.service:常驻计划同步。deploy/systemd/git-repo-sync-web.service:后台运行 Web 管理台。
使用前请按实际环境修改模板里的 User、WorkingDirectory、Environment=PATH、ExecStart --config。
sudo cp deploy/systemd/git-repo-sync-daemon.service /etc/systemd/system/
sudo cp deploy/systemd/git-repo-sync-web.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now git-repo-sync-daemon
sudo systemctl enable --now git-repo-sync-web
sudo systemctl status git-repo-sync-daemon
sudo journalctl -u git-repo-sync-daemon -f运行数据目录
默认运行数据写入当前用户目录下的 .git_repo_sync/runtime(由配置中的 runtimeDir 决定):
~/.git_repo_sync/runtime/
cache/ 本地 mirror 缓存仓库
state/ 每个仓库的同步状态 JSON
logs/ 每个仓库的运行日志 JSONL
locks/ 防止同一仓库并发同步的锁文件
runs/ sync now 的批量运行结果 JSONL
web/ Web 管理台触发的操作历史(operations.jsonl)也可以在配置中按仓库覆盖 cacheDir、stateFile、logFile、lockFile。
凭证建议
不要把明文密码或 token 提交到配置文件里。
推荐:
- 使用 SSH 地址 + 部署专用 SSH key。
- 使用 Git Credential Manager。
- CI/CD 或服务器环境中通过环境变量、密钥管理系统注入凭证。
- 必须使用 HTTP token 时,只写在本地未提交的 YAML 文件里,并确认它已被
.gitignore忽略。
工具运行 Git 命令时会设置 GIT_TERMINAL_PROMPT=0,凭证缺失时不会停下来等待交互输入,而是直接失败并记录错误。
常见问题
推送失败或提示 non-fast-forward
通常是目标仓库已有与源仓库不一致的历史。
- 如果目标仓库只是镜像或备份,可以为该仓库配置
allowForcePush: true。 - 如果目标仓库有人直接提交,不建议开启强推,需要先人工确认目标仓库差异。
目标仓库残留了源仓库已删除的分支
默认 deleteMissingBranches: false,工具不会删除目标仓库多余分支。需要严格镜像时:
deleteMissingBranches: true开启前请确认目标仓库不是人工协作仓库。
不想同步 tags
在仓库配置中覆盖:
syncTags: falserun-once 没有执行同步
依次检查:
- 当前时间是否已经晚于
scheduleTime。 timezone是否配置正确。- 状态文件中的
lastScheduledDateCompleted是否已经是当天日期。 syncOnMissedSchedule是否为true。
本地缓存损坏
停止任务后删除该仓库对应的 cacheDir,下一次同步会重新 git clone --mirror。只删除确认属于本工具的缓存目录,避免误删其他仓库。
进一步阅读
贡献与开发
仓库:github.com/zhujunzhujunzhu/git_repo_sync
git clone [email protected]:zhujunzhujunzhu/git_repo_sync.git
cd git_repo_sync
bun install
bun test
bun run typecheck集成测试会创建本地临时 bare 仓库,并执行真实 Git 命令。
