Working with Multiple Git Remotes: Fork, Mirror & Collaborate
In this tutorial, you'll learn about Working with Multiple Git Remotes: Fork, Mirror & Collaborate. We cover key concepts, practical examples, and best practices.
A Git remote is a reference to a remote repository, and you can add multiple remotes to a single clone for syncing forks or mirroring across platforms.
In this tutorial, you'll learn how to manage multiple Git remotes for forking, mirroring, and cross-platform collaboration. Most projects use a single remote, but complex workflows often need two or more — syncing a fork with the original, mirroring to another platform, or working across GitHub and GitLab. By the end, you'll configure, sync, and maintain multiple remotes confidently.
flowchart TD A[Your local clone] --> B[origin: your fork on GitHub] A --> C[upstream: original repo] A --> D[gitlab-mirror: GitLab copy] B --> E[git push origin main] C --> F[git fetch upstream] F --> G[git merge upstream/main] D --> H[git push gitlab-mirror main]
Viewing and Adding Remotes
# View current remotes
git remote -v
# Add an upstream remote (original repo you forked from)
git remote add upstream https://github.com/original-owner/project.git
# Add a mirror remote
git remote add mirror https://gitlab.com/your-username/project.git
Expected output:
origin https://github.com/your-username/project.git (fetch)
origin https://github.com/your-username/project.git (push)
upstream https://github.com/original-owner/project.git (fetch)
upstream https://github.com/original-owner/project.git (push)
mirror https://gitlab.com/your-username/project.git (fetch)
mirror https://gitlab.com/your-username/project.git (push)
Syncing a Fork with Upstream
The most common multi-remote workflow — keeping your fork up to date:
# Fetch latest from upstream
git fetch upstream
# Checkout your main branch
git checkout main
# Merge upstream changes
git merge upstream/main
# Push to your fork
git push origin main
Fetching from Multiple Remotes
# Fetch all remotes
git fetch --all
# Fetch from a specific remote
git fetch upstream
git fetch mirror
Pushing to Multiple Remotes
# Push to origin by default
git push origin main
# Push to mirror as well
git push mirror main
# Set up push to multiple remotes per push
git remote set-url --add --push origin https://github.com/your-username/project.git
git remote set-url --add --push origin https://gitlab.com/your-username/project.git
Now git push origin main pushes to both GitHub and GitLab simultaneously.
Renaming and Removing Remotes
# Rename
git remote rename origin github
# Remove
git remote remove mirror
Mirroring a Repository
For full mirroring (including all branches and tags):
git clone --mirror https://github.com/original/project.git
cd project.git
git remote set-url --push origin https://gitlab.com/your-username/project.git
git push --mirror
Pulling from Multiple Remotes
Manage incoming changes from different sources:
# Fetch from all remotes
git fetch --all
# Check what's new on upstream
git log main..upstream/main --oneline
# Merge upstream changes into your main
git checkout main
git merge upstream/main
# Or rebase your feature branch onto upstream
git checkout feature-branch
git rebase upstream/main
Per-Remote Branch Management
Push different branches to different remotes:
# Push feature branch only to origin
git push origin feature-branch
# Push main branch to multiple remotes
git push origin main
git push mirror main
# Delete a remote branch
git push origin --delete old-feature
Common Errors
| Error | Cause | Fix |
|---|---|---|
fatal: remote upstream already exists |
Remote name taken | Remove and re-add or use different name |
fatal: 'upstream' does not appear to be a git repository |
Wrong URL | Check URL format and permissions |
Permission denied on push |
Wrong credentials | Use SSH keys or check token scope |
refusing to merge unrelated histories |
No common ancestor | Use --allow-unrelated-histories |
push --mirror fails |
Protected branches on target | Disable branch protection temporarily |
Fetch from upstream failed |
Upstream repo deleted or moved | Update remote URL |
| Cannot push to some remotes | Different permissions per remote | Configure per-remote push URLs |
| Remote branch not showing after fetch | Pruned tracking references | git fetch --prune to clean stale refs |
Practice Questions
Challenge
Create a local repository. Add three remotes: origin (your GitHub repo), upstream (a public repo), and mirror (a GitLab repo). Make commits, push to origin. Fetch from upstream. Merge upstream changes. Push to mirror. Remove the mirror remote. Rename upstream to original. Verify all configurations with git remote -v.
Real-World Task
You maintain an open-source project that is hosted on GitHub but needs regular mirroring to GitLab for a client who uses GitLab internally. Set up automated mirroring using a CI/CD pipeline that triggers on pushes to the main branch. The pipeline fetches the latest from GitHub, then pushes to GitLab including tags and all branches. Add a scheduled job that fetches from GitLab too (in case merge requests are made there). This multi-remote mirroring setup is used at DodaTech for clients who require private GitLab mirrors of public GitHub repositories.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro