# HG changeset patch # User Pierre-Yves David # Date 1433223241 25200 # Node ID b5311068077e45ccc579218c038c8f10fbb13288 # Parent 1457c1f28c92d5573132c3e197e3bbfff09f3e29 pull: prevent race condition in bookmark update when using -B (issue4689) We are already fetching remote bookmarks to honor the -B option, we now pass that data to the pull process so it can reuse it. This prevents a race condition between the initial looking and the actual pulling of changesets and bookmarks. Tests are updated to handle this fact. diff -r 1457c1f28c92 -r b5311068077e mercurial/commands.py --- a/mercurial/commands.py Tue Jun 02 00:43:11 2015 -0700 +++ b/mercurial/commands.py Mon Jun 01 22:34:01 2015 -0700 @@ -5129,6 +5129,7 @@ # not ending up with the name of the bookmark because of a race # condition on the server. (See issue 4689 for details) remotebookmarks = other.listkeys('bookmarks') + pullopargs['remotebookmarks'] = remotebookmarks for b in opts['bookmark']: if b not in remotebookmarks: raise util.Abort(_('remote bookmark %s not found!') % b) diff -r 1457c1f28c92 -r b5311068077e mercurial/exchange.py --- a/mercurial/exchange.py Tue Jun 02 00:43:11 2015 -0700 +++ b/mercurial/exchange.py Mon Jun 01 22:34:01 2015 -0700 @@ -808,7 +808,8 @@ afterward. """ - def __init__(self, repo, remote, heads=None, force=False, bookmarks=()): + def __init__(self, repo, remote, heads=None, force=False, bookmarks=(), + remotebookmarks=None): # repo we pull into self.repo = repo # repo we pull from @@ -828,7 +829,7 @@ # list of missing changeset to fetch remotely self.fetch = None # remote bookmarks data - self.remotebookmarks = None + self.remotebookmarks = remotebookmarks # result of changegroup pulling (used as return code by pull) self.cgresult = None # list of step already done diff -r 1457c1f28c92 -r b5311068077e tests/test-bookmarks-pushpull.t --- a/tests/test-bookmarks-pushpull.t Tue Jun 02 00:43:11 2015 -0700 +++ b/tests/test-bookmarks-pushpull.t Mon Jun 01 22:34:01 2015 -0700 @@ -308,6 +308,43 @@ Y 4:b0a5eff05604 Z 1:0d2164f0ce0d +Update a bookmark right after the initial lookup -B (issue4689) + + $ echo c6 > ../pull-race/f3 # to be committed during the race + $ cat < ../pull-race/.hg/hgrc + > [hooks] + > # If anything to commit, commit it right after the first key listing used + > # during lookup. This makes the commit appear before the actual getbundle + > # call. + > listkeys.makecommit= ((hg st | grep -q M) && (hg commit -m race; echo commited in pull-race)) || exit 0 + > EOF + +(new config need server restart) + + $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS + $ hg -R ../pull-race serve -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log + $ cat ../pull-race.pid >> $DAEMON_PIDS + + $ hg -R $TESTTMP/pull-race book + @ 1:0d2164f0ce0d + X 1:0d2164f0ce0d + * Y 5:35d1ef0a8d1b + Z 1:0d2164f0ce0d + $ hg pull -B Y + pulling from http://localhost:$HGPORT/ + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating bookmark Y + (run 'hg update' to get a working copy) + $ hg book + * @ 1:0d2164f0ce0d + X 1:0d2164f0ce0d + Y 5:35d1ef0a8d1b + Z 1:0d2164f0ce0d + (done with this section of the test) $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS diff -r 1457c1f28c92 -r b5311068077e tests/test-hook.t --- a/tests/test-hook.t Tue Jun 02 00:43:11 2015 -0700 +++ b/tests/test-hook.t Mon Jun 01 22:34:01 2015 -0700 @@ -253,7 +253,6 @@ listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} no changes found listkeys hook: HG_NAMESPACE=phase HG_VALUES={} - listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} adding remote bookmark bar listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'} $ cd ../a