Ya' row ze: Lets go!

You are here

bulk pushing branches to multiple remotes

We use git as a deployment tool as well as a repo. This is all thanks to GIT's new "receive.denyCurrentBranch updateInstead" option which we set at the destination webserver. With that set, we can push directly to that clone instance, and git will just update the working copy with any new commits pushed.

The two main challenges here are: 1) how do you push all branches? 2) how do you push to all remotes except origin?

Pushing all branches.

Initially we had an interative loop that checked out each branch at origin to local, then did a git push --all. It looked something like this:

git branch -a|grep remotes/origin|sed 's/remotes\/origin\/(.*?)/git checkout -B \1/'|sh
git push [remote] --all

This has a lot of overhead because it creates a local branch each time, leaves the repo on that local branch, and can cause strange branch naming behavior at the destination.

I had seen a lot of information about "REFS", but it was relatively convoluted and unclear how these worked and what they were doing. Ultimately I finally tracked down a solution using git push with proper refs, and it makes things a lot easier:

git push [remote] remotes/origin/*:refs/heads/*

Thats it! w/o doing any crazy branch switching, I was able to push all of the branches from origin to the destination repo.

Pushing to all remotes
The next part of this is to send the updates from origin to all of the remotes listed in the repo. This is a much cleaner process than the earlier command.
one of the key items here is that we do not want to push to origin because we just got updates from origin, and it's possible that we might do things to the branches in a different process. putting a simple 'grep -v origin' in the process makes sure that we get and iterate through every remote except for origin.

git remote origin update
git remote|grep -v origin|sed 's/.*/git push \0 remotes\/origin\/*:refs\/heads\/* \&/'|sh

this keeps things much cleaner, and running a lot faster. Also the \& at the end of the command should make the push to all remotes asynchronous, making this an even faster process.

Back to top