103
86
eq(rev.message, 'add hello')
105
88
tree1 = b.repository.revision_tree(rh[0])
107
89
text = tree1.get_file_text(file_id)
109
self.assertEqual('hello world', text)
90
eq(text, 'hello world')
111
92
tree2 = b.repository.revision_tree(rh[1])
113
text = tree2.get_file_text(file_id)
115
self.assertEqual('version 2', text)
117
def test_commit_lossy_native(self):
118
"""Attempt a lossy commit to a native branch."""
119
wt = self.make_branch_and_tree('.')
121
file('hello', 'w').write('hello world')
123
revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
124
self.assertEquals('revid', revid)
126
def test_commit_lossy_foreign(self):
127
"""Attempt a lossy commit to a foreign branch."""
128
test_foreign.register_dummy_foreign_for_test(self)
129
wt = self.make_branch_and_tree('.',
130
format=test_foreign.DummyForeignVcsDirFormat())
132
file('hello', 'w').write('hello world')
134
revid = wt.commit(message='add hello', lossy=True,
135
timestamp=1302659388, timezone=0)
136
self.assertEquals('dummy-v1:1302659388.0-0-UNKNOWN', revid)
138
def test_commit_bound_lossy_foreign(self):
139
"""Attempt a lossy commit to a bzr branch bound to a foreign branch."""
140
test_foreign.register_dummy_foreign_for_test(self)
141
foreign_branch = self.make_branch('foreign',
142
format=test_foreign.DummyForeignVcsDirFormat())
143
wt = foreign_branch.create_checkout("local")
145
file('local/hello', 'w').write('hello world')
147
revid = wt.commit(message='add hello', lossy=True,
148
timestamp=1302659388, timezone=0)
149
self.assertEquals('dummy-v1:1302659388.0-0-0', revid)
150
self.assertEquals('dummy-v1:1302659388.0-0-0',
151
foreign_branch.last_revision())
152
self.assertEquals('dummy-v1:1302659388.0-0-0',
153
wt.branch.last_revision())
155
def test_missing_commit(self):
156
"""Test a commit with a missing file"""
93
eq(tree2.get_file_text(file_id), 'version 2')
95
def test_delete_commit(self):
96
"""Test a commit with a deleted file"""
157
97
wt = self.make_branch_and_tree('.')
159
99
file('hello', 'w').write('hello world')
590
490
other_tree.commit('modify all sample files and dirs.')
592
492
other_tree.unlock()
593
this_tree.merge_from_branch(other_tree.branch)
493
self.merge(other_tree.branch, this_tree)
594
494
reporter = CapturingReporter()
595
495
this_tree.commit('do the commit', reporter=reporter)
497
('change', 'unchanged', 'dirtoleave'),
498
('change', 'unchanged', 'filetoleave'),
597
499
('change', 'modified', 'filetomodify'),
598
500
('change', 'added', 'newdir'),
599
501
('change', 'added', 'newfile'),
600
502
('renamed', 'renamed', 'dirtorename', 'renameddir'),
601
('renamed', 'renamed', 'filetorename', 'renamedfile'),
602
503
('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
603
504
('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
505
('renamed', 'renamed', 'filetorename', 'renamedfile'),
604
506
('deleted', 'dirtoremove'),
605
507
('deleted', 'filetoremove'),
607
result = set(reporter.calls)
608
missing = expected - result
609
new = result - expected
610
self.assertEqual((set(), set()), (missing, new))
612
def test_commit_removals_respects_filespec(self):
613
"""Commit respects the specified_files for removals."""
614
tree = self.make_branch_and_tree('.')
615
self.build_tree(['a', 'b'])
617
tree.commit('added a, b')
618
tree.remove(['a', 'b'])
619
tree.commit('removed a', specific_files='a')
620
basis = tree.basis_tree()
623
self.assertIs(None, basis.path2id('a'))
624
self.assertFalse(basis.path2id('b') is None)
628
def test_commit_saves_1ms_timestamp(self):
629
"""Passing in a timestamp is saved with 1ms resolution"""
630
tree = self.make_branch_and_tree('.')
631
self.build_tree(['a'])
633
tree.commit('added a', timestamp=1153248633.4186721, timezone=0,
636
rev = tree.branch.repository.get_revision('a1')
637
self.assertEqual(1153248633.419, rev.timestamp)
639
def test_commit_has_1ms_resolution(self):
640
"""Allowing commit to generate the timestamp also has 1ms resolution"""
641
tree = self.make_branch_and_tree('.')
642
self.build_tree(['a'])
644
tree.commit('added a', rev_id='a1')
646
rev = tree.branch.repository.get_revision('a1')
647
timestamp = rev.timestamp
648
timestamp_1ms = round(timestamp, 3)
649
self.assertEqual(timestamp_1ms, timestamp)
651
def assertBasisTreeKind(self, kind, tree, file_id):
652
basis = tree.basis_tree()
655
self.assertEqual(kind, basis.kind(file_id))
659
def test_commit_kind_changes(self):
660
self.requireFeature(SymlinkFeature)
661
tree = self.make_branch_and_tree('.')
662
os.symlink('target', 'name')
663
tree.add('name', 'a-file-id')
664
tree.commit('Added a symlink')
665
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
668
self.build_tree(['name'])
669
tree.commit('Changed symlink to file')
670
self.assertBasisTreeKind('file', tree, 'a-file-id')
673
os.symlink('target', 'name')
674
tree.commit('file to symlink')
675
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
679
tree.commit('symlink to directory')
680
self.assertBasisTreeKind('directory', tree, 'a-file-id')
683
os.symlink('target', 'name')
684
tree.commit('directory to symlink')
685
self.assertBasisTreeKind('symlink', tree, 'a-file-id')
687
# prepare for directory <-> file tests
690
tree.commit('symlink to directory')
691
self.assertBasisTreeKind('directory', tree, 'a-file-id')
694
self.build_tree(['name'])
695
tree.commit('Changed directory to file')
696
self.assertBasisTreeKind('file', tree, 'a-file-id')
700
tree.commit('file to directory')
701
self.assertBasisTreeKind('directory', tree, 'a-file-id')
703
def test_commit_unversioned_specified(self):
704
"""Commit should raise if specified files isn't in basis or worktree"""
705
tree = self.make_branch_and_tree('.')
706
self.assertRaises(errors.PathsNotVersionedError, tree.commit,
707
'message', specific_files=['bogus'])
709
class Callback(object):
711
def __init__(self, message, testcase):
713
self.message = message
714
self.testcase = testcase
716
def __call__(self, commit_obj):
718
self.testcase.assertTrue(isinstance(commit_obj, Commit))
721
def test_commit_callback(self):
722
"""Commit should invoke a callback to get the message"""
724
tree = self.make_branch_and_tree('.')
728
self.assertTrue(isinstance(e, BzrError))
729
self.assertEqual('The message or message_callback keyword'
730
' parameter is required for commit().', str(e))
732
self.fail('exception not raised')
733
cb = self.Callback(u'commit 1', self)
734
tree.commit(message_callback=cb)
735
self.assertTrue(cb.called)
736
repository = tree.branch.repository
737
message = repository.get_revision(tree.last_revision()).message
738
self.assertEqual('commit 1', message)
740
def test_no_callback_pointless(self):
741
"""Callback should not be invoked for pointless commit"""
742
tree = self.make_branch_and_tree('.')
743
cb = self.Callback(u'commit 2', self)
744
self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
745
allow_pointless=False)
746
self.assertFalse(cb.called)
748
def test_no_callback_netfailure(self):
749
"""Callback should not be invoked if connectivity fails"""
750
tree = self.make_branch_and_tree('.')
751
cb = self.Callback(u'commit 2', self)
752
repository = tree.branch.repository
753
# simulate network failure
754
def raise_(self, arg, arg2, arg3=None, arg4=None):
755
raise errors.NoSuchFile('foo')
756
repository.add_inventory = raise_
757
repository.add_inventory_by_delta = raise_
758
self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
759
self.assertFalse(cb.called)
761
def test_selected_file_merge_commit(self):
762
"""Ensure the correct error is raised"""
763
tree = self.make_branch_and_tree('foo')
764
# pending merge would turn into a left parent
765
tree.commit('commit 1')
766
tree.add_parent_tree_id('example')
767
self.build_tree(['foo/bar', 'foo/baz'])
768
tree.add(['bar', 'baz'])
769
err = self.assertRaises(errors.CannotCommitSelectedFileMerge,
770
tree.commit, 'commit 2', specific_files=['bar', 'baz'])
771
self.assertEqual(['bar', 'baz'], err.files)
772
self.assertEqual('Selected-file commit of merges is not supported'
773
' yet: files bar, baz', str(err))
775
def test_commit_ordering(self):
776
"""Test of corner-case commit ordering error"""
777
tree = self.make_branch_and_tree('.')
778
self.build_tree(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
779
tree.add(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
781
self.build_tree(['a/c/d/'])
783
tree.rename_one('a/z/x', 'a/c/d/x')
784
tree.commit('test', specific_files=['a/z/y'])
786
def test_commit_no_author(self):
787
"""The default kwarg author in MutableTree.commit should not add
788
the 'author' revision property.
790
tree = self.make_branch_and_tree('foo')
791
rev_id = tree.commit('commit 1')
792
rev = tree.branch.repository.get_revision(rev_id)
793
self.assertFalse('author' in rev.properties)
794
self.assertFalse('authors' in rev.properties)
796
def test_commit_author(self):
797
"""Passing a non-empty author kwarg to MutableTree.commit should add
798
the 'author' revision property.
800
tree = self.make_branch_and_tree('foo')
801
rev_id = self.callDeprecated(['The parameter author was '
802
'deprecated in version 1.13. Use authors instead'],
803
tree.commit, 'commit 1', author='John Doe <jdoe@example.com>')
804
rev = tree.branch.repository.get_revision(rev_id)
805
self.assertEqual('John Doe <jdoe@example.com>',
806
rev.properties['authors'])
807
self.assertFalse('author' in rev.properties)
809
def test_commit_empty_authors_list(self):
810
"""Passing an empty list to authors shouldn't add the property."""
811
tree = self.make_branch_and_tree('foo')
812
rev_id = tree.commit('commit 1', authors=[])
813
rev = tree.branch.repository.get_revision(rev_id)
814
self.assertFalse('author' in rev.properties)
815
self.assertFalse('authors' in rev.properties)
817
def test_multiple_authors(self):
818
tree = self.make_branch_and_tree('foo')
819
rev_id = tree.commit('commit 1',
820
authors=['John Doe <jdoe@example.com>',
821
'Jane Rey <jrey@example.com>'])
822
rev = tree.branch.repository.get_revision(rev_id)
823
self.assertEqual('John Doe <jdoe@example.com>\n'
824
'Jane Rey <jrey@example.com>', rev.properties['authors'])
825
self.assertFalse('author' in rev.properties)
827
def test_author_and_authors_incompatible(self):
828
tree = self.make_branch_and_tree('foo')
829
self.assertRaises(AssertionError, tree.commit, 'commit 1',
830
authors=['John Doe <jdoe@example.com>',
831
'Jane Rey <jrey@example.com>'],
832
author="Jack Me <jme@example.com>")
834
def test_author_with_newline_rejected(self):
835
tree = self.make_branch_and_tree('foo')
836
self.assertRaises(AssertionError, tree.commit, 'commit 1',
837
authors=['John\nDoe <jdoe@example.com>'])
839
def test_commit_with_checkout_and_branch_sharing_repo(self):
840
repo = self.make_repository('repo', shared=True)
841
# make_branch_and_tree ignores shared repos
842
branch = bzrdir.BzrDir.create_branch_convenience('repo/branch')
843
tree2 = branch.create_checkout('repo/tree2')
844
tree2.commit('message', rev_id='rev1')
845
self.assertTrue(tree2.branch.repository.has_revision('rev1'))