comparison mercurial/exchangev2.py @ 39635:349482d726ee

exchangev2: fetch and apply bookmarks This is pretty similar to phases data. We collect bookmarks data as we process records. Then at the end we make a call to the bookmarks subsystem to reflect the remote's bookmarks. Like phases, the code for handling bookmarks is vastly simpler than the previous wire protocol code because the server always transfers the full set of bookmarks when bookmarks are requested. We don't have to keep track of whether we requested bookmarks or not. Differential Revision: https://phab.mercurial-scm.org/D4486
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 29 Aug 2018 17:03:19 -0700
parents ff2de4f2eb3c
children 399ddd3227a4
comparison
equal deleted inserted replaced
39634:9dffa99f9158 39635:349482d726ee
13 from .node import ( 13 from .node import (
14 nullid, 14 nullid,
15 short, 15 short,
16 ) 16 )
17 from . import ( 17 from . import (
18 bookmarks,
18 mdiff, 19 mdiff,
19 phases, 20 phases,
20 pycompat, 21 pycompat,
21 setdiscovery, 22 setdiscovery,
22 ) 23 )
48 if phase == b'secret' or not csetres['nodesbyphase'][phase]: 49 if phase == b'secret' or not csetres['nodesbyphase'][phase]:
49 continue 50 continue
50 51
51 phases.advanceboundary(repo, tr, phases.phasenames.index(phase), 52 phases.advanceboundary(repo, tr, phases.phasenames.index(phase),
52 csetres['nodesbyphase'][phase]) 53 csetres['nodesbyphase'][phase])
54
55 # Write bookmark updates.
56 bookmarks.updatefromremote(repo.ui, repo, csetres['bookmarks'],
57 remote.url(), pullop.gettransaction,
58 explicit=pullop.explicitbookmarks)
53 59
54 def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True): 60 def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True):
55 """Determine which changesets need to be pulled.""" 61 """Determine which changesets need to be pulled."""
56 62
57 if heads: 63 if heads:
89 # resuming interrupted clones, higher server-side cache hit rates due 95 # resuming interrupted clones, higher server-side cache hit rates due
90 # to smaller segments, etc. 96 # to smaller segments, etc.
91 with remote.commandexecutor() as e: 97 with remote.commandexecutor() as e:
92 objs = e.callcommand(b'changesetdata', { 98 objs = e.callcommand(b'changesetdata', {
93 b'noderange': [sorted(common), sorted(remoteheads)], 99 b'noderange': [sorted(common), sorted(remoteheads)],
94 b'fields': {b'parents', b'phase', b'revision'}, 100 b'fields': {b'bookmarks', b'parents', b'phase', b'revision'},
95 }).result() 101 }).result()
96 102
97 # The context manager waits on all response data when exiting. So 103 # The context manager waits on all response data when exiting. So
98 # we need to remain in the context manager in order to stream data. 104 # we need to remain in the context manager in order to stream data.
99 return _processchangesetdata(repo, tr, objs) 105 return _processchangesetdata(repo, tr, objs)
122 128
123 def onchangeset(cl, node): 129 def onchangeset(cl, node):
124 progress.increment() 130 progress.increment()
125 131
126 nodesbyphase = {phase: set() for phase in phases.phasenames} 132 nodesbyphase = {phase: set() for phase in phases.phasenames}
133 remotebookmarks = {}
127 134
128 # addgroup() expects a 7-tuple describing revisions. This normalizes 135 # addgroup() expects a 7-tuple describing revisions. This normalizes
129 # the wire data to that format. 136 # the wire data to that format.
130 # 137 #
131 # This loop also aggregates non-revision metadata, such as phase 138 # This loop also aggregates non-revision metadata, such as phase
134 for cset in objs: 141 for cset in objs:
135 node = cset[b'node'] 142 node = cset[b'node']
136 143
137 if b'phase' in cset: 144 if b'phase' in cset:
138 nodesbyphase[cset[b'phase']].add(node) 145 nodesbyphase[cset[b'phase']].add(node)
146
147 for mark in cset.get(b'bookmarks', []):
148 remotebookmarks[mark] = node
139 149
140 # Some entries might only be metadata only updates. 150 # Some entries might only be metadata only updates.
141 if b'revisionsize' not in cset: 151 if b'revisionsize' not in cset:
142 continue 152 continue
143 153
162 progress.complete() 172 progress.complete()
163 173
164 return { 174 return {
165 'added': added, 175 'added': added,
166 'nodesbyphase': nodesbyphase, 176 'nodesbyphase': nodesbyphase,
177 'bookmarks': remotebookmarks,
167 } 178 }