tags:

views:

72

answers:

3

Hi, How can we push code to multiple servers? We have many servers which needs to have the same copy of the code. It is difficult to push to individual server. I know mercurial has hooks but none of them gives a proper solution.

+1  A: 

In your .hg/hgrc file you should have a [paths] directive, which contains your default location. What about adding something like:

[paths]
default = http://server1
server2 = http://server2

And then do a:

hg push default
hg push server2
Roberto Aloi
yes that's the problem. I know this solution, what I want is a hook or a trigger that on a successful push to server1, push to server2 is automatically initiated. The above solution always has a chance of forgetting to push to one server. By the way, thanks for a quick reply.
+3  A: 

In your central server you create an changegroup hook.

So your central server would have the following hgrc:

[paths]
server2=http://server2
server3=http://server3
[hooks]
server2.changegroup = hg push -f server2
server3.changegroup = hg push -f server3

You can have multiple hooks for the same event, so that shouldn't be an issue.
The advantage of the changegroup hook over the changeset hook is that it is run far less often.

Ton
This one's the best solution because it will only be triggered if the push to server 1 succeeded. You'll probably need 'push -f' in those changegroup hook lines if you're working with branchy histories.
Ry4an
Added -f option
Ton
A: 

i assume that one of the servers is a master repo, the rest are deployments. in such a situation, i would interact with just the master and leave the deployments up to cron:

cat >$HOME/bin/dist <<'EOM'
#!/bin/sh
cd ${1:?}
tip=$(hg tip --template '{node}')
for r in $remotes; do
  hg push -r $tip $r
done
EOM

chmod +x $HOME/bin/dist
(crontab -l; echo '*/5 * * * * $HOME/bin/dist /var/repos/master') | crontab -
just somebody
huh.. what will happen if more than one commit has been pushed in less than 5 mn? :-). In this case it's better to setup a "changegroup" hook. Also when a changeset is creating a branch, it would be necessary to push with the -f option (force). My advice, if you want to use cron instead of a hook, would be to set it up on the remote machines which would regularly pull changes: this way, there can be more than one changeset pulled (so you can even pull every hours for example), and also pull does not require the -f option. Just my 0.02€. Cheers, Christophe.
Christophe Muller
@just somebody's solution works fine. 'push' pushes 'tip' and all of its ancestors, so they'll get everything. There's a lot of unecessary code though, you can use the name 'tip' instead of using the template to learn it (-r takes names just fine), and you can skip the -r param all together and just do 'push' which defaults to tip. You probably want push -f though since you may need to push new branches and new heads at some point and you don't want the script failing.
Ry4an
@ry4an: you cannot use the name `tip`, since it could point to a different changeset before the script gets from server1 to server3. that's just the reason why you cannot just leave out the `-r`: if you want all the mirrors to have the same tip after each push, you need to stick to the same revision for the whole script. the `-f` comment is valid, though.
just somebody