Help us shape the future of Go! Take the 2026 Go Developer Survey

git-ferry

command module
v1.38.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: MIT Imports: 14 Imported by: 0

README

GitFerry

Chinese name 「摆渡」— ferry your code where it belongs: between intranets, out to the open-source world, and into backup harbors.

CI Release Go Report Card Go Version License Latest Release npm version

中文文档

Why GitFerry · Capabilities · Install CLI · Quick Start · AI Agent Quick Start · Web Console · Ops & DR · Agent Access · Configuration


Why GitFerry

Code hosting is fragmented: GitHub on the public internet, GitLab/Gitee on the intranet, backups scattered across scripts. The moment you need cross-platform sync, open-source publishing, and cold backup / DR, you end up gluing three tools together.

GitFerry folds those three jobs into one self-hosted hub:

Scenario Pain GitFerry
Cross-platform sync Scripts + cron + manual reconciliation Task-based sync: cron / webhook / manual, with auto-compensation
Open-source publish Module path rewrite, dual-repo identity clashes Mirror hub: identity-rewrite snapshots + pre-check / build gate / divergence confirm
Repo backup Git objects only; metadata lost Cold backup (bundle/zip) + issues/PR/releases snapshots that are restorable
Ops & audit Black box, no health signal Health score / RPO / drift / audit hash chain / DR drills
Automation Web UI only CLI + MCP + Agent Skills — humans and agents

Borrowing mature patterns from gickup, ghorg, gitea-mirror, and github-backup-rust, then adding three differentiators: restorable metadata, Agent-Native access, and module identity rewrite.

Capabilities

Sync
  • Platforms: GitHub / GitLab / Gitee / GitLink / Gitea / self-hosted
  • Triggers: cron, real-time webhook, manual / batch
  • Scope: branch globs, include allow-list, ignore refs/pull/* and other PR refs, tags, wiki, submodules, partial clone
  • Safety: force_push_policy (allow / block / backup_on_demand), prune
  • Resilience: runwatch auto-retry; exponential backoff on 403/429 rate limits
Mirror & backup
  • Mirror hub: open-source publishing (dual/multi-repo module identity rewrite snapshots)
  • Cold backup: git bundle or zip, backup_keep rotation, optional AES-256-GCM
  • Multi-destination: S3 / WebDAV / Azure / local fan-out
  • Metadata snapshot: issues (with comments) / PRs / labels / milestones / releases / gists / release assets
  • Metadata restore: metadata-restore, dry-run by default, selective kinds
  • Integrity: Merkle root manifest + verify; DR drill (restore + fsck + refs compare)
  • Git Smart HTTP: git clone cold backups over LAN without pushing to another forge first
Organization & ecosystem
  • Org mapping: preserve / single / flat / mixed bulk mapping to a target namespace
  • Starred import, public org anonymous mirror (GitHub)
  • force-push approval flow: pending requests under block policy, one-shot Admin approve
  • post-exec hook: callback script after every sync (notify / alert / custom pipeline)
Ops & governance
  • Five-dimension health score (reliability / freshness / schedule / safety / completeness)
  • Inventory (orphan repos), RPO/RTO, drift detection, unified todo queue
  • RBAC (admin/operator/readonly), OIDC JWT, audit export + hash chain, legal_hold
  • Prometheus metrics, ntfy/gotify/webhook notifications, success/fail heartbeats
Interfaces
  • Vue 3 web console (GitHub Enterprise / Linear-style calm ops UI)
  • RESTful API + OpenAPI (/swagger)
  • gitferry CLI (Envelope output, confirmation gate for dangerous ops)
  • MCP Server (Streamable HTTP, same tool registry as the AI assistant)
  • Agent Skills (Claude Code / MiMo / Cursor)
  • AI ops assistant (eino, off by default)

Quick Start

Prerequisites
  • Node.js 14+ (npm/npx) — only for skill installation (npx skills add)
  • Platforms: macOS, Linux, Windows (x64/arm64)
  • Go 1.27+ — source builds only
  • Server runs standalone: Docker or Release binary
Install the CLI (humans)

AI assistants: if you are helping a user install, jump to Quick Start (AI Agent).

Option 1 — Release binary (recommended):

# Pick a platform asset on https://github.com/yi-nology/git-ferry/releases/latest
VER=1.21.0   # replace with the latest version
curl -fsSL -o gitferry.tgz \
  "https://github.com/yi-nology/git-ferry/releases/download/v${VER}/gitferry_${VER}_darwin_arm64.tar.gz"
tar -xzf gitferry.tgz && sudo mv gitferry /usr/local/bin/

Option 2 — Agent Skills (optional; for Claude Code / MiMo):

# Run inside a clone of this repository (requires Node.js)
npx skills add ./skills -y -g
# or: make install-skills

Option 3 — Source build / package managers / Docker:

git clone https://github.com/yi-nology/git-ferry.git
cd git-ferry
make build && make build-cli    # output/git-ferry + output/gitferry
make docker-build               # server image

# Package manager templates: examples/packaging/
# brew install yi-nology/tap/git-ferry   (after tap publish)

npm (not published yet): npm install -g gitferry-cli will start working once NPM_TOKEN is configured for the Release workflow — the package is not on the npm registry yet (the publish step currently skips silently). Until then, use Option 1.

Quick Start (humans)
# 1. Configure CLI (writes ~/.config/gitferry/config.yaml)
gitferry config init --base-url http://127.0.0.1:8890 --token <API_KEY>
# or via env:
export GITFERRY_BASE_URL=http://127.0.0.1:8890
export GITFERRY_TOKEN=<API_KEY>

# 2. Verify connectivity
gitferry auth status
gitferry task +list --format json

# 3. Start the server (if not running)
cp .env.example .env && openssl rand -base64 32   # set ENCRYPTION_KEY
cp conf/config.example.yaml conf/config.yaml && make run
# Open http://localhost:8890  (System → CLI / Agent has the command cheatsheet)
Quick Start (AI Agent)

Steps for Claude Code / MiMo / Cursor. The user must supply an API Key in the browser or CI.

Step 1 — Install

# 1) Install the CLI — follow "Option 1 — Release binary" above
#    (the npm package is not published yet)
# 2) Install Agent Skills from a clone of this repository:
npx skills add ./skills -y -g

Step 2 — Configure

gitferry config init --base-url http://127.0.0.1:8890 --token "$GITFERRY_TOKEN"
# or env only (CI / sandbox):
export GITFERRY_BASE_URL=http://127.0.0.1:8890
export GITFERRY_TOKEN=<API_KEY>

Step 3 — Verify

gitferry auth status
gitferry ops +todo --format json

API Key source: the server GIT_SYNC_API_KEY used by the web console, or the key bound to the signed-in session.

First sync in 3 minutes
  1. Platforms → add GitHub/GitLab credentials → test connection
  2. Repos → add source and target (or POST /ops/auto-discover)
  3. Sync tasks → create a task (cron / include_branches / force_push_policy)
  4. History → trigger manually, inspect steps; diagnose + retry on failure

CLI equivalent:

export GITFERRY_BASE_URL=http://127.0.0.1:8890
export GITFERRY_TOKEN=your-api-key

gitferry platform +list --format json
gitferry repo +list --format json
gitferry task +create --name demo \
  --source-repo gh/owner/repo --target-repo gl/owner/repo \
  --source-branch '*' --target-branch '*' --yes
gitferry task +run --key <task-key> --yes
gitferry history +list --task <task-key> --format json

Web Console

Vue 3 + Ant Design Vue. Visual anchor: GitHub Enterprise / Linear-style calm ops console — neutral palette first, restrained semantic colors, metric strips over loud icons.

Entry What it does
Dashboard Metrics + failed tasks “needs attention” + recent sync/repos
Sync tasks / History Task CRUD, filters, batch ops, run detail
Repos / Mirror hub Repo cards, unified config, publish & backup channels
Webhook rules / Events Trigger rules and inbound event stream
Ops center Health score, inventory, templates, deploy keys, cold backup & metadata restore
AI assistant Floating ball / top bar; configure model under System
CLI / Agent System → CLI / Agent: install gitferry, Skills, command cheatsheet
Platforms Git host credentials and connection tests

Login Dashboard Sync tasks

More screenshots: docs/screenshots/. Frontend dev: frontend/README.md.


Ops & Disaster Recovery

Capability matrix
Capability Entry
Prometheus metrics GET /metrics
Failure compensation runwatch + auto retry; POST /ops/retry / retry-batch
Notifications ntfy / gotify + success/fail heartbeats (healthchecks.io)
Health score GET /ops/health-score (gold/silver/bronze/basic + 5 dimensions)
Inventory GET /ops/inventory (orphan repos)
Unified todo GET /ops/todo + dashboard card
Policy templates GET/POST /ops/templates + preview/apply (dry-run, inheritance)
Audit CSV export, hash chain GET /ops/audit-chain/verify
Secret injection GIT_SYNC_TOKEN_<NAME> / GIT_SYNC_TOKEN_CMD_<NAME>
Deploy keys POST /ops/deploy-key (Ed25519)
Cold backup git_bundle; sync.backup_format: bundle|zip + backup_keep
Metadata snapshot POST /ops/metadata-backup (issues/PR/releases/gists/assets, since incremental)
Metadata restore POST /ops/metadata-restore (dry-run default, selective kinds)
DR drill POST /ops/dr-drill (restore + fsck + refs); RPO GET /ops/rpo
Integrity Merkle root manifest + verify
Multi-destination sync.backup_destinations (s3/webdav/azure/local)
Git Smart HTTP git_serve — LAN git clone of cold backups
Lifecycle auto-discover, drift, upstream-deleted cleanup
force-push approval ops/force-push-approvals request / list / Admin approve
Org mapping POST /ops/org-mirror (preserve/single/flat/mixed) + resolve-org-target
Starred / public org POST /ops/import-starred / import-public-org
Governance RBAC, OIDC JWT, legal_hold
Rebuild POST /ops/rebuild
Filtered import POST /ops/sync-platform (exclude archived/fork, star/language/glob)
GitHub archive POST /ops/migration (Migration API tar.gz)
post-exec hook sync.post_exec_script with GITFERRY_TASK/RESULT/RUN_ID/TRIGGER

Frontend entry: Sidebar → Ops center. Config: conf/config.example.yaml.

Metadata recovery loop

Backup success ≠ recoverable. GitFerry closes the loop: snapshot → verify → restore.

# 1) Snapshot (incremental with since)
curl -X POST .../api/v1/ops/metadata-backup \
  -d '{"repo_key":"gh/owner/repo","with_issues":true,"with_prs":true}'

# 2) Preview restore plan (dry-run, no writes)
gitferry ops +metadata-restore --key gh/owner/repo --format json

# 3) Commit after review
gitferry ops +metadata-restore --key gh/owner/repo --kinds labels,milestones,issues --execute --yes

Restore order: labels → milestones → issues (comments + closed state) → PRs (as annotated issues) → releases.

LAN disaster recovery pickup
# conf/config.yaml
git_serve:
  enabled: true
  base_path: "/data/git-serve"   # empty = <sync.backup_dir>/git-serve
  public_read: false             # true only on trusted LAN
git clone http://gitferry:8890/git/github/octocat/hello.git

Agent Access (CLI · MCP · Skills)

Three surfaces share one tool semantic — both humans and agents can operate GitFerry.

1. gitferry CLI
export GITFERRY_BASE_URL=http://127.0.0.1:8890
export GITFERRY_TOKEN=your-api-key        # maps to X-API-Key

gitferry auth status
gitferry task +list --format json
gitferry ops +health --with-drift --format json
gitferry ops +metadata-restore --key gh/o/r --dry-run --format json
gitferry api GET /api/v1/system/status --format json
gitferry schema list && gitferry schema show ops
  • Unified Envelope: {ok, data, error, meta}; --format json|table|yaml
  • Dangerous shortcuts (task +run, ops +drill, ops +metadata-restore --execute) return 409 unless --yes
  • --all paginate, --dry-run preview, --csv export

Install: see Quick Start (one npm command).

2. MCP Server (Claude Code / Cursor)

POST /mcp (Streamable HTTP) reuses the same tool registry as the built-in AI assistant:

# capability probe
curl -H "X-API-Key: $GITFERRY_TOKEN" http://127.0.0.1:8890/mcp

# Claude Code
claude mcp add gitferry --transport http http://127.0.0.1:8890/mcp \
  --header "X-API-Key: $GITFERRY_TOKEN"

Supports initialize / tools/list / tools/call / ping. Dangerous tools keep confirmation semantics.

3. Agent Skills
make install-skills
# or: npx skills add ./skills -y -g
Skill Covers
gitferry-shared Auth, Envelope, safety rules, troubleshooting
gitferry-repo / gitferry-task / gitferry-history Repos, tasks, run history
gitferry-ops / gitferry-workflow Ops checks, failure triage, DR, metadata restore

Design notes: docs/superpowers/plans/.


AI Assistant (eino)

Built on CloudWeGo eino. Disabled by default (returns 501 until enabled).

Enable under System → AI Assistant: pick a preset (OpenAI / DashScope / DeepSeek / Ollama / vLLM / custom) or set API Base URL, choose model (or fetch list), set API Key, Save (hot reload to data/ai-settings.json, no restart).

30 tools: queries, health, inventory, RPO, integrity, drift, audit, failure diagnosis, memory (plan_mode / remember / recall), deep_analyze, DR drills. Read-only queries run directly; run_task, connection tests, and other dangerous ops require a UI confirmation card + one-shot token.

Safety: read-only by default; git credentials and model keys never enter prompts/logs; tool results are injected as data only (prompt-injection hardening).

Method Path Notes
GET /api/v1/ai/status 501 = disabled
POST /api/v1/ai/chat SSE chat
GET /api/v1/ai/config config (key masked)
POST /api/v1/ai/config save + hot reload
POST /api/v1/ai/config/test probe OpenAI-compatible endpoint
GET /api/v1/ai/models list models from endpoint

Configuration

Environment
Variable Required Description
ENCRYPTION_KEY Yes AES-256-GCM key for credential storage
GITFERRY_TOKEN CLI API key for gitferry (X-API-Key)
GIT_SYNC_AI_API_KEY AI AI assistant key (optional)
GIT_SYNC_TOKEN_<NAME> Ops Injected platform tokens (never in request body)
GIT_SYNC_TOKEN_CMD_<NAME> Ops Command that prints a token (secrets manager)
GIT_SYNC_BACKUP_DIR Backup Cold backup output directory
GIT_SYNC_POST_EXEC_SCRIPT Hook Post-sync script path
cp .env.example .env
openssl rand -base64 32   # write into ENCRYPTION_KEY
Config file

conf/config.yaml (full example: conf/config.example.yaml; schema: conf/config.schema.json):

server:
  host: "0.0.0.0"
  port: 8890
  api_key: ""              # X-API-Key; set a strong value in production
  api_key_role: admin      # admin | operator | readonly

database:
  driver: sqlite           # sqlite | mysql
  dsn: "data/git_sync.db"

sync:
  backup_dir: "var/backup"
  backup_keep: 5
  backup_format: bundle    # bundle | zip
  post_exec_script: ""
  max_concurrent: 2

runwatch:
  interval_seconds: 30
  history_limit: 10
  retry:
    max_auto_retries: 2
    cooldown_minutes: 5

# notify:
#   ntfy: [{ url: "https://ntfy.sh", topic: "gitferry-alerts" }]
#   gotify: [{ url: "https://gotify.example.com", token: "..." }]
#   heartbeat:
#     success_urls: ["https://hc-ping.com/uuid"]
#     fail_urls: ["https://hc-ping.com/uuid"]

# git_serve:
#   enabled: false
#   base_path: ""          # empty = <sync.backup_dir>/git-serve
#   public_read: false     # true only on trusted LAN

This is the public shell in a three-repo architecture; it depends on the engine as a Go module:

Repository Import path Role
git-ferry-core github.com/yi-nology/git-ferry-core Sync engine library (no HTTP)
git-ferry (this repo) github.com/yi-nology/git-ferry Public shell: hz API + Vue + CLI
git-ferry-intranet github.com/yi-nology/git-ferry-intranet Intranet shell (gateway/SSO auth)

Single-repo build works (git clone + go build). Local core workspace:

go work init . ../git-ferry-core   # do not commit go.work / replace
Architecture
flowchart TB
  subgraph Entry
    W[Web Console]
    C[gitferry CLI]
    M[MCP / Agent Skills]
    AI[AI Assistant eino]
  end
  subgraph Shell git-ferry
    H[hz REST API]
    OPS[Ops Center]
    MCP[mcp server]
    GW[git-serve read-only]
  end
  subgraph Engine git-ferry-core
    EX[executor sync/cold backup]
    SVC[service task/platform/gov]
  end
  W --> H
  C --> H
  M --> MCP
  AI --> H
  H --> SVC
  OPS --> SVC
  MCP --> SVC
  GW --> EX
  SVC --> EX
  EX --> P1[GitHub/GitLab/Gitee...]
  EX --> P2[S3/WebDAV/Azure]

Development

make tidy && make test && make lint
make build && make build-cli
make apidoc          # regenerate docs/openapi.json
cd frontend && npm ci && npm run build

Service-less CI mirror path: examples/ci/github-actions-mirror.yml.

Security

Please report vulnerabilities privately — see SECURITY.md. Credentials are AES-256-GCM encrypted; tokens enter only via env / secret commands; dangerous operations require confirmation by default.

Contributing

  1. Fork and branch (git checkout -b feature/amazing-feature)
  2. Keep make test / make lint green
  3. Open a PR using the template

License

MIT — see LICENSE.

Project Stats

Metric Value
Test Files 19
Total Tests 104

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
biz
serve
Package serve 提供公网/内网壳共用的 HTTP 启动能力: JSON recovery、gzip、完整路由注册、oekit bootstrap 驱动的优雅退出。
Package serve 提供公网/内网壳共用的 HTTP 启动能力: JSON recovery、gzip、完整路由注册、oekit bootstrap 驱动的优雅退出。
cmd
aistub command
aistub 是 OpenAI /chat/completions 兼容的本地桩,用于 AI 助手链路实测: 按用户消息关键词脚本化返回「先调工具 → 再总结」两轮行为。
aistub 是 OpenAI /chat/completions 兼容的本地桩,用于 AI 助手链路实测: 按用户消息关键词脚本化返回「先调工具 → 再总结」两轮行为。
apidoc command
历史同步(histsync)的公开 API 契约。
历史同步(histsync)的公开 API 契约。
gitferry command
internal
agent
Package agent 提供 git-ferry 的 AI 助手能力(eino 编排层)。
Package agent 提供 git-ferry 的 AI 助手能力(eino 编排层)。
agent/memory
Package memory 提供 AI 助手的持久记忆(借鉴 zcode memory extraction/recall)。
Package memory 提供 AI 助手的持久记忆(借鉴 zcode memory extraction/recall)。
agent/tools
Package tools 把 corebridge 能力包装为 eino 工具。
Package tools 把 corebridge 能力包装为 eino 工具。
agent/tools/toolstest
Package toolstest 提供跨包共用的测试基建:SyncService mock 与脚本化假模型。
Package toolstest 提供跨包共用的测试基建:SyncService mock 与脚本化假模型。
cli/schema
Package schema 从内嵌 OpenAPI 生成 API 自省视图,供 `gitferry schema` 使用。
Package schema 从内嵌 OpenAPI 生成 API 自省视图,供 `gitferry schema` 使用。
converter
Package converter 负责把 core 层领域实体转成 thrift 生成的对外 DTO。
Package converter 负责把 core 层领域实体转成 thrift 生成的对外 DTO。
gitserve
Package gitserve 只读 Git Smart HTTP:局域网/灾备场景直接 `git clone` 冷备或 workdir 中的 bare/mirror 仓库,不必先推到另一 forge。
Package gitserve 只读 Git Smart HTTP:局域网/灾备场景直接 `git clone` 冷备或 workdir 中的 bare/mirror 仓库,不必先推到另一 forge。
mcp
Package mcp 提供 MCP Streamable HTTP 端点,把 internal/agent/tools 注册表 暴露给 Claude Code / Cursor 等外部客户端。
Package mcp 提供 MCP Streamable HTTP 端点,把 internal/agent/tools 注册表 暴露给 Claude Code / Cursor 等外部客户端。
metrics
Package metrics 提供壳层可观测指标:基于 prometheus/client_golang,默认注册表复用 oekit metrics.Registry(自带 Go runtime / process 采集器与 app_build_info), /metrics 端点由 oekit hertz/metrics 暴露。
Package metrics 提供壳层可观测指标:基于 prometheus/client_golang,默认注册表复用 oekit metrics.Registry(自带 Go runtime / process 采集器与 app_build_info), /metrics 端点由 oekit hertz/metrics 暴露。
notify
Package notify 提供同步结果的多通道通知与存活心跳。
Package notify 提供同步结果的多通道通知与存活心跳。
pkg/authz
Package authz 承载访问角色(RBAC 最小集)与它在 Go context 里的传递。
Package authz 承载访问角色(RBAC 最小集)与它在 Go context 里的传递。
pkg/swagger
Package swagger 内嵌 OpenAPI 文档与 Swagger UI,服务启动即可浏览 API 文档。
Package swagger 内嵌 OpenAPI 文档与 Swagger UI,服务启动即可浏览 API 文档。
pkg/textutil
Package textutil 是 core strutil 的转发层:文本/路径安全化、CSV 与小工具 的唯一实现在 git-ferry-core/pkg/strutil,本包只保留包名以稳定调用方 import。
Package textutil 是 core strutil 的转发层:文本/路径安全化、CSV 与小工具 的唯一实现在 git-ferry-core/pkg/strutil,本包只保留包名以稳定调用方 import。
runwatch
Package runwatch 把「运行结束」转成通知/指标/心跳与失败自动补偿。
Package runwatch 把「运行结束」转成通知/指标/心跳与失败自动补偿。
version
Package version 提供服务版本号。
Package version 提供服务版本号。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL