diff mercurial/commands.py @ 18851:a60963c02f92

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.
author Siddharth Agarwal <sid0@fb.com>
date Fri, 29 Mar 2013 19:54:06 -0700
parents cc741817a49e
children f02045645d12
line wrap: on
line diff
--- a/mercurial/commands.py	Fri Mar 29 19:52:02 2013 -0700
+++ b/mercurial/commands.py	Fri Mar 29 19:54:06 2013 -0700
@@ -4496,10 +4496,11 @@
     ui.status(_('pulling from %s\n') % util.hidepassword(source))
     revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
 
+    remotebookmarks = other.listkeys('bookmarks')
+
     if opts.get('bookmark'):
         if not revs:
             revs = []
-        remotebookmarks = other.listkeys('bookmarks')
         for b in opts['bookmark']:
             if b not in remotebookmarks:
                 raise util.Abort(_('remote bookmark %s not found!') % b)
@@ -4514,7 +4515,7 @@
             raise util.Abort(err)
 
     modheads = repo.pull(other, heads=revs, force=opts.get('force'))
-    bookmarks.updatefromremote(ui, repo, other, source)
+    bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
     if checkout:
         checkout = str(repo.changelog.rev(other.lookup(checkout)))
     repo._subtoppath = source