The problem
Assume that you had a repo that was hosted on github, and you decided that for some reason you would like to have a copy of your repo on gitlab as well. Perhaps the obvious solution would be to add another remote to your git config.
$ git remote add gitlab [email protected]/username/my-repo.git
Pushing to both repos would then be achieved as follows:
$ git push origin main
$ git push gitlab main
Remembering to run both these commands every time you wanted to push your changes seems like a tall ask. The good new is that you can get the desired behaviour with just a single command that's likely already part of your muscle-memory:
$ git push origin main
The solution
A good place to start implementing our solution to this problem would be to check for existing remotes.
$ git remote -v
The above command lists out our fetch and push remotes, which may look something like this:
origin [email protected]:username/my-repo.git (fetch)
origin [email protected]:username/my-repo.git (push)
For the superstitious amongst us, you can optionally clear and re-add the origin
remote.
$ git remote remove origin
$ git remote add origin [email protected]:username/my-repo.git
We now have one push and one pull URL. The solution to our problem lies in setting a second push URL as shown:
$ git remote set-url --add --push origin [email protected]:username/my-repo.git
To wrap up, we then set the upstream branch of our choosing (main
in this case).
$ git fetch origin main
$ git branch --set-upstream-to origin/main
From now on, whenever we run git push origin main
, git will push our changes to both remote repositories (github and gitlab). Fetching or pulling changes from origin will always refer to just the one repo (github).
Bonus points
As a final touch, we can give both of our repo hosts a unique name in case we ever need to explicitly push or fetch from a particular one.
$ git remote add github [email protected]:username/my-repo.git
$ git remote add gitlab [email protected]:username/my-repo.git
Once this is done, listing our remotes with git remote -v
gives the following output:
github [email protected]:username/my-repo.git (fetch)
github [email protected]:username/my-repo.git (push)
gitlab [email protected]:username/my-repo.git (fetch)
gitlab [email protected]:username/my-repo.git (push)
origin [email protected]:username/my-repo.git (fetch)
origin [email protected]:username/my-repo.git (push)
origin [email protected]:username/my-repo.git (push)