146
149
self.build_tree(['known_file', 'unknown_file'])
147
150
wt.add('known_file')
149
self.assertRaises(errors.PathsNotVersionedError,
150
wt.changes_from, wt.basis_tree(), wt, specific_files=['known_file',
151
'unknown_file'], require_versioned=True)
153
errors.PathsNotVersionedError,
154
wt.changes_from, wt.basis_tree(), wt,
155
specific_files=['known_file', 'unknown_file'],
156
require_versioned=True)
153
158
# we need to pass a known file with an unknown file to get this to
154
159
# fail when expected.
155
160
delta = wt.changes_from(wt.basis_tree(),
156
specific_files=['known_file', 'unknown_file'],
157
require_versioned=False)
161
specific_files=['known_file', 'unknown_file'],
162
require_versioned=False)
158
163
self.assertEqual(len(delta.added), 1)
161
class TestMultiWalker(TestCaseWithTransport):
163
def assertStepOne(self, has_more, path, file_id, iterator):
164
retval = _mod_tree.MultiWalker._step_one(iterator)
166
self.assertIs(None, path)
167
self.assertIs(None, file_id)
168
self.assertEqual((False, None, None), retval)
170
self.assertEqual((has_more, path, file_id),
171
(retval[0], retval[1], retval[2].file_id))
173
def test__step_one_empty(self):
174
tree = self.make_branch_and_tree('empty')
175
repo = tree.branch.repository
176
empty_tree = repo.revision_tree(revision.NULL_REVISION)
178
iterator = empty_tree.iter_entries_by_dir()
179
self.assertStepOne(False, None, None, iterator)
180
self.assertStepOne(False, None, None, iterator)
182
def test__step_one(self):
183
tree = self.make_branch_and_tree('tree')
184
self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
185
tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
187
iterator = tree.iter_entries_by_dir()
189
self.addCleanup(tree.unlock)
191
root_id = tree.path2id('')
192
self.assertStepOne(True, '', root_id, iterator)
193
self.assertStepOne(True, 'a', 'a-id', iterator)
194
self.assertStepOne(True, 'b', 'b-id', iterator)
195
self.assertStepOne(True, 'b/c', 'c-id', iterator)
196
self.assertStepOne(False, None, None, iterator)
197
self.assertStepOne(False, None, None, iterator)
199
def assertWalkerNext(self, exp_path, exp_file_id, master_has_node,
200
exp_other_paths, iterator):
201
"""Check what happens when we step the iterator.
203
:param path: The path for this entry
204
:param file_id: The file_id for this entry
205
:param master_has_node: Does the master tree have this entry?
206
:param exp_other_paths: A list of other_path values.
207
:param iterator: The iterator to step
209
path, file_id, master_ie, other_values = next(iterator)
210
self.assertEqual((exp_path, exp_file_id), (path, file_id),
211
'Master entry did not match')
213
self.assertIsNot(None, master_ie, 'master should have an entry')
215
self.assertIs(None, master_ie, 'master should not have an entry')
216
self.assertEqual(len(exp_other_paths), len(other_values),
217
'Wrong number of other entries')
220
for path, ie in other_values:
221
other_paths.append(path)
223
other_file_ids.append(None)
225
other_file_ids.append(ie.file_id)
228
for path in exp_other_paths:
230
exp_file_ids.append(None)
232
exp_file_ids.append(file_id)
233
self.assertEqual(exp_other_paths, other_paths, "Other paths incorrect")
234
self.assertEqual(exp_file_ids, other_file_ids,
235
"Other file_ids incorrect")
237
def lock_and_get_basis_and_root_id(self, tree):
239
self.addCleanup(tree.unlock)
240
basis_tree = tree.basis_tree()
241
basis_tree.lock_read()
242
self.addCleanup(basis_tree.unlock)
243
root_id = tree.path2id('')
244
return basis_tree, root_id
246
def test_simple_stepping(self):
247
tree = self.make_branch_and_tree('tree')
248
self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
249
tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
251
tree.commit('first', rev_id='first-rev-id')
253
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
255
walker = _mod_tree.MultiWalker(tree, [basis_tree])
256
iterator = walker.iter_all()
257
self.assertWalkerNext(u'', root_id, True, [u''], iterator)
258
self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
259
self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
260
self.assertWalkerNext(u'b/c', 'c-id', True, [u'b/c'], iterator)
261
self.assertRaises(StopIteration, next, iterator)
263
def test_master_has_extra(self):
264
tree = self.make_branch_and_tree('tree')
265
self.build_tree(['tree/a', 'tree/b/', 'tree/c', 'tree/d'])
266
tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
268
tree.commit('first', rev_id='first-rev-id')
270
tree.add(['c'], ['c-id'])
271
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
273
walker = _mod_tree.MultiWalker(tree, [basis_tree])
274
iterator = walker.iter_all()
275
self.assertWalkerNext(u'', root_id, True, [u''], iterator)
276
self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
277
self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
278
self.assertWalkerNext(u'c', 'c-id', True, [None], iterator)
279
self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
280
self.assertRaises(StopIteration, next, iterator)
282
def test_master_renamed_to_earlier(self):
283
"""The record is still present, it just shows up early."""
284
tree = self.make_branch_and_tree('tree')
285
self.build_tree(['tree/a', 'tree/c', 'tree/d'])
286
tree.add(['a', 'c', 'd'], ['a-id', 'c-id', 'd-id'])
287
tree.commit('first', rev_id='first-rev-id')
288
tree.rename_one('d', 'b')
290
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
292
walker = _mod_tree.MultiWalker(tree, [basis_tree])
293
iterator = walker.iter_all()
294
self.assertWalkerNext(u'', root_id, True, [u''], iterator)
295
self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
296
self.assertWalkerNext(u'b', 'd-id', True, [u'd'], iterator)
297
self.assertWalkerNext(u'c', 'c-id', True, [u'c'], iterator)
298
self.assertRaises(StopIteration, next, iterator)
300
def test_master_renamed_to_later(self):
301
tree = self.make_branch_and_tree('tree')
302
self.build_tree(['tree/a', 'tree/b', 'tree/d'])
303
tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
304
tree.commit('first', rev_id='first-rev-id')
305
tree.rename_one('b', 'e')
307
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
309
walker = _mod_tree.MultiWalker(tree, [basis_tree])
310
iterator = walker.iter_all()
311
self.assertWalkerNext(u'', root_id, True, [u''], iterator)
312
self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
313
self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
314
self.assertWalkerNext(u'e', 'b-id', True, [u'b'], iterator)
315
self.assertRaises(StopIteration, next, iterator)
317
def test_other_extra_in_middle(self):
318
tree = self.make_branch_and_tree('tree')
319
self.build_tree(['tree/a', 'tree/b', 'tree/d'])
320
tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
321
tree.commit('first', rev_id='first-rev-id')
324
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
325
walker = _mod_tree.MultiWalker(tree, [basis_tree])
326
iterator = walker.iter_all()
327
self.assertWalkerNext(u'', root_id, True, [u''], iterator)
328
self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
329
self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
330
self.assertWalkerNext(u'b', 'b-id', False, [u'b'], iterator)
331
self.assertRaises(StopIteration, next, iterator)
333
def test_other_extra_at_end(self):
334
tree = self.make_branch_and_tree('tree')
335
self.build_tree(['tree/a', 'tree/b', 'tree/d'])
336
tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
337
tree.commit('first', rev_id='first-rev-id')
340
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
341
walker = _mod_tree.MultiWalker(tree, [basis_tree])
342
iterator = walker.iter_all()
343
self.assertWalkerNext(u'', root_id, True, [u''], iterator)
344
self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
345
self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
346
self.assertWalkerNext(u'd', 'd-id', False, [u'd'], iterator)
347
self.assertRaises(StopIteration, next, iterator)
349
def test_others_extra_at_end(self):
350
tree = self.make_branch_and_tree('tree')
351
self.build_tree(['tree/a', 'tree/b', 'tree/c', 'tree/d', 'tree/e'])
352
tree.add(['a', 'b', 'c', 'd', 'e'],
353
['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
354
tree.commit('first', rev_id='first-rev-id')
356
tree.commit('second', rev_id='second-rev-id')
358
tree.commit('third', rev_id='third-rev-id')
361
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
362
first_tree = tree.branch.repository.revision_tree('first-rev-id')
363
second_tree = tree.branch.repository.revision_tree('second-rev-id')
364
walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree,
366
iterator = walker.iter_all()
367
self.assertWalkerNext(u'', root_id, True, [u'', u'', u''], iterator)
368
self.assertWalkerNext(u'a', 'a-id', True, [u'a', u'a', u'a'], iterator)
369
self.assertWalkerNext(u'b', 'b-id', True, [u'b', u'b', u'b'], iterator)
370
self.assertWalkerNext(u'c', 'c-id', False, [u'c', u'c', u'c'], iterator)
371
self.assertWalkerNext(u'd', 'd-id', False, [None, u'd', u'd'], iterator)
372
self.assertWalkerNext(u'e', 'e-id', False, [None, u'e', None], iterator)
373
self.assertRaises(StopIteration, next, iterator)
375
def test_different_file_id_in_others(self):
376
tree = self.make_branch_and_tree('tree')
377
self.build_tree(['tree/a', 'tree/b', 'tree/c/'])
378
tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
379
tree.commit('first', rev_id='first-rev-id')
381
tree.rename_one('b', 'c/d')
382
self.build_tree(['tree/b'])
383
tree.add(['b'], ['b2-id'])
384
tree.commit('second', rev_id='second-rev-id')
386
tree.rename_one('a', 'c/e')
387
self.build_tree(['tree/a'])
388
tree.add(['a'], ['a2-id'])
390
basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
391
first_tree = tree.branch.repository.revision_tree('first-rev-id')
392
walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree])
394
iterator = walker.iter_all()
395
self.assertWalkerNext(u'', root_id, True, [u'', u''], iterator)
396
self.assertWalkerNext(u'a', 'a2-id', True, [None, None], iterator)
397
self.assertWalkerNext(u'b', 'b2-id', True, [u'b', None], iterator)
398
self.assertWalkerNext(u'c', 'c-id', True, [u'c', u'c'], iterator)
399
self.assertWalkerNext(u'c/d', 'b-id', True, [u'c/d', u'b'], iterator)
400
self.assertWalkerNext(u'c/e', 'a-id', True, [u'a', u'a'], iterator)
401
self.assertRaises(StopIteration, next, iterator)
403
def assertCmpByDirblock(self, cmp_val, path1, path2):
404
self.assertEqual(cmp_val,
405
_mod_tree.MultiWalker._cmp_path_by_dirblock(path1, path2))
407
def test__cmp_path_by_dirblock(self):
408
# We only support Unicode strings at this point
409
self.assertRaises(TypeError,
410
_mod_tree.MultiWalker._cmp_path_by_dirblock, '', 'b')
411
self.assertCmpByDirblock(0, u'', u'')
412
self.assertCmpByDirblock(0, u'a', u'a')
413
self.assertCmpByDirblock(0, u'a/b', u'a/b')
414
self.assertCmpByDirblock(0, u'a/b/c', u'a/b/c')
415
self.assertCmpByDirblock(1, u'a-a', u'a')
416
self.assertCmpByDirblock(-1, u'a-a', u'a/a')
417
self.assertCmpByDirblock(-1, u'a=a', u'a/a')
418
self.assertCmpByDirblock(1, u'a-a/a', u'a/a')
419
self.assertCmpByDirblock(1, u'a=a/a', u'a/a')
420
self.assertCmpByDirblock(1, u'a-a/a', u'a/a/a')
421
self.assertCmpByDirblock(1, u'a=a/a', u'a/a/a')
422
self.assertCmpByDirblock(1, u'a-a/a/a', u'a/a/a')
423
self.assertCmpByDirblock(1, u'a=a/a/a', u'a/a/a')
425
def assertPathToKey(self, expected, path):
426
self.assertEqual(expected, _mod_tree.MultiWalker._path_to_key(path))
428
def test__path_to_key(self):
429
self.assertPathToKey(([u''], u''), u'')
430
self.assertPathToKey(([u''], u'a'), u'a')
431
self.assertPathToKey(([u'a'], u'b'), u'a/b')
432
self.assertPathToKey(([u'a', u'b'], u'c'), u'a/b/c')
166
class FindPreviousPathsTests(TestCaseWithTransport):
169
tree = self.make_branch_and_tree('tree')
170
self.build_tree(['tree/b'])
172
revid1 = tree.commit('first')
173
tree1 = tree.branch.repository.revision_tree(revid1)
175
tree0 = tree.branch.repository.revision_tree(revision.NULL_REVISION)
177
self.assertEqual({'b': None}, find_previous_paths(tree1, tree0, ['b']))
179
def test_find_previous_paths(self):
180
tree = self.make_branch_and_tree('tree')
181
self.build_tree(['tree/b'])
183
revid1 = tree.commit('first')
184
tree1 = tree.branch.repository.revision_tree(revid1)
186
tree.rename_one('b', 'c')
187
self.build_tree(['tree/b'])
189
revid2 = tree.commit('second')
190
tree2 = tree.branch.repository.revision_tree(revid2)
192
self.assertEqual({'c': 'b', 'b': None},
193
find_previous_paths(tree2, tree1, ['b', 'c']))
196
class GetCanonicalPath(TestCaseWithTransport):
198
def test_existing_case(self):
199
# Test that we can find a file from a path with different case
200
tree = self.make_branch_and_tree('tree')
201
self.build_tree(['tree/b'])
205
get_canonical_path(tree, 'b', lambda x: x.lower()))
208
get_canonical_path(tree, 'B', lambda x: x.lower()))
210
def test_nonexistant_preserves_case(self):
211
tree = self.make_branch_and_tree('tree')
214
get_canonical_path(tree, 'b', lambda x: x.lower()))
217
get_canonical_path(tree, 'B', lambda x: x.lower()))
219
def test_in_directory_with_case(self):
220
tree = self.make_branch_and_tree('tree')
221
self.build_tree(['tree/a/', 'tree/a/b'])
222
tree.add(['a', 'a/b'])
225
get_canonical_path(tree, 'a/b', lambda x: x.lower()))
228
get_canonical_path(tree, 'A/B', lambda x: x.lower()))
231
get_canonical_path(tree, 'A/b', lambda x: x.lower()))
234
get_canonical_path(tree, 'A/C', lambda x: x.lower()))