npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zhujunzhujun/git-repo-sync

v0.0.4

Published

One-way Git repository sync CLI built with Bun.

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 now

3. 查看状态

git-repo-sync status

4. (可选)启动 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>,已存在则更新 origingit 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+CSIGINTSIGTERM 后会在当前检查周期结束后退出。

定时运行示例

有两种推荐运行方式:

  • 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.logruntime/daemon.err.logruntime/web-server.out.logruntime/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.yaml

Linux systemd

仓库提供了两个 systemd 模板:

  • deploy/systemd/git-repo-sync-daemon.service:常驻计划同步。
  • deploy/systemd/git-repo-sync-web.service:后台运行 Web 管理台。

使用前请按实际环境修改模板里的 UserWorkingDirectoryEnvironment=PATHExecStart --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)

也可以在配置中按仓库覆盖 cacheDirstateFilelogFilelockFile

凭证建议

不要把明文密码或 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: false

run-once 没有执行同步

依次检查:

  • 当前时间是否已经晚于 scheduleTime
  • timezone 是否配置正确。
  • 状态文件中的 lastScheduledDateCompleted 是否已经是当天日期。
  • syncOnMissedSchedule 是否为 true

本地缓存损坏

停止任务后删除该仓库对应的 cacheDir,下一次同步会重新 git clone --mirror只删除确认属于本工具的缓存目录,避免误删其他仓库。

进一步阅读

  • 配置项参考:defaultsrepositories[] 完整字段说明。
  • 架构概览:CLI 命令、Web API、运行态目录、模块依赖一图汇总。
  • 文档导航:设计文档、阶段总结、外部数据资料的入口。

贡献与开发

仓库: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 命令。

许可证

MIT