Mercurial > hg
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 } |