If a project has to have multiple git repos (e.g. Bitbucket and Github) then it's better that they remain in sync.
Usually this would involve pushing each branch to each repo in turn, but actually Git allows pushing to multiple repos in one go.
If in doubt about what git is doing when you run these commands, just
edit .git/config
(git-config(1)) and see what it's put there.
Suppose your git remotes are set up like this:
git remote add github git@github.com:muccg/my-project.git git remote add bb git@bitbucket.org:ccgmurdoch/my-project.git
The origin
remote probably points to one of these URLs.
To set up the push URLs do this:
git remote set-url --add --push origin git@github.com:muccg/my-project.git git remote set-url --add --push origin git@bitbucket.org:ccgmurdoch/my-project.git
It will change the remote.origin.pushurl
config entry. Now pushes
will send to both of these destinations, rather than the fetch URL.
Check it out by running:
git remote show origin
A branch can push and pull from separate remotes. This might be useful
in rare circumstances such as maintaining a fork with customizations
to the upstream repo. If your branch follows github
by default:
git branch --set-upstream-to=github next_release
(That command changed branch.next_release.remote
.)
Then git allows branches to have multiple branch.<name>.pushRemote
entries. You must edit the .git/config
file to set them.
You can't pull from multiple remotes at once, but you can fetch from all of them:
git fetch --all
Note that fetching won't update your current branch (that's why
git-pull
exists), so you have to merge -- fast-forward or
otherwise.
For example, this will octopus merge the branches if the remotes got out of sync:
git merge github/next_release bb/next_release
It seems to work but doesn't actually sync the two repos for me.
My git config looks like this:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@github.com:redacted
fetch = +refs/heads/:refs/remotes/origin/
pushurl = git@github.com:redacted
pushurl = myuser@trac:redacted
[branch "main"]
remote = origin
merge = refs/heads/main
[remote "github"]
url = git@github.com:redacted
fetch = +refs/heads/:refs/remotes/github/
[remote "trac"]
url = myuser@trac:redacted
fetch = +refs/heads/:refs/remotes/trac/
After I commit and then do
git push
I see:Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 325 bytes | 325.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:redacted
5bc92c5..d7eaa99 main -> main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 325 bytes | 325.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
To trac:redacted
5bc92c5..d7eaa99 main -> main
Looks great! It says it pushed to both repos and from the output it looks like it did identical operations on both repos. But the changes are NOT on the "trac" repository.
Even when I try to compare trac separately with
git fetch trac
andgit pull trac main
, it tells me "Already up to date." but the trac repo is definitely out of sync with what I have in my local file system.My 'Github' repo is fine! I must be missing something. Can anyone see my problem?