remotenames: fix pull race conditions

Summary:
We have seen one report that the race condition caused lagged remote/master.

The race condition is:
- pull everything: get all commits, but not remotenames.
- expull: get all remotenames. Some point to new commits received by the
  server that are unknown to the client. The client ignores them.

This diff adds a double check to pull again if it sees remotenames pointing
to unknown nodes.

This won't be necessary if we migrate everyone to selectivepull, and clean up
the pull command to use the race-free repo.pull API. Because the new code path
will first query the bookmarks, then pull the heads explicitly.

Reviewed By: DurhamG

Differential Revision: D20703268

fbshipit-source-id: 42bd0201c3c4f709f25ad0fea3a191db9991e4fc
This commit is contained in:
Jun Wu 2020-04-01 19:36:18 -07:00 committed by Facebook GitHub Bot
parent 5730719bd9
commit e2af876a45

View File

@ -390,6 +390,21 @@ def pullremotenames(repo, remote, bookmarks):
repo = repo.unfiltered()
saveremotenames(repo, {path: bookmarks})
# repo.ui.paths.get(path) might be empty during clone.
if repo.ui.paths.get(path):
# Collect selected bookmarks that point to unknown commits. This
# indicates a race condition.
selected = set(selectivepullbookmarknames(repo, path))
hasnode = repo.changelog.hasnode
movedbookmarks = [
name
for name, hexnode in bookmarks.items()
if name in selected and hexnode and not hasnode(bin(hexnode))
]
# Those bookmarks have moved since pull. Pull them again.
if movedbookmarks:
repo.pull(path, bookmarknames=movedbookmarks)
precachedistance(repo)