I have two remote git repositories. origin
and github
I push my branch devel
to both repositories.
git push -u origin devel git push -u github devel
But then, when I do. git push
It would only get pushed to github
.
Is there anyway I can set up my two remotes, so that I can push changes to both repositories with one command ?
It is easy to synchronize code between multiple git repositories, especially, pushing to multiple remotes. This is helpful when you're maintaining mirrors / copies of the same repository. All you need to do is set up multiple push URLs on a remote and then perform git push to that remote as you usually do.
Running git pushall will now push all branches to all remotes.
You can have as many remote repositories as you want, but you must give them different names. The repository name is different in this case. Is the the word "origin" a name that can be changed? Yep, git remote rename <old> <new> : linux.die.net/man/1/git-remote.
To add a new remote, use the git remote add command on the terminal, in the directory your repository is stored at. The git remote add command takes two arguments: A unique remote name, for example, “my_awesome_new_remote_repo” A remote URL, which you can find on the Source sub-tab of your Git repo.
In recent versions of Git you can add multiple pushurl
s for a given remote. Use the following to add two pushurl
s to your origin
:
git remote set-url --add --push origin git://original/repo.git git remote set-url --add --push origin git://another/repo.git
So when you push to origin
, it will push to both repositories.
UPDATE 1: Git 1.8.0.1 and 1.8.1 (and possibly other versions) seem to have a bug that causes --add
to replace the original URL the first time you use it, so you need to re-add the original URL using the same command. Doing git remote -v
should reveal the current URLs for each remote.
UPDATE 2: Junio C. Hamano, the Git maintainer, explained it's how it was designed. Doing git remote set-url --add --push <remote_name> <url>
adds a pushurl
for a given remote, which overrides the default URL for pushes. However, you may add multiple pushurl
s for a given remote, which then allows you to push to multiple remotes using a single git push
. You can verify this behavior below:
$ git clone git://original/repo.git $ git remote -v origin git://original/repo.git (fetch) origin git://original/repo.git (push) $ git config -l | grep '^remote\.' remote.origin.url=git://original/repo.git remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
Now, if you want to push to two or more repositories using a single command, you may create a new remote named all
(as suggested by @Adam Nelson in comments), or keep using the origin
, though the latter name is less descriptive for this purpose. If you still want to use origin
, skip the following step, and use origin
instead of all
in all other steps.
So let's add a new remote called all
that we'll reference later when pushing to multiple repositories:
$ git remote add all git://original/repo.git $ git remote -v all git://original/repo.git (fetch) <-- ADDED all git://original/repo.git (push) <-- ADDED origin git://original/repo.git (fetch) origin git://original/repo.git (push) $ git config -l | grep '^remote\.all' remote.all.url=git://original/repo.git <-- ADDED remote.all.fetch=+refs/heads/*:refs/remotes/all/* <-- ADDED
Then let's add a pushurl
to the all
remote, pointing to another repository:
$ git remote set-url --add --push all git://another/repo.git $ git remote -v all git://original/repo.git (fetch) all git://another/repo.git (push) <-- CHANGED origin git://original/repo.git (fetch) origin git://original/repo.git (push) $ git config -l | grep '^remote\.all' remote.all.url=git://original/repo.git remote.all.fetch=+refs/heads/*:refs/remotes/all/* remote.all.pushurl=git://another/repo.git <-- ADDED
Here git remote -v
shows the new pushurl
for push, so if you do git push all master
, it will push the master
branch to git://another/repo.git
only. This shows how pushurl
overrides the default url (remote.all.url).
Now let's add another pushurl
pointing to the original repository:
$ git remote set-url --add --push all git://original/repo.git $ git remote -v all git://original/repo.git (fetch) all git://another/repo.git (push) all git://original/repo.git (push) <-- ADDED origin git://original/repo.git (fetch) origin git://original/repo.git (push) $ git config -l | grep '^remote\.all' remote.all.url=git://original/repo.git remote.all.fetch=+refs/heads/*:refs/remotes/all/* remote.all.pushurl=git://another/repo.git remote.all.pushurl=git://original/repo.git <-- ADDED
You see both pushurl
s we added are kept. Now a single git push all master
will push the master
branch to both git://another/repo.git
and git://original/repo.git
.
IMPORTANT NOTE: If your remotes have distinct rules (hooks) to accept/reject a push, one remote may accept it while the other doesn't. Therefore, if you want them to have the exact same history, you'll need to fix your commits locally to make them acceptable by both remotes and push again, or you might end up in a situation where you can only fix it by rewriting history (using push -f
), and that could cause problems for people that have already pulled your previous changes from the repo.
To send to both remote with one command, you can create a alias for it:
git config alias.pushall '!git push origin devel && git push github devel'
With this, when you use the command git pushall
, it will update both repositories.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With