Pushing to multiple git repos

Scope

How to push a git repo to multiple remote repositories, such as GitLab & BitBucket, with a single command.

Background

I’ve been using BitBucket, which offers unlimited private repositories for free, to backup my git repos in the cloud.

Recently I switched to GitLab. They offer a similar service, also for free, but with a nicer UI. In particular, GitLab can search inside files, not just the filenames. This feature is curiously missing from BitBucket, although it was logged back in 2011.

Unfortunately, GitLab’s shiny UI baulks when confronted with my notes repository: a single folder containing several hundred markdown files. BitBucket, meanwhile, handles it without a hitch.

I wanted to keep both repos updated so that I can use whichever service is more useful for a given task. Having redundant copies of my files also offers some peace of mind.

Method

Set up the remote repos

I use the web interface of GitLab and BitBucket to set up the repositories. There are some CLI tools available, but I haven’t tried them.

The URLs for the common hosting services are identical, except for the domain:

BitBucketgit@bitbucket.org:namespace/repo.git
GitHubgit@github.com:namespace/repo.git
GitLabgit@gitlab.com:namespace/repo.git

To prevent your being asked for passwords when pushing, make sure to set up SSH access for each service.

Configure your local repo

The basic idea is to add multiple “push URLs” to a single remote alias. The confusing bit (but it’s a feature, not a bug) is that these URLs override a repo’s default URL when pushing.

Let’s say that you have created an alias called origin to your main remote repository (in my case this would be on GitLab):

git remote add origin .com:namespace/repo.git

To push to multiple repositories you need to add push URLs for all repositories. For example:

git remote set-url --add --push origin .com:namespace/repo.git
git remote set-url --add --push origin .org:namespace/repo.git

These commands will add push URLs for both GitLab and BitBucket, even though I already have set up GitLab as a remote repo.

If you prefer, you can make the changes directly in your repo’s .git/config.

After the above commands it would look something like this:

[remote "origin"]
	url = .com:namespace/repo.git
	fetch = +refs/heads/*:refs/remotes/origin/*
	pushurl = .com:namespace/repo.git
	pushurl = .org:namespace/repo.git

The configuration file makes clear what is going on with the URLs.

Pushing & pulling

Once you’ve set this up, git push commands will push to all repos you’ve defined with pushurls.

For example, git push --all -u will push all your local branches and set up tracking.

Note that you’ll only be pulling from the main repository (once again, it’s a feature, not a bug).

Caveats

I’ve been using this technique for private repos where I am the only user. But I don’t anticipate any issues if multiple people are pushing changes, as long as everyone is pushing and fetching from the main repository. Even Linus does this (or at least he did in 2006, though the setup was a bit different at the time). And the only horror story I’ve found had to do with post-hooks.

It would be more efficient to push the local changes to only one remote repo and then set up a post-commit hook to push the changes to other repositories. But as far as I can tell it’s not possible with BitBucket or the freely hosted version of GitLab.

Update (21 January 2015)

Last week GitLab released a new UI. Not only does the new release look great, it now handles my numerous markdown files without breaking a sweat. Hurrah!


Further reading on Stack Overflow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值