{"id":50203569,"url":"https://github.com/sphireinc/git-ark","last_synced_at":"2026-05-26T00:03:47.928Z","repository":{"id":354234848,"uuid":"1222693892","full_name":"sphireinc/git-ark","owner":"sphireinc","description":"A cross-platform CLI/script that takes one local git repo and pushes it to multiple remote git providers as backup mirrors","archived":false,"fork":false,"pushed_at":"2026-05-20T05:52:30.000Z","size":3878,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-20T09:20:07.280Z","etag":null,"topics":["backup","code","git","github","mirroring","repository"],"latest_commit_sha":null,"homepage":"https://sphireinc.github.io/git-ark/","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/sphireinc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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-27T16:03:28.000Z","updated_at":"2026-05-20T05:52:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sphireinc/git-ark","commit_stats":null,"previous_names":["sphireinc/git-ark"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/sphireinc/git-ark","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sphireinc%2Fgit-ark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sphireinc%2Fgit-ark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sphireinc%2Fgit-ark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sphireinc%2Fgit-ark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sphireinc","download_url":"https://codeload.github.com/sphireinc/git-ark/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sphireinc%2Fgit-ark/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33497930,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-25T14:31:05.219Z","status":"ssl_error","status_checked_at":"2026-05-25T14:31:02.878Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["backup","code","git","github","mirroring","repository"],"created_at":"2026-05-26T00:03:43.436Z","updated_at":"2026-05-26T00:03:47.904Z","avatar_url":"https://github.com/sphireinc.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-ark\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./logo-transparent.png\" alt=\"git-ark logo\" width=\"400\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/sphireinc/git-ark/actions/workflows/ci.yml\"\u003e\n    \u003cimg alt=\"CI\" src=\"https://github.com/sphireinc/git-ark/actions/workflows/ci.yml/badge.svg?branch=main\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/sphireinc/git-ark/actions/workflows/release.yml\"\u003e\n    \u003cimg alt=\"Release\" src=\"https://github.com/sphireinc/git-ark/actions/workflows/release.yml/badge.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"./LICENSE\"\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-blue.svg\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n`git-ark` is a CLI tool written in Go for backing up a local Git repository to one or more configured remotes.\n\nIt is built around a simple idea: keep the default backup path safe, explicit, and easy to audit.\n\nWhile service-side technical failures are rare on platforms like GitLab, Bitbucket, et al. - they can still happen - take for instance GitHub.\n\nThis project was created to mitigate data loss as a result of service-side technical failures, account loss, or some \nother act of (digital) nature. \n\nDocs site: \u003chttps://sphireinc.github.io/git-ark/\u003e\n\n## What It Does\n\n- Backs up branches and tags to multiple remotes.\n- Uses mirror mode only when you ask for it.\n- Can create a local bundle archive alongside remote backups.\n- Synchronizes local remotes from config when you want the repo to match the file.\n- Surfaces repo health, remote reachability, and provider-specific guidance.\n- Records backup history in metadata so `status` can show what happened last time.\n\n## Installation\n\n### Build From Source\n\n```bash\ngo build ./cmd/git-ark\n```\n\n### Run Without Installing\n\n```bash\ngo run ./cmd/git-ark --help\n```\n\n### Tagged Builds\n\nTagged pushes trigger the release workflow in [.github/workflows/release.yml](./.github/workflows/release.yml), which builds binaries for Linux, macOS, and Windows, creates a GitHub Release, and attaches release assets plus checksums. The same workflow can also be run manually from the GitHub Actions UI by providing a tag name like `v1.0.2`. Those releases can be found and downloaded from [Releases](https://github.com/sphireinc/git-ark/releases).\n\n## Quick Start\n\n1. Generate a starter config:\n\n```bash\ngit-ark init\n```\n\n2. Review the generated file and point `remotes` at your backup destination.\n3. Validate the repo and config:\n\n```bash\ngit-ark validate\n```\n\n4. Run a dry run first if you want to see the plan:\n\n```bash\ngit-ark backup --dry-run\n```\n\n5. Run the real backup:\n\n```bash\ngit-ark backup\n```\n\n6. Check the latest metadata and repo health:\n\n```bash\ngit-ark status\ngit-ark doctor\n```\n\n## Commands\n\n| Command | What it does |\n| --- | --- |\n| `git-ark init` | Writes a starter `git-ark.yml` file. |\n| `git-ark validate` | Checks the config and local repo for obvious problems. |\n| `git-ark backup` | Runs the backup workflow against configured remotes. |\n| `git-ark status` | Shows repo state, configured remotes, and backup history. |\n| `git-ark doctor` | Runs health checks and provider-aware diagnostics. |\n| `git-ark remotes list` | Lists configured remotes and whether they exist locally. |\n| `git-ark remotes sync` | Adds or updates local Git remotes from config. |\n| `git-ark version` | Prints build/version information. |\n\n## Common Flags\n\n- `--config`: use an explicit config file path.\n- `--repo`: override the repo directory.\n- `--dry-run`: show the plan without mutating remotes or creating bundles.\n- `--json`: emit machine-readable output where supported.\n\n`git-ark backup` also supports:\n\n- `--mode`: override the configured mode.\n- `--remote`: run against a selected subset of remotes.\n- `--include-disabled`: allow selected remotes that are disabled in config.\n- `--yes`: skip the mirror-mode confirmation prompt.\n- `--verbose`: print more target detail.\n- `--quiet`: suppress normal plan and summary output.\n- `--prune`: prune remote refs not present locally.\n\n## Configuration\n\n`git-ark init` generates a commented starter file. A minimal config can be as small as:\n\n```yaml\nremotes:\n  github:\n    url: git@github.com:example/example-backup.git\n```\n\nA more complete config looks like this:\n\n```yaml\nversion: 1\nrepo: \".\"\nmode: \"safe\"\nremotes:\n  github:\n    url: git@github.com:example/example-backup.git\n    enabled: true\n    required: true\n    provider: github\n    description: GitHub backup mirror\n  gitlab:\n    url: git@gitlab.com:example/example-backup.git\n    enabled: true\n    required: true\n    provider: gitlab\noptions:\n  manage_remotes: true\n  push_branches: true\n  push_tags: true\n  push_notes: false\n  push_all_refs: false\n  prune: false\n  verify_clean_worktree: false\n  continue_on_error: true\n  confirm_dangerous_operations: true\n  fetch_before_backup: false\n  pull_before_backup: false\n  skip_lfs: false\n  include_archived_branches: true\n  write_metadata: true\nbranch_filters:\n  include:\n    - main\n    - release/*\n  exclude:\n    - wip/*\ntag_filters:\n  include:\n    - v*\n  exclude:\n    - test-*\nbundle:\n  enabled: true\n  path: ./backups\n  filename_template: \"{{repo}}-{{timestamp}}.bundle\"\n  include_all_refs: true\nlogging:\n  level: debug\n  format: text\nmetadata:\n  path: .git/git-ark-last-backup.json\n```\n\n### Top-Level Fields\n\n| Field | Purpose |\n| --- | --- |\n| `version` | Config schema version. Current value: `1`. |\n| `repo` | Default repo path to operate on. |\n| `mode` | Backup mode: `safe`, `mirror`, or `bundle`. |\n| `remotes` | Map of remote names to remote definitions. |\n| `options` | Backup behavior toggles. |\n| `branch_filters` | Include/exclude glob filters for branches. |\n| `tag_filters` | Include/exclude glob filters for tags. |\n| `bundle` | Local bundle archive settings. |\n| `logging` | Output format settings. |\n| `metadata` | Path for the last-backup history file. |\n\n### Remote Fields\n\n| Field | Purpose |\n| --- | --- |\n| `url` | Remote URL. Required. |\n| `enabled` | Whether the remote is part of a normal backup run. |\n| `required` | Whether a failure on this remote should count as a required failure. |\n| `provider` | Provider hint for diagnostics, validation, and friendlier output. |\n| `description` | Human-friendly note for maintainers. |\n\nUseful provider hints:\n\n- `github`\n- `gitlab`\n- `bitbucket`\n- `codeberg`\n- `gitea`\n- `generic`\n- `ssh`\n- `https`\n\n### Option Groups\n\n- Safety and sync behavior:\n  - `manage_remotes`\n  - `confirm_dangerous_operations`\n  - `continue_on_error`\n  - `prune`\n  - `push_all_refs`\n- Backup scope:\n  - `push_branches`\n  - `push_tags`\n  - `push_notes`\n  - `include_archived_branches`\n  - `skip_lfs`\n- Preflight steps:\n  - `verify_clean_worktree`\n  - `fetch_before_backup`\n  - `pull_before_backup`\n- History and output:\n  - `write_metadata`\n\n`push_all_refs` is broader than the normal safe mode. `prune` is opt-in and narrows the push behavior, but it can still delete remote refs that are no longer present locally.\n\n## Modes\n\n### Safe Mode\n\nSafe mode is the default. It pushes branches and tags without mirroring every ref.\n\n```bash\ngit push \u003cremote\u003e --all\ngit push \u003cremote\u003e --tags\n```\n\n### Mirror Mode\n\nMirror mode is explicit and destructive.\n\n```bash\ngit push \u003cremote\u003e --mirror\n```\n\nIf confirmation is enabled, `git-ark` requires `--yes` in non-interactive environments.\n\n### Bundle Mode\n\nBundle mode creates a local Git bundle archive in addition to the selected backup behavior.\n\n```bash\ngit bundle create \u003coutput\u003e --all\n```\n\n## Filters\n\nBranch and tag filters use glob matching.\n\nIf an include list is empty, everything is included unless excluded.\n\n```yaml\nbranch_filters:\n  include:\n    - main\n    - release/*\n  exclude:\n    - wip/*\n\ntag_filters:\n  include:\n    - v*\n  exclude:\n    - test-*\n```\n\n## Remote Management\n\n`git-ark remotes sync` is useful when you want the local repo to match the config file.\n\n```bash\ngit-ark remotes list\ngit-ark remotes sync\n```\n\nUse `--dry-run` if you only want to see what would change.\n\n## Metadata and History\n\nAfter a successful backup, `git-ark` writes a history file to `.git/git-ark-last-backup.json` by default.\n\n`git-ark status` reads that history and shows:\n\n- The latest run\n- The number of recorded backups\n- A short recent history summary\n\nIf you move the metadata file in config, `status` follows that path.\n\n## Doctor and Provider Diagnostics\n\n`git-ark doctor` checks:\n\n- Whether `git` is available\n- Whether `ssh` is available\n- Whether the repo looks valid\n- Whether the local branch/tag state looks reasonable\n- Whether configured remotes are reachable\n- Whether configured providers look like they match the remote URL\n\nIf provider and host do not line up, `doctor` will call that out. That is intentional and usually means the URL or the provider field needs a quick review.\n\n## Troubleshooting\n\n- If mirror mode fails in a non-interactive shell, pass `--yes`.\n- If HTTPS remotes fail, try a token-based URL or switch to SSH.\n- If SSH remotes fail, make sure your agent is running and the key is loaded.\n- If `validate` says no remotes are configured, add at least one remote entry.\n- If `doctor` warns about a provider mismatch, check the provider value and the remote host.\n- If `status` shows no history, run `git-ark backup` once with `options.write_metadata: true`.\n\n## Windows Notes\n\n- Use a recent Git for Windows installation.\n- Make sure `git` is on `PATH`.\n- Forward-compatible SSH URLs like `git@github.com:org/repo.git` work well.\n- If you rely on SSH, make sure an agent is running and your key is loaded.\n\n## Security\n\n- Secrets are never printed intentionally.\n- HTTPS credentials in URLs are redacted in output.\n- Mirror mode can delete refs on the destination, so it requires explicit confirmation.\n- This tool shells out to the installed `git` binary; it does not implement a custom Git protocol client.\n\n## Limitations\n\n- v1 does not remove local remotes.\n- v1 does not implement a custom Git protocol client.\n- v1 does not attempt to reconcile remote history beyond the selected push mode.\n- Archived-branch handling is still limited to configuration and planning.\n- Full Git LFS backup is not implemented; `skip_lfs` only skips smudge downloads during preflight fetch/pull.\n\n## GitHub Actions\n\n- [`.github/workflows/ci.yml`](./.github/workflows/ci.yml) runs tests, vet, and build on Linux, macOS, and Windows.\n- [`.github/workflows/release.yml`](./.github/workflows/release.yml) builds tagged binaries for Linux, macOS, and Windows and publishes GitHub Releases.\n- [`.github/workflows/pages.yml`](./.github/workflows/pages.yml) deploys the docs site to GitHub Pages from `docs/`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsphireinc%2Fgit-ark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsphireinc%2Fgit-ark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsphireinc%2Fgit-ark/lists"}