# git-mirror ![Logo](./docs/icons/256x256/git-mirror.png) Small Bash utility for mirroring a directory of local Git repositories to GitHub, GitLab, and Codeberg. The repository currently contains a single script, `git-mirror`, which: - scans a source directory for both standard repositories and bare repositories - creates missing remote repositories on GitHub, GitLab, and Codeberg - configures per-repository mirror remotes - pushes branches and tags to each target service ## Requirements - Bash - `git` - `curl` - `realpath` - `sed` - `grep` - `pass` for retrieving access tokens - SSH access configured for GitHub, GitLab, and Codeberg ## Configuration Edit the variables near the top of the script: ```bash SOURCE_DIR="$(realpath "data/small/gitea/git/repositories/sean")" THIRD_PARTY_GIT_USER="seanhly" GITHUB_TOKEN="$(pass github-token)" GITLAB_TOKEN="$(pass gitlab-token)" CODEBERG_TOKEN="$(pass codeberg-token)" ``` What each value does: - `SOURCE_DIR`: directory containing the repositories to mirror - `THIRD_PARTY_GIT_USER`: account or namespace used on all three services - `GITHUB_TOKEN`: GitHub personal access token used for repository creation - `GITLAB_TOKEN`: GitLab personal access token used for repository creation - `CODEBERG_TOKEN`: Codeberg token used for repository creation The script expects repository creation to happen over each service's HTTP API, but pushes happen over SSH. That means the tokens must be valid for API access and your local SSH keys must already be authorized on each hosting provider. ## Usage Make the script executable if needed: ```bash chmod +x ./git-mirror ``` Run it from the repository root: ```bash ./git-mirror ``` ## What It Mirrors The script handles both of these layouts inside `SOURCE_DIR`: - non-bare repositories: directories containing a `.git/` subdirectory - bare repositories: directories ending in `.git` For each repository it will: 1. create the remote repository if it does not already exist 2. replace any existing `github-mirror`, `gitlab-mirror`, and `codeberg-mirror` remotes 3. push repository contents to each service GitHub uses `git push --mirror`, which mirrors all refs. GitLab and Codeberg use explicit branch and tag pushes with prune enabled: ```bash git push --prune 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*' ``` ## Operational Notes - The script adds each processed repository to Git's global `safe.directory` list. - Remote repository creation is currently hard-coded as private on all providers. - Existing mirror remotes are removed and re-added on every run. - The script assumes the same username or namespace is valid on GitHub, GitLab, and Codeberg. ## Caution Run this only when you intend to synchronize local state to the target remotes. - `git push --mirror` can overwrite or delete remote refs that do not exist locally. - `--prune` on GitLab and Codeberg will remove remote branches that no longer exist locally. - Repository creation and push failures are only partially checked; review terminal output after each run. ## License This project is licensed under the GNU General Public License, version 3. See `LICENSE` for the full text.