$ hg init master $ cd master; touch a; hg ci -Am "a"; hg book book1; cd .. $ hg clone master slave $ echo "[hooks]\nchangegroup = echo Press Enter to finish pulling; read -r DUMMY" >> slave/.hg/hgrc $ cd master; touch b; hg ci -Am "b"; cd .. $ cd slave $ hg pull This will pull in b, then pause until you press Enter. In a different terminal (or using job control): $ cd ../master; touch c; hg ci -Am "c" Now resume the slave pull. Note that the bookmark didn't get moved at all on the slave, not even to b. We're hitting this at FB with large pulls, where the master bookmark on the server gets updated in the middle of the pull. The master bookmark on the client doesn't get updated at all. Seems like a fix would be to either do the bookmark determination simultaneously with the changeset determination, or to do it before pulling in changesets if possible.
FYI, you can actually do the racing commit in the hook. We use similar tricks in various places in the test suite to test similar races.
Not sure what we can do about this short of making this happen: http://mercurial.selenic.com/wiki/BundleFormat2
What about figuring out bookmarks before pulling in changesets? If the changeset corresponding to that bookmark does get pulled in, we move the bookmark forward. That would leave a much smaller race window.
That's probably feasible.
Fixed by http://selenic.com/repo/hg/rev/a60963c02f92 Siddharth Agarwal <sid0@fb.com> pull: list bookmarks before pulling changesets (issue3873) Consider a bookmark B that exists both locally and remotely. If B is updated remotely, and then a pull is performed where the pull set contains the new location of B, the bookmark is updated locally. However, if remote B is updated in the middle of a pull to a location not in the pull set, the bookmark won't be updated locally at all. To fix this, list bookmarks before pulling in changesets, not after. This still leaves a race open if B gets moved in between listing bookmarks and pulling in changesets, but the race window is much smaller. Fixing the race properly would require a bundle format upgrade. test-hook.t's output changes because we no longer do two listkeys calls during pull, just one. test-pull-http.t's output changes because we now search for bookmarks before searching for changes. (please test the fix)