258
274
lock_and_call_current_dirstate(tree, 'lock_tree_write')
259
275
self.assertRaises(errors.ObjectNotLocked, tree.current_dirstate)
277
def test_set_parent_trees_uses_update_basis_by_delta(self):
278
builder = self.make_branch_builder('source')
279
builder.start_series()
280
self.addCleanup(builder.finish_series)
281
builder.build_snapshot('A', [], [
282
('add', ('', 'root-id', 'directory', None)),
283
('add', ('a', 'a-id', 'file', 'content\n'))])
284
builder.build_snapshot('B', ['A'], [
285
('modify', ('a-id', 'new content\nfor a\n')),
286
('add', ('b', 'b-id', 'file', 'b-content\n'))])
287
tree = self.make_workingtree('tree')
288
source_branch = builder.get_branch()
289
tree.branch.repository.fetch(source_branch.repository, 'B')
290
tree.pull(source_branch, stop_revision='A')
292
self.addCleanup(tree.unlock)
293
state = tree.current_dirstate()
295
orig_update = state.update_basis_by_delta
296
def log_update_basis_by_delta(delta, new_revid):
297
called.append(new_revid)
298
return orig_update(delta, new_revid)
299
state.update_basis_by_delta = log_update_basis_by_delta
300
basis = tree.basis_tree()
301
self.assertEqual('a-id', basis.path2id('a'))
302
self.assertEqual(None, basis.path2id('b'))
303
def fail_set_parent_trees(trees, ghosts):
304
raise AssertionError('dirstate.set_parent_trees() was called')
305
state.set_parent_trees = fail_set_parent_trees
306
repo = tree.branch.repository
307
tree.pull(source_branch, stop_revision='B')
308
self.assertEqual(['B'], called)
309
basis = tree.basis_tree()
310
self.assertEqual('a-id', basis.path2id('a'))
311
self.assertEqual('b-id', basis.path2id('b'))
313
def test_set_parent_trees_handles_missing_basis(self):
314
builder = self.make_branch_builder('source')
315
builder.start_series()
316
self.addCleanup(builder.finish_series)
317
builder.build_snapshot('A', [], [
318
('add', ('', 'root-id', 'directory', None)),
319
('add', ('a', 'a-id', 'file', 'content\n'))])
320
builder.build_snapshot('B', ['A'], [
321
('modify', ('a-id', 'new content\nfor a\n')),
322
('add', ('b', 'b-id', 'file', 'b-content\n'))])
323
builder.build_snapshot('C', ['A'], [
324
('add', ('c', 'c-id', 'file', 'c-content\n'))])
325
b_c = self.make_branch('branch_with_c')
326
b_c.pull(builder.get_branch(), stop_revision='C')
327
b_b = self.make_branch('branch_with_b')
328
b_b.pull(builder.get_branch(), stop_revision='B')
329
# This is reproducing some of what 'switch' does, just to isolate the
330
# set_parent_trees() step.
331
wt = b_b.create_checkout('tree', lightweight=True)
332
fmt = wt.bzrdir.find_branch_format()
333
fmt.set_reference(wt.bzrdir, None, b_c)
334
# Re-open with the new reference
335
wt = wt.bzrdir.open_workingtree()
336
wt.set_parent_trees([('C', b_c.repository.revision_tree('C'))])
337
self.assertEqual(None, wt.basis_tree().path2id('b'))
261
339
def test_new_dirstate_on_new_lock(self):
262
340
# until we have detection for when a dirstate can be reused, we
263
341
# want to reparse dirstate on every new lock.
595
673
tree_iter_changes, ['bar', 'foo'])
596
674
self.assertEqual(e.paths, ['foo'])
676
def test_iter_changes_unversioned_non_ascii(self):
677
"""Unversioned non-ascii paths should be reported as unicode"""
678
self.requireFeature(features.UnicodeFilenameFeature)
679
tree = self.make_branch_and_tree('.')
680
self.build_tree_contents([('f', '')])
681
tree.add(['f'], ['f-id'])
682
def tree_iter_changes(tree, files):
683
return list(tree.iter_changes(tree.basis_tree(),
684
specific_files=files, require_versioned=True))
686
self.addCleanup(tree.unlock)
687
e = self.assertRaises(errors.PathsNotVersionedError,
688
tree_iter_changes, tree, [u'\xa7', u'\u03c0'])
689
self.assertEqual(e.paths, [u'\xa7', u'\u03c0'])
598
691
def get_tree_with_cachable_file_foo(self):
599
692
tree = self.make_branch_and_tree('.')
600
self.build_tree(['foo'])
694
self.addCleanup(tree.unlock)
695
self.build_tree_contents([('foo', 'a bit of content for foo\n')])
601
696
tree.add(['foo'], ['foo-id'])
602
# a 4 second old timestamp is always hashable - sucks to delay
603
# the test suite, but not testing this is worse.
697
tree.current_dirstate()._cutoff_time = time.time() + 60
607
700
def test_commit_updates_hash_cache(self):
608
701
tree = self.get_tree_with_cachable_file_foo()
609
702
revid = tree.commit('a commit')
610
703
# tree's dirstate should now have a valid stat entry for foo.
612
self.addCleanup(tree.unlock)
613
704
entry = tree._get_entry(path='foo')
614
705
expected_sha1 = osutils.sha_file_by_name('foo')
615
706
self.assertEqual(expected_sha1, entry[1][0][1])
707
self.assertEqual(len('a bit of content for foo\n'), entry[1][0][2])
617
709
def test_observed_sha1_cachable(self):
618
710
tree = self.get_tree_with_cachable_file_foo()
619
711
expected_sha1 = osutils.sha_file_by_name('foo')
620
712
statvalue = os.lstat("foo")
623
tree._observed_sha1("foo-id", "foo", (expected_sha1, statvalue))
624
self.assertEqual(expected_sha1,
625
tree._get_entry(path="foo")[1][0][1])
713
tree._observed_sha1("foo-id", "foo", (expected_sha1, statvalue))
714
entry = tree._get_entry(path="foo")
715
entry_state = entry[1][0]
716
self.assertEqual(expected_sha1, entry_state[1])
717
self.assertEqual(statvalue.st_size, entry_state[2])
628
720
tree = tree.bzrdir.open_workingtree()
630
722
self.addCleanup(tree.unlock)
631
self.assertEqual(expected_sha1, tree._get_entry(path="foo")[1][0][1])
723
entry = tree._get_entry(path="foo")
724
entry_state = entry[1][0]
725
self.assertEqual(expected_sha1, entry_state[1])
726
self.assertEqual(statvalue.st_size, entry_state[2])
633
728
def test_observed_sha1_new_file(self):
634
729
tree = self.make_branch_and_tree('.')