Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git - Pushing code to two remotes [duplicate]

Tags:

git

github

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 ?

like image 368
yasith Avatar asked Jan 12 '13 04:01

yasith


People also ask

Can git push to multiple remotes?

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.

Does git push push to all remotes?

Running git pushall will now push all branches to all remotes.

Can we have multiple origins in git?

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.

How do I add a second remote to git?

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.


2 Answers

In recent versions of Git you can add multiple pushurls for a given remote. Use the following to add two pushurls 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 pushurls 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 pushurls 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.

like image 95
jweyrich Avatar answered Oct 07 '22 12:10

jweyrich


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.

like image 26
William Seiti Mizuta Avatar answered Oct 07 '22 11:10

William Seiti Mizuta