10

I am the process of writing an update script, which pulls the latest version of a number of repositories, and rebuilds the projects. I wanted to make the build conditional, so I tried

hg pull -u && ant clean build

and the variation

hg pull; hg update && ant clean build

However, the ant build is always invoked, even when nothing has changed. I know that I can use hg incoming to check for changes before doing the pull, but this feels wasteful to me.

How can I check for new changes, without having to contact the server twice (once for hg incoming, once for hg pull)?

UPDATE: This is my build script now:

update() {
  TIP=$(hg tip --template "{node"})
  hg pull -u
  if test "$TIP" != $(hg tip --template "{node}"); then
    ant clean build
  fi
}

(cd repo1; update )
(cd repo2; update )

And for people wondering why I do a clean build every time, there are two reasons for that:

  1. The repositories depend on each other, and when the API in one of them changes, I need to do a full rebuild to find places where these API changes break code
  2. The Java compiler inlines constants, also from other class files. Now, when I change a constant in a class back to a field that can change, all other class files using that constant remain untouched by a build, and this can lead to subtle bugs that I want to avoid.
Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
daniel kullmann
  • 13,653
  • 8
  • 51
  • 67

1 Answers1

10

You should not just run hg incoming twice since it will actually download all the changesets twice then. This because you cannot just take a sneak peek at the remote repository without running a full hg pull.

So save the incoming changesets in a bundle and pull from that instead:

hg incoming --bundle incoming.hg && hg pull --update incoming.hg && echo "Go!"

The hg incoming command acts as a guard for the following commands: the && is short-circuiting so the first command that return a non-zero exit code will make the whole construct fail with that exit code. This means that hg pull and any following commands aren't executed at all when hg incoming signals that there is nothing to pull.

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
  • 2
    He wasn't actually calling incoming twice. But I didn't realise that incoming downloads the full changeset, so doing an incoming and pull is in effect downloading things twice. – Adam Houldsworth Jan 19 '12 at 11:59
  • Strange, `hg pull --update && echo "Go"` always does the `echo`, but `hg pull --update incoming.hg && echo "Go"` only when new changes are introduced. Is there any reason for that? – daniel kullmann Jan 19 '12 at 12:08
  • @AdamHouldsworth: Yeah, incoming and pull are really the same thing (incoming just throws away the changesets). The documentation is not very clear on this, so you cannot be blamed for thinking that it's cheap to run incoming. – Martin Geisler Jan 19 '12 at 12:39
  • @danielkullmann: that also baffled me at first, since it shouldn't matter where pull retrieves the changesets from. And it does't matter: it just looks like that at a first glance. I've updated the answer to explain this. – Martin Geisler Jan 19 '12 at 13:00