{"id":49947105,"url":"https://github.com/entireio/git-sync","last_synced_at":"2026-05-30T17:02:16.707Z","repository":{"id":354870208,"uuid":"1205118051","full_name":"entireio/git-sync","owner":"entireio","description":"🪩 Mirror git refs from a source remote to a target remote without a local checkout. Packfiles stream directly over Smart HTTP and an in-memory object store.","archived":false,"fork":false,"pushed_at":"2026-05-29T11:05:41.000Z","size":58186,"stargazers_count":455,"open_issues_count":6,"forks_count":18,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-29T11:17:18.135Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/entireio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-08T16:47:15.000Z","updated_at":"2026-05-28T11:31:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/entireio/git-sync","commit_stats":null,"previous_names":["entireio/git-sync"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/entireio/git-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/entireio%2Fgit-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/entireio%2Fgit-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/entireio%2Fgit-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/entireio%2Fgit-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/entireio","download_url":"https://codeload.github.com/entireio/git-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/entireio%2Fgit-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33700863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-17T16:00:40.661Z","updated_at":"2026-05-30T17:02:16.686Z","avatar_url":"https://github.com/entireio.png","language":"Go","funding_links":[],"categories":["others","Go"],"sub_categories":[],"readme":"![git-sync theme](docs/images/gh-repo-cover.png \"git-sync cover image\")\n\n# git-sync\n\n`git-sync` mirrors refs from a source remote to a target remote without creating a local checkout. It uses an in-memory `go-git` object store and talks smart HTTP directly:\n\n- `info/refs` ref advertisement for source and target\n- `upload-pack` fetch from source with target tip hashes advertised as `have`\n- `receive-pack` push to target with explicit ref update commands and a streamed packfile\n\nThat keeps the target side incremental without fetching target objects into the local process first.\n\n## Why This Exists\n\nMirroring Git data between remotes usually means a local mirror clone followed by a mirror push. That's fine for small repos but turns a remote-to-remote operation into a local storage problem at scale, and shell glue around `git fetch` / `git push` tends to skip planning and structured output.\n\n`git-sync` fills that gap. It streams source packs directly into target `receive-pack` when it can, plans every action before pushing, and emits typed JSON for automation.\n\nFor when to use it (and when not), see [docs/architecture.md](docs/architecture.md).\n\n## Commands\n\nThe main commands are:\n\n- `git-sync sync`: mirror source refs into the target\n- `git-sync replicate`: overwrite target refs to match source via relay, and fail rather than materialize locally\n\n`sync` automatically bootstraps an empty target, so the same command covers initial seeding and ongoing sync. To preview what would happen without pushing, run `git-sync plan` — it takes the same flags as `sync`, and `--mode replicate` previews a `replicate` run.\n\nFor command examples, JSON output, auth, protocol flags, and advanced command notes, see [docs/usage.md](docs/usage.md).\n\n## Library API\n\n`git-sync` is also a Go library. Use `entire.io/entire/git-sync` for the stable embedding surface (`Probe`, `Plan`, `Sync`, `Replicate`, typed results, auth and HTTP injection). `entire.io/entire/git-sync/unstable` exposes advanced controls (`Bootstrap`, `Fetch`, batching knobs, heap measurement) and is not stable.\n\n## Installation\n\n### Homebrew (macOS, Linux)\n\n```bash\nbrew tap entireio/tap\nbrew install --cask git-sync\n```\n\n### `go install`\n\nRequires Go 1.26 or newer.\n\n```bash\ngo install entire.io/entire/git-sync/cmd/git-sync@latest\n```\n\nThis drops a `git-sync` binary into `$(go env GOPATH)/bin`. Make sure that directory is on your `PATH`.\n\n### From source\n\n```bash\ngit clone https://github.com/entireio/git-sync.git\ncd git-sync\ngo build -o git-sync ./cmd/git-sync\n```\n\n## Quick Start\n\n```bash\ngit-sync sync \\\n  --source-token \"$GITSYNC_SOURCE_TOKEN\" \\\n  --target-token \"$GITSYNC_TARGET_TOKEN\" \\\n  https://github.com/source-org/source-repo.git \\\n  https://github.com/target-org/target-repo.git\n```\n\nhttps://github.com/user-attachments/assets/60adb873-4032-4ab7-b236-24d038e04681\n\n## Sync Behavior\n\n`sync` picks the bootstrap relay path automatically when the target is empty. For non-empty targets, safe fast-forward updates also use a relay path that streams the source pack directly into target `receive-pack` without local materialization. Anything not relay-eligible (force, prune, deletes, tag retargets) falls back to a materialized path bounded by `--materialized-max-objects`.\n\nFor branch filtering, ref mapping, tags, pruning, protocol selection, JSON output, and auth details, see [docs/usage.md](docs/usage.md).\n\n## Testing\n\nDefault suite:\n\n```bash\nenv GOCACHE=/tmp/go-build go test ./...\n```\n\nExtended and environment-specific test instructions are in [docs/testing.md](docs/testing.md).\n\n## Documentation\n\n- [docs/usage.md](docs/usage.md) — CLI commands, examples, sync behavior, JSON output, auth, protocol notes\n- [docs/architecture.md](docs/architecture.md) — product rationale, package layout, operation modes vs transfer modes, memory model\n- [docs/protocol.md](docs/protocol.md) — smart HTTP, pkt-line, capability negotiation, sideband, relay framing\n- [docs/testing.md](docs/testing.md) — test suites and integration coverage\n\n## FAQ\n\n### Does it sync complete Git history or only perform a shallow/partial sync?\n\n`git-sync` syncs the complete Git object history required for the selected refs. It does not create a shallow clone. Some planning paths may use filtered fetches, but the target receives the full objects needed for valid refs.\n\n### Is it just refs, or objects as well?\n\nObjects as well. Refs are what `git-sync` plans and updates, but it also transfers the commits, trees, blobs, and tags needed for those refs to exist on the target.\n\n### Is it bidirectional?\n\nNo. `git-sync` is one-way: source remote to target remote. To go the other way you'd run a second invocation with the endpoints swapped.\n\n### Does it support create, update, and delete actions?\n\nYes. It supports creating refs, updating refs, force updates with `--force`, and deleting managed refs with `--prune`. `replicate` can overwrite target refs, but it is relay-only and more restrictive than `sync`.\n\n### How does it scale?\n\n`git-sync` has two transfer paths:\n\n- **Relay** — pack data streams from source `upload-pack` directly into target `receive-pack`. The local process holds no object graph, so memory stays bounded regardless of repo size. Used when the target supports relay.\n- **Materialized fallback** — when relay isn't available, `git-sync` fetches the needed objects into an in-memory `go-git` store, plans, then encodes and pushes a packfile. Memory scales with the diff being pushed and is guarded by an explicit object-count limit. Bootstrap can batch large initial syncs to keep this bounded.\n\nPlanning itself is cheap: ref-only round-trips, plus a `filter tree:0` fetch for ancestry checks when the source advertises filter support.\n\n### How long does it take for a medium-sized repo?\n\nIt depends on repository size, network speed, and whether the relay path is available. As a rule of thumb, the relay path is bounded by source pack generation + network transfer + target receive-pack time — roughly the time of a `git clone` from the source plus a `git push` of the same pack. The materialized fallback adds local memory work for objects that need inspection.\n\nFor concrete numbers on your own setup, run the included benchmark tool against a representative repo; see [docs/testing.md](docs/testing.md#benchmarking).\n\n### Does it support SSH?\n\nYes. `git-sync` supports SSH remotes through the local `ssh` binary, including\n`ssh://`, SCP-style `git@host:path.git`, and `git+ssh://` URLs. See\n[docs/usage.md](docs/usage.md) for details and current caveats.\n\n### Does it run as a daemon or watch for changes?\n\nNo. `git-sync` is a one-shot CLI/library operation. To sync on a schedule or in response to events, run it from cron, CI, a worker, or another service.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md), and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fentireio%2Fgit-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fentireio%2Fgit-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fentireio%2Fgit-sync/lists"}