94
95
pb.update("Finding revisions", 0, 2)
95
96
search = self._revids_to_fetch()
97
mutter('fetching: %s', search)
98
100
pb.update("Fetching revisions", 1, 2)
99
101
self._fetch_everything_for_search(search)
126
128
resume_tokens, missing_keys = self.sink.insert_stream(
127
129
stream, from_format, [])
128
130
if self.to_repository._fallback_repositories:
130
self._parent_inventories(search.get_keys()))
131
if not isinstance(search, graph.EverythingResult):
132
# If search is EverythingResult this is be unnecessary,
133
# so we can skip this step. The source will send us
134
# every revision it has, and their parent inventories.
135
# (Unless the source is damaged! but not really worth
136
# optimising for that case. The pack code will reject bad
139
self._parent_inventories(search.get_keys()))
132
141
pb.update("Missing keys")
133
142
stream = source.get_stream_for_missing_keys(missing_keys)
151
160
"""Determines the exact revisions needed from self.from_repository to
152
161
install self._last_revision in self.to_repository.
154
If no revisions need to be fetched, then this just returns None.
163
:returns: A SearchResult of some sort. (Possibly a
164
PendingAncestryResult, EmptySearchResult, etc.)
156
if self._fetch_spec is not None:
166
mutter("self._fetch_spec, self._last_revision: %r, %r",
167
self._fetch_spec, self._last_revision)
168
get_search = getattr(self._fetch_spec, 'get_search', None)
169
if get_search is not None:
170
# This is EverythingNotInOther or a similar kind of fetch_spec.
171
# Turn it into a search result.
173
elif self._fetch_spec is not None:
174
# The fetch spec is already a concrete search result.
157
175
return self._fetch_spec
158
mutter('fetch up to rev {%s}', self._last_revision)
159
if self._last_revision is NULL_REVISION:
176
elif self._last_revision == NULL_REVISION:
177
# fetch_spec is None + last_revision is null => empty fetch.
160
178
# explicit limit of no revisions needed
162
return self.to_repository.search_missing_revision_ids(
163
self.from_repository, self._last_revision,
164
find_ghosts=self.find_ghosts)
179
return graph.EmptySearchResult()
180
elif self._last_revision is not None:
181
return graph.NotInOtherForRevs(self.to_repository,
182
self.from_repository, [self._last_revision],
183
find_ghosts=self.find_ghosts).get_search()
184
else: # self._last_revision is None:
185
return graph.EverythingNotInOther(self.to_repository,
186
self.from_repository, find_ghosts=self.find_ghosts).get_search()
166
188
def _parent_inventories(self, revision_ids):
167
189
# Find all the parent revisions referenced by the stream, but
243
268
# yet, and are unlikely to in non-rich-root environments anyway.
244
269
root_id_order.sort(key=operator.itemgetter(0))
245
270
# Create a record stream containing the roots to create.
247
# XXX: not covered by tests, should have a flag to always run
248
# this. -- mbp 20100129
249
graph = self.source_repo.get_known_graph_ancestry(revs)
271
if len(revs) > self.known_graph_threshold:
272
graph = self.source.get_known_graph_ancestry(revs)
250
273
new_roots_stream = _new_root_data_stream(
251
274
root_id_order, rev_id_to_root_id, parent_map, self.source, graph)
252
275
return [('texts', new_roots_stream)]
255
def _get_rich_root_heads_graph(source_repo, revision_ids):
256
"""Get a Graph object suitable for asking heads() for new rich roots."""
260
278
def _new_root_data_stream(
261
279
root_keys_to_create, rev_id_to_root_id_map, parent_map, repo, graph=None):
262
280
"""Generate a texts substream of synthesised root entries.