Git: push the same code to GitHub and GitLab from a single local repo (remote called remote)#
Do you want a single local repo and to push to GitHub and GitLab without breaking anything?
Here’s a quick guide with zero drama. 😎
🎯 Goal#
Have one local repository and keep two remote repositories with the same code:
- Repo 1: GitHub
- Repo 2: GitLab
- The “main” remote in your local repo might be called
origin(notremote).
Also:
- Know when and how to push only to GitHub, only to GitLab, or to both.
- Learn how to sync branches (and optionally tags) so both remotes stay aligned.
🗺️ Conventions used in this guide#
Replace these URLs with yours:
- GitHub:
https://github.com/<org>/<repo>.git - GitLab:
https://gitlab.com/<org>/<repo>.git
Main branch: main (if you use master, replace main with master in all commands).
✅ 1) Initial state (or verification)#
In your local repo, list remotes:
git remote -vIf a remote called remote already exists, you’ll see something like:
remote https://github.com/<org>/<repo>.git (fetch)
remote https://github.com/<org>/<repo>.git (push)If it doesn’t exist, you’ll create it in the next step. Easy.
🔗 2) Configure remotes for GitHub + GitLab#
Case A: You don’t have the remote remote yet#
Configure it pointing to GitHub first (or GitLab if you prefer):
git remote add remote https://github.com/<org>/<repo>.gitNow add explicit remotes so you can separate pushes when needed:
git remote add github https://github.com/<org>/<repo>.git
git remote add gitlab https://gitlab.com/<org>/<repo>.gitYes: you’ll have three names (remote, github, gitlab) on purpose.github and gitlab are for selective pushes, and remote is the alias to push to both.
Verify:
git remote -vCase B: You already have remote and want to add GitLab#
First create explicit remotes:
git remote add github https://github.com/<org>/<repo>.git
git remote add gitlab https://gitlab.com/<org>/<repo>.gitThen we’ll adjust remote so it can push to both (below).
🚀 3) Split the push: repo1, repo2, and both#
Here’s the important part. We’ll go through the three modes:
Mode 1 — Push ONLY to GitHub (repo1)#
git push github mainWhen to use it:
- If GitHub is the “main” repo (PRs, checks, releases).
- If you want to test on one remote and not touch the other yet.
Mode 2 — Push ONLY to GitLab (repo2)#
git push gitlab mainWhen to use it:
- If GitLab is used for internal pipelines.
- If you want to update the mirror without affecting GitHub.
Mode 3 — Push to BOTH with one command (using remote)#
We’ll configure remote to push to two URLs.
3.1 Configure remote with multiple push URLs#
First make sure you have remote created:
git remote add remote https://github.com/<org>/<repo>.gitNow add two push URLs to remote:
git remote set-url --add --push remote https://github.com/<org>/<repo>.git
git remote set-url --add --push remote https://gitlab.com/<org>/<repo>.gitOptional (and recommended): set the fetch URL of remote to a single one (for example GitHub):
git remote set-url remote https://github.com/<org>/<repo>.gitVerify:
git remote -vYou should see remote with one fetch and two pushes (sometimes listed twice for push).
3.2 Push to both#
git push remote mainWhen to use it:
- When GitHub and GitLab must always be in sync at the same time.
- When you’re running an operational “mirror” (without cloning duplicate repos).
Note: If one push fails (permissions, branch protection, etc.), Git will tell you.
The other may have gone through, so check the command output. 👀
🔁 4) Sync branches (so GitHub and GitLab stay identical)#
True sync boils down to this: push the same branches to both remotes.
4.1 Sync a specific branch (e.g., main)#
To GitHub:
git push github mainTo GitLab:
git push gitlab mainTo both (if you configured remote with two push URLs):
git push remote main4.2 Sync ALL local branches to the remote#
To GitHub:
git push github --allTo GitLab:
git push gitlab --all✅ Mini visual checklist#
- I have
remote,github, andgitlabcreated. - I know when to push to one or the other.
- I can push to both with
git push remote main. - My branches are synced on both remotes.
To both:
git push remote --allWhat does --all do?
Pushes all local branches (not tags).
Very useful when you’re setting up the mirror for the first time.
4.3 Sync tags (recommended if you do releases)
Tags are NOT included with --all. For tags:
To GitHub:
git push github --tagsTo GitLab:
git push gitlab --tagsTo both:
git push remote --tags4.4 Typical full sync (branches + tags)
To leave both remotes identical, you usually do:
git push remote --all
git push remote --tags- Best practices and typical gotchas
Branch protection
If main is protected (very common), you may find:
GitHub only allows push via PR, and GitLab too.
Then direct push will fail on one or both.
Solution: push a feature branch and open a PR/MR on each platform, or decide one as the “source of truth.”
Source of truth
Decide whether:
GitHub is the source of truth and GitLab is a mirror, or vice versa.
Avoid having divergent changes in both (for example, independent merges on each). If you do, you’ll end up with conflicts or different histories.
Pushing “to both” is powerful… and dangerous
Use remote (double push) when you’re clear that:
the same rules (protections) apply,
and you want permanent sync.
If not, use separate pushes (github / gitlab) to control timing.
- Quick checklist (operational procedure)
Setup (one time)
Create github and gitlab remotes
Configure remote to push to both
Daily operation
Only GitHub:
git push github <branch>Only GitLab:
git push gitlab <branch>Both:
git push remote <branch>Sync everything
git push remote --all
git push remote --tags- Final verification: check that everything is aligned
List the remote branches your local sees:
git fetch --all --prune
git branch -rYou should see something like:
github/main
gitlab/main
...If you see differences (branches that exist on one remote and not the other), repeat push --all to the missing one.
Conclusion
With this setup:
github and gitlab give you fine-grained control (selective push).
remote lets you do a “single push” to both when you’re sure they must stay synced.
For full sync: --all + --tags.