tags:

views:

1393

answers:

4

Short: is there a way to have a git repo push to and pull from a list of remote repos (rather than a single "origin")?

The long: I often have a situation when I'm developing an app in multiple computers, with different connectivity -- say a laptop while on transit, a computer "A" while I'm in a certain location, and another computer "B" while on another. Also, the laptop might have connectivity with only either "A" or "B", and sometimes both.

What I would like to is for git to always "pull" from and "push" to all the computers it can currently connect to, so it's easier to jump from one machine to the other and continue working seamlessly.

+2  A: 

You'll need a script to loop through them. Git doesn't a provide a "push all." You could theoretically do a push in multiple threads, but a native method is not available.

Fetch is even more complicated, and I'd recommend doing that linearly.

I think your best answer is to have once machine that everybody does a push / pull to, if that's at all possible.

Autocracy
Problem is, as I described, there is no central always available box. If I have to write a looping bash script, so be it, but it feels funny that a distributed VC would not help me more here...
Zorzella
Being distributed, it assumes that not everybody is available, or wanted to be pushed to. It also relates to different repositories being in different states, and the assumption that others are working on them concurrently. The order you push )
Autocracy
+6  A: 

You can configure multiple remote repos with the "git remote" command; for example "git remote add alt alt-machine:/path/to/repo". When you do "git remote update", that will fetch from all the configured remotes and update tracking branches--- but not merge into HEAD. If it's not currently connected to one of them, it will time out or throw an error, and go on to the next. You'll have to manually merge from the fetched repos as you decide is right. Or cherry-pick, or however you want to organise collecting changes. You can also just do for instance "git pull alt master" to fetch the master branch from alt and pull it into your current head. So in fact git pull is almost shorthand for git pull origin HEAD (actually it looks in the config file to determine this, but you get the idea).

For pushing updates, you have to do that to each repo manually. Push was, I think, designed with the central-repository workflow in mind.

araqnid
so what you are saying is that "git remote add foo ssh://foo.bar/baz" creates a shorthand form, but I still need to loop over them with a "git pull", or loop over them with a "git merge" (what's the syntax here, after a "git remove update"?)Won't this shorthand name also work for "git push"? I.e. can't I "git push foo" etc (loop)?Thanks
Zorzella
"git pull" is basically "git fetch" followed by "git merge". "git remote update" just does a bunch of "git fetch" calls for you. So what remains is to do the "git merge" bit.You can say "git merge origin/master" and it will merge origin's version of master into your current HEAD. "git pull origin master" does the same thing, although it will do a fetch first (and if you've already done git remote update, that won't have anything more to fetch, so it's redundant).Yes, you can say "git push foo" and it will push all matching branches to the remote called "foo".
araqnid
+2  A: 

You can add remotes with:

git remote add a urla
git remote add b urlb

Then to update all the repos do:

git remote update
felipec
I tried this and got "fatal: remote origin already exists".
Jauder Ho
Oops, there was a mistake... fixed.
felipec
+3  A: 

This is undocumented, and possibly even a bug, but it’s something I’ve been using for quite a while without bad consequences. araqnid’s solution is the proper one for bringing code into your repository… but when you, like me, have multiple equivalent authoritative upstreams (I keep some of my more critical projects cloned to both a private upstream, GitHub, and Codaset), it can be a pain to push changes to each one, every day.

Long story short, git remote add all of your remotes individually… and then vim .git/config and add a merged‐remote. Assuming you have this repository config:

[remote "GitHub"]
    url = [email protected]:elliottcable/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/GitHub/*
[branch "Master"]
    remote = GitHub
    merge = refs/heads/Master
[remote "Codaset"]
    url = [email protected]:elliottcable/paws-o.git
    fetch = +refs/heads/*:refs/remotes/Codaset/*
[remote "Paws"]
    url = [email protected]:Paws/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/Paws/*

… to create a merged‐remote for "Paws" and "Codaset", I can add the following after all of those:

[remote "Origin"]
    url = [email protected]:Paws/Paws.o.git
    url = [email protected]:elliottcable/paws-o.git

Once I’ve done this, when I git push Origin Master, it will push to both Paws/Master and Codaset/Master sequentially, making life a little easier.

elliottcable
Been wanting to do this for a while, thanks!
gregf