45
45
graph = branch.repository.get_graph()
46
46
history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
47
[_mod_revision.NULL_REVISION]))
47
[_mod_revision.NULL_REVISION]))
111
111
# construct. One way would be to uncommit and gc the revision, but not
112
112
# every branch supports that. -- mbp 20070814
114
#TODO: test that fetch correctly does reweaving when needed. RBC 20051008
114
# TODO: test that fetch correctly does reweaving when needed. RBC 20051008
115
115
# Note that this means - updating the weave when ghosts are filled in to
116
116
# add the right parents.
119
119
class TestFetch(TestCaseWithTransport):
121
121
def test_fetch(self):
122
#highest indices a: 5, b: 7
122
# highest indices a: 5, b: 7
123
123
br_a, br_b = make_branches(self, format='dirstate-tags')
124
124
fetch_steps(self, br_a, br_b, br_a)
156
156
# Make sure fetch retrieved only what we requested
157
self.assertEqual({(b'tree-root', b'rev1'):()},
158
repo.texts.get_parent_map(
159
[(b'tree-root', b'rev1'), (b'tree-root', b'rev2')]))
157
self.assertEqual({(b'tree-root', b'rev1'): ()},
158
repo.texts.get_parent_map(
159
[(b'tree-root', b'rev1'), (b'tree-root', b'rev2')]))
162
162
branch.pull(tree.branch)
167
167
# Make sure fetch retrieved only what we requested
168
self.assertEqual({(b'tree-root', b'rev2'):((b'tree-root', b'rev1'),)},
169
repo.texts.get_parent_map([(b'tree-root', b'rev2')]))
168
self.assertEqual({(b'tree-root', b'rev2'): ((b'tree-root', b'rev1'),)},
169
repo.texts.get_parent_map([(b'tree-root', b'rev2')]))
173
173
def test_fetch_incompatible(self):
174
174
knit_tree = self.make_branch_and_tree('knit', format='knit')
175
175
knit3_tree = self.make_branch_and_tree('knit3',
176
format='dirstate-with-subtree')
176
format='dirstate-with-subtree')
177
177
knit3_tree.commit('blah')
178
178
e = self.assertRaises(errors.IncompatibleRepositories,
179
179
knit_tree.branch.fetch, knit3_tree.branch)
180
180
self.assertContainsRe(str(e),
181
r"(?m).*/knit.*\nis not compatible with\n.*/knit3/.*\n"
182
r"different rich-root support")
181
r"(?m).*/knit.*\nis not compatible with\n.*/knit3/.*\n"
182
r"different rich-root support")
185
185
class TestMergeFetch(TestCaseWithTransport):
280
280
tree.commit('one', rev_id=b'rev-one')
281
281
source = tree.branch.repository
282
282
source.texts = versionedfile.RecordingVersionedFilesDecorator(
284
284
source.signatures = versionedfile.RecordingVersionedFilesDecorator(
286
286
source.revisions = versionedfile.RecordingVersionedFilesDecorator(
288
288
source.inventories = versionedfile.RecordingVersionedFilesDecorator(
291
291
self.assertTrue(target._format._fetch_uses_deltas)
292
292
target.fetch(source, revision_id=b'rev-one')
294
294
target._format._fetch_order, False),
295
295
self.find_get_record_stream(source.texts.calls))
296
296
self.assertEqual(('get_record_stream', [(b'rev-one',)],
297
target._format._fetch_order, False),
298
self.find_get_record_stream(source.inventories.calls, 2))
297
target._format._fetch_order, False),
298
self.find_get_record_stream(source.inventories.calls, 2))
299
299
self.assertEqual(('get_record_stream', [(b'rev-one',)],
300
300
target._format._fetch_order, False),
301
301
self.find_get_record_stream(source.revisions.calls))
320
320
tree.commit('one', rev_id=b'rev-one')
321
321
source = tree.branch.repository
322
322
source.texts = versionedfile.RecordingVersionedFilesDecorator(
324
324
source.signatures = versionedfile.RecordingVersionedFilesDecorator(
326
326
source.revisions = versionedfile.RecordingVersionedFilesDecorator(
328
328
source.inventories = versionedfile.RecordingVersionedFilesDecorator(
330
330
# XXX: This won't work in general, but for the dirstate format it does.
331
331
self.overrideAttr(target._format, '_fetch_uses_deltas', False)
332
332
target.fetch(source, revision_id=b'rev-one')
334
334
target._format._fetch_order, True),
335
335
self.find_get_record_stream(source.texts.calls))
336
336
self.assertEqual(('get_record_stream', [(b'rev-one',)],
337
target._format._fetch_order, True),
338
self.find_get_record_stream(source.inventories.calls, 2))
337
target._format._fetch_order, True),
338
self.find_get_record_stream(source.inventories.calls, 2))
339
339
self.assertEqual(('get_record_stream', [(b'rev-one',)],
340
340
target._format._fetch_order, True),
341
341
self.find_get_record_stream(source.revisions.calls))
371
371
source.lock_read()
372
372
self.addCleanup(source.unlock)
373
373
record = next(source.revisions.get_record_stream([(b'rev-two',)],
375
375
self.assertEqual('knit-delta-gz', record.storage_kind)
376
376
target.fetch(tree.branch.repository, revision_id=b'rev-two')
377
377
# The record should get expanded back to a fulltext
378
378
target.lock_read()
379
379
self.addCleanup(target.unlock)
380
380
record = next(target.revisions.get_record_stream([(b'rev-two',)],
382
382
self.assertEqual('knit-ft-gz', record.storage_kind)
384
384
def test_fetch_with_fallback_and_merge(self):
405
405
('add', ('', b'TREE_ROOT', 'directory', None))]
406
406
for i in range(10):
407
407
fname = 'file%03d' % (i,)
408
fileid = ('%s-%s' % (fname, osutils.rand_chars(64))).encode('ascii')
409
(fname, osutils.rand_chars(64))).encode('ascii')
409
410
to_add.append(('add', (fname, fileid, 'file', b'content\n')))
410
411
builder.build_snapshot(None, to_add, revision_id=b'A')
411
412
builder.build_snapshot([b'A'], [], revision_id=b'B')
422
423
source.lock_read()
423
424
self.addCleanup(source.unlock)
424
425
source.inventories = versionedfile.OrderingVersionedFilesDecorator(
426
key_priority={(b'E',): 1, (b'D',): 2, (b'C',): 4,
427
key_priority={(b'E',): 1, (b'D',): 2, (b'C',): 4,
428
429
# Ensure that the content is yielded in the proper order, and given as
429
430
# the expected kinds
430
431
records = [(record.key, record.storage_kind)
431
432
for record in source.inventories.get_record_stream(
432
[(b'D',), (b'C',), (b'E',), (b'F',)], 'unordered', False)]
433
[(b'D',), (b'C',), (b'E',), (b'F',)], 'unordered', False)]
433
434
self.assertEqual([((b'E',), 'knit-delta-gz'), ((b'D',), 'knit-delta-gz'),
434
435
((b'F',), 'knit-delta-gz'), ((b'C',), 'knit-delta-gz')],
437
438
target_branch.lock_write()
438
439
self.addCleanup(target_branch.unlock)
480
481
def get_parents(self, file_id, revision_id):
481
482
self.repo.lock_read()
483
parent_map = self.repo.texts.get_parent_map([(file_id, revision_id)])
484
parent_map = self.repo.texts.get_parent_map(
485
[(file_id, revision_id)])
484
486
return parent_map[(file_id, revision_id)]
486
488
self.repo.unlock()
492
494
fork = self.tree.controldir.sprout('fork', b'null:').open_workingtree()
493
495
fork.commit('not a ghost', rev_id=b'not-ghost-parent')
494
496
self.tree.branch.repository.fetch(fork.branch.repository,
496
498
self.tree.add_parent_tree_id(b'not-ghost-parent')
497
499
self.tree.commit('second commit', rev_id=b'second-id')
498
500
self.repo.fetch(self.tree.branch.repository, b'second-id')
522
524
def test_two_fetches(self):
523
525
self.make_two_commits(change_root=False, fetch_twice=True)
524
526
self.assertEqual(((b'TREE_ROOT', b'first-id'),),
525
self.get_parents(b'TREE_ROOT', b'second-id'))
527
self.get_parents(b'TREE_ROOT', b'second-id'))