55
56
:param last_revision: If set, try to limit to the data this revision
58
:param fetch_spec: A SearchResult specifying which revisions to fetch.
59
If set, this overrides last_revision.
57
60
:param find_ghosts: If True search the entire history for ghosts.
59
62
# repository.fetch has the responsibility for short-circuiting
92
95
pb.show_pct = pb.show_count = False
94
97
pb.update("Finding revisions", 0, 2)
95
search = self._revids_to_fetch()
98
search_result = self._revids_to_fetch()
99
mutter('fetching: %s', search_result)
100
if search_result.is_empty():
98
102
pb.update("Fetching revisions", 1, 2)
99
self._fetch_everything_for_search(search)
103
self._fetch_everything_for_search(search_result)
125
129
pb.update("Inserting stream")
126
130
resume_tokens, missing_keys = self.sink.insert_stream(
127
131
stream, from_format, [])
128
if self.to_repository._fallback_repositories:
130
self._parent_inventories(search.get_keys()))
132
133
pb.update("Missing keys")
133
134
stream = source.get_stream_for_missing_keys(missing_keys)
151
152
"""Determines the exact revisions needed from self.from_repository to
152
153
install self._last_revision in self.to_repository.
154
If no revisions need to be fetched, then this just returns None.
155
:returns: A SearchResult of some sort. (Possibly a
156
PendingAncestryResult, EmptySearchResult, etc.)
158
mutter("self._fetch_spec, self._last_revision: %r, %r",
159
self._fetch_spec, self._last_revision)
156
160
if self._fetch_spec is not None:
161
# The fetch spec is already a concrete search result.
157
162
return self._fetch_spec
158
mutter('fetch up to rev {%s}', self._last_revision)
159
if self._last_revision is NULL_REVISION:
163
elif self._last_revision == NULL_REVISION:
164
# fetch_spec is None + last_revision is null => empty fetch.
160
165
# 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)
166
def _parent_inventories(self, revision_ids):
167
# Find all the parent revisions referenced by the stream, but
168
# not present in the stream, and make sure we send their
170
parent_maps = self.to_repository.get_parent_map(revision_ids)
172
map(parents.update, parent_maps.itervalues())
173
parents.discard(NULL_REVISION)
174
parents.difference_update(revision_ids)
175
missing_keys = set(('inventories', rev_id) for rev_id in parents)
166
return graph.EmptySearchResult()
167
elif self._last_revision is not None:
168
return graph.NotInOtherForRevs(self.to_repository,
169
self.from_repository, [self._last_revision],
170
find_ghosts=self.find_ghosts).execute()
171
else: # self._last_revision is None:
172
return graph.EverythingNotInOther(self.to_repository,
173
self.from_repository,
174
find_ghosts=self.find_ghosts).execute()
179
177
class Inter1and2Helper(object):
243
244
# yet, and are unlikely to in non-rich-root environments anyway.
244
245
root_id_order.sort(key=operator.itemgetter(0))
245
246
# 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)
247
if len(revs) > self.known_graph_threshold:
248
graph = self.source.get_known_graph_ancestry(revs)
250
249
new_roots_stream = _new_root_data_stream(
251
250
root_id_order, rev_id_to_root_id, parent_map, self.source, graph)
252
251
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
254
def _new_root_data_stream(
261
255
root_keys_to_create, rev_id_to_root_id_map, parent_map, repo, graph=None):
262
256
"""Generate a texts substream of synthesised root entries.